公司动态

【STM32U385RG 测评】——6.我愿称之为万能WIFI蓝牙AT指令测试神器

📅 2026/8/21 2:35:38
【STM32U385RG 测评】——6.我愿称之为万能WIFI蓝牙AT指令测试神器
当使用STM32外接WIFI和蓝牙芯片时绝大多数都是采用AT指令来进行通信测试的这里我想借这个机会分享一个万能WIFI蓝牙AT指令测试工程用它可以在通信早期尽快的测试WIFI和蓝牙芯片的通信功能已检测连接有没有问题硬件有没有故障。适合于任何使用串口进行AT指令通信的场合采用循环队列加中断的方式实现这里摒弃了DMA因为有的MCU单片机没有DMA所以直接使用中断加队列的方式来实现方便移植到任何MCU上甚至能支持最简单的MCS-51单片机。整个原理就是把串口1 调试串口接收的AT指令发给ESP8266的数据串口5然后把ESP8266的数据串口5收到的返回数据发给PC调试串口。核心代码如下#include esp8266.huint8_t esp8266_buf[RXBUFFLENGTH];uint16_t esp8266_cnt 0;uint16_t esp8266_cntPre 0;void WIFI_Send_Byte(uint8_t ch){/* 发送一个字节数据到UART */HAL_UART_Transmit(UART_ESP8266, (uint8_t *)ch, 1, 0xFFFF);}void WIFI_Send_Bytes(uint8_t *data, uint32_t len){/* 发送一个字节数据到UART */HAL_UART_Transmit(UART_ESP8266, data, len, 0xFFFF);}void WIFI_Send_String_Length(uint8_t *str,uint32_t strlen){unsigned int k0;do{WIFI_Send_Byte (*(str k));k;} while(k strlen);}void WIFI_Send_String(uint8_t *str){unsigned int k0;do{WIFI_Send_Byte (*(str k));k;} while(*(str k)!\0);}void ESP8266_Clear(void){memset(esp8266_buf, 0, sizeof(esp8266_buf));esp8266_cnt 0;}uint8_t ESP8266_WaitRecive(void){if(esp8266_cnt 0) //如果接收计数为0 则说明没有处于接收数据中所以直接跳出结束函数return REV_WAIT;if(esp8266_cnt esp8266_cntPre) //如果上一次的值和这次相同则说明接收完毕{esp8266_cnt 0; //清0接收计数return REV_OK; //返回接收完成标志}esp8266_cntPre esp8266_cnt; //置为相同return REV_WAIT; //返回接收未完成标志}static uint8_t rx_data 0;void ESP8266_RxCallBack(void){if(esp8266_cnt sizeof(esp8266_buf)) esp8266_cnt 0; //防止串口被刷爆esp8266_buf[esp8266_cnt] rx_data;HAL_UART_Receive_IT(UART_ESP8266, rx_data, 1);}#include usart9.huint8_t U1_RxBuff[RXBUFFLENGTH];uint16_t U1_Rxlen 0;uint16_t U1_RxlencntPre 0;void uart9_Send_Byte(uint8_t ch){/* 发送一个字节数据到UART */HAL_UART_Transmit(UART_PC, (uint8_t *)ch, 1, 0xFFFF);}void uart9_Send_Bytes(uint8_t *data, uint32_t len){/* 发送一个字节数据到UART */HAL_UART_Transmit(UART_PC, data, len, 0xFFFF);}void uart9_Send_String_Length(uint8_t *str,uint32_t strlen){unsigned int k0;do{uart9_Send_Byte (*(str k));k;} while(k strlen);}void uart9_Send_String(uint8_t *str){unsigned int k0;do{uart9_Send_Byte (*(str k));k;} while(*(str k)!\0);}void user_uart_clear(void){memset(U1_RxBuff, 0, sizeof(U1_RxBuff));U1_Rxlen 0;}uint8_t user_uart_wait_receive(void){if(U1_Rxlen 0) //如果接收计数为0 则说明没有处于接收数据中所以直接跳出结束函数return REV_WAIT;if(U1_Rxlen U1_RxlencntPre) //如果上一次的值和这次相同则说明接收完毕{U1_Rxlen 0; //清0接收计数return REV_OK; //返回接收完成标志}U1_RxlencntPre U1_Rxlen; //置为相同return REV_WAIT; //返回接收未完成标志}static uint8_t rx_data 0;void PC_RxCallBack(void){if(U1_Rxlen sizeof(U1_RxBuff)) U1_Rxlen 0; //防止串口被刷爆U1_RxBuff[U1_Rxlen] rx_data;HAL_UART_Receive_IT(UART_PC, rx_data, 1);}/* USER CODE BEGIN Header *//********************************************************************************* file : main.c* brief : Main program body******************************************************************************* attention** Copyright (c) 2025 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************//* USER CODE END Header *//* Includes ------------------------------------------------------------------*/#include main.h#include usart.h#include gpio.h#include stdio.h#include usart9.h#include esp8266.h/* Private includes ----------------------------------------------------------*//* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*//* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*//* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*//* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*//* USER CODE BEGIN PV */void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){if (huart UART_ESP8266) {ESP8266_RxCallBack();}if (huart UART_PC) {PC_RxCallBack();}}/* USER CODE END PV *//* Private function prototypes -----------------------------------------------*/void SystemClock_Config(void);/* USER CODE BEGIN PFP *//* USER CODE END PFP *//* Private user code ---------------------------------------------------------*//* USER CODE BEGIN 0 */static uint8_t rx_data2 0;static uint8_t rx_data1 0;/* USER CODE END 0 *//*** brief The application entry point.* retval int*/int main(void){/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();MX_UART5_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */HAL_UART_Receive_IT(UART_ESP8266, rx_data1, 1);HAL_UART_Receive_IT(UART_PC, rx_data2, 1);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE */if(user_uart_wait_receive() REV_OK){WIFI_Send_String(U1_RxBuff);user_uart_clear();}if(ESP8266_WaitRecive() REV_OK){uart9_Send_String(esp8266_buf);ESP8266_Clear();}HAL_Delay(10);/* USER CODE BEGIN 3 */}/* USER CODE END 3 */}/*** brief System Clock Configuration* retval None*/void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct {0};RCC_ClkInitTypeDef RCC_ClkInitStruct {0};/** Enable Epod Booster*/if (HAL_RCCEx_EpodBoosterClkConfig(RCC_EPODBOOSTER_SOURCE_MSIS, RCC_EPODBOOSTER_DIV1) ! HAL_OK){Error_Handler();}if (HAL_PWREx_EnableEpodBooster() ! HAL_OK){Error_Handler();}/** Configure the main internal regulator output voltage*/if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) ! HAL_OK){Error_Handler();}/** Set Flash latency before increasing MSIS*/__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_2);/** Initializes the CPU, AHB and APB buses clocks*/RCC_OscInitStruct.OscillatorType RCC_OSCILLATORTYPE_MSIS;RCC_OscInitStruct.MSISState RCC_MSI_ON;RCC_OscInitStruct.MSISSource RCC_MSI_RC0;RCC_OscInitStruct.MSISDiv RCC_MSI_DIV1;if (HAL_RCC_OscConfig(RCC_OscInitStruct) ! HAL_OK){Error_Handler();}/** Initializes the CPU, AHB and APB buses clocks*/RCC_ClkInitStruct.ClockType RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2|RCC_CLOCKTYPE_PCLK3;RCC_ClkInitStruct.SYSCLKSource RCC_SYSCLKSOURCE_MSIS;RCC_ClkInitStruct.AHBCLKDivider RCC_SYSCLK_DIV1;RCC_ClkInitStruct.APB1CLKDivider RCC_HCLK_DIV1;RCC_ClkInitStruct.APB2CLKDivider RCC_HCLK_DIV1;RCC_ClkInitStruct.APB3CLKDivider RCC_HCLK_DIV1;if (HAL_RCC_ClockConfig(RCC_ClkInitStruct, FLASH_LATENCY_2) ! HAL_OK){Error_Handler();}}/* USER CODE BEGIN 4 *//* USER CODE END 4 *//*** brief This function is executed in case of error occurrence.* retval None*/void Error_Handler(void){/* USER CODE BEGIN Error_Handler_Debug *//* User can add his own implementation to report the HAL error return state */__disable_irq();while (1){}/* USER CODE END Error_Handler_Debug */}#ifdef USE_FULL_ASSERT/*** brief Reports the name of the source file and the source line number* where the assert_param error has occurred.* param file: pointer to the source file name* param line: assert_param error line source number* retval None*/void assert_failed(uint8_t *file, uint32_t line){/* USER CODE BEGIN 6 *//* User can add his own implementation to report the file name and line number,ex: printf(Wrong parameters value: file %s on line %d\r\n, file, line) *//* USER CODE END 6 */}#endif /* USE_FULL_ASSERT */编译烧录打开串口助手经过测试这个万能WIFI蓝牙AT指令测试神器功能正确。---------------------作者龙鳞铁碎牙链接https://bbs.21ic.com/icview-3477438-1-1.html来源21ic.com此文章已获得原创/原创奖标签著作权归21ic所有任何人未经允许禁止转载。