今天和大家分享一下,如何使用STM32的串口自动检测波特率的功能。
为了调试功能方便,这里我们使用开发板的串口2引脚,可以直接连接到调试板的串口引脚上面,方便我们调试,无需在外接USB转TTL模块。
一:软件代码编写的基本配置思路:
1.1 主程序开始时,调用 HAL_Init() 函数来重置所有外围设备,
1.2 初始化 Flash 接口和系统。,
1.3 使用 SystemClock_Config() 函数将
1.4 STM32U0xx 器件的系统时钟 (SYSCLK) 配置为以 54 MHz 运行。
1.5 串口2的配置过程
UART 外设配置由 HAL_UART_Init() 函数确保。稍后调用 HAL_UART_MspInit() 函数,该内核根据使用的硬件(CLOCK、GPIO 和 NVIC)实现所需 UART 资源的配置。你可以更新此功能以更改 UART 配置。
配置串口2的模式如下:
波特率 = 115200 波特率
字长 = 8 位(8 个数据位,无奇偶校验位)
One Stop Bit
禁用硬件流控制(RTS 和 CTS 信号)
启用接收和传输
二:测试的方式和注意事项
该方法说明 STM32 UART 外设支持的不同方法,用于自动检测连接上使用的波特率。这种自动检测基于对一个字符的接收。
根据接收字符的不同模式,有 4 种自动波特率检测模式:
模式 0:起始位 在此模式下,USART 测量起始位的持续时间(下降沿到上升沿)。预期字符 :从 1 处以 bit0 开头的任何字符(例如“A”)
模式 1:下降沿 在此模式下,USART 测量 Start 和第 1 个数据位的持续时间。测量从下降沿到下降沿进行,以确保在信号斜率较慢的情况下具有更好的精度。预期字符 :以 10xx 位模式开头的任何字符(例如“1”)
模式 2:0x7F字符帧(在 LSB 优先模式下可能是 0x7F 字符,在 MSB 优先模式下可能是 0xFE)。在此模式下,波特率首先在起始位的末尾更新,然后在位 6 的末尾更新(基于从下降沿到下降沿的测量)。预期字符 : 0x7F字符,即 LSB 第一模式下的 DEL 键
模式 3:0x55字符框架。在此模式下,波特率首先在起始位的末尾更新,然后在 bit0 的末尾更新(基于从下降沿到下降沿的测量),最后在 bit6 的末尾更新。预期字符 : 0x55字符,即 LSB 第一模式下的 “U”
三:测试代码
3.1 串口的初始化
/** * @brief USART2 Initialization Function * @param None * @retval None */ static void MX_USART2_UART_Init(void) { /* USER CODE BEGIN USART2_Init 0 */ /* USER CODE END USART2_Init 0 */ /* USER CODE BEGIN USART2_Init 1 */ /* USER CODE END USART2_Init 1 */ huart2.Instance = USART2; huart2.Init.BaudRate = 115200; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; huart2.Init.ClockPrescaler = UART_PRESCALER_DIV1; huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT; huart2.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE; huart2.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetTxFifoThreshold(&huart2, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_SetRxFifoThreshold(&huart2, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK) { Error_Handler(); } if (HAL_UARTEx_DisableFifoMode(&huart2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART2_Init 2 */ /* USER CODE END USART2_Init 2 */ }
3.2 串口处理数据
/* For all supported Auto baud rate detection methods */ for (autobaudrate_mode = 0; autobaudrate_mode < NB_AUTO_BAUD_RATE_MODES; autobaudrate_mode++) { /* Configure UART with Auto baud rate method and current baud rate */ huart2.Init.BaudRate = baudrate; huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT; huart2.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE; huart2.AdvancedInit.AutoBaudRateMode = aDetectionMethods[autobaudrate_mode].AutoBaudRateMode; if (HAL_UART_Init(&huart2) != HAL_OK) { Error_Handler(); } /* Send msg using previously set baud rate */ PrintInfo(&huart2, aTextAskForNewBaudRate, COUNTOF(aTextAskForNewBaudRate)); PrintInfo(&huart2, aDetectionMethods[autobaudrate_mode].DetectionInfoText, aDetectionMethods[autobaudrate_mode].DetectionInfoTextSize); /* Reset transmission flag */ ReceptionReady = RESET; /* Wait for receiving 1 char */ HAL_UART_Receive_IT(&huart2, aRXBufferUser, 1); /* While waiting for character from PC side, LED4 is blinking according to the following pattern: toggle every 100ms */ while (ReceptionReady != SET) { /* Toggle LED4 every 100ms */ BSP_LED_Toggle(LED4); HAL_Delay(100); } /* Check if Auto baud rate detection has been successfully executed. If not, Auto baud Rate Detection error (ABRE) is reported */ if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_ABRE)) { ErrorDetected = SET; PrintInfo(&huart2, aTextErrorDetected, COUNTOF(aTextErrorDetected)); } else { /* Wait for completion of auto baud rate detection : ABRF flag in ISR */ while (!__HAL_UART_GET_FLAG(&huart2, UART_FLAG_ABRF)); /* Clear ABRF flag */ __HAL_UART_SEND_REQ(&huart2, UART_AUTOBAUD_REQUEST); /* Retrieve baud rate */ baudrate = LL_USART_GetBaudRate(huart2.Instance, periphclk, huart2.Init.ClockPrescaler, huart2.Init.OverSampling); /* Print result to Terminal */ if (aRXBufferUser[0] == DEL_ASCII_CODE) { /* Specific case of DEL character entered : "DEL" string to print printed on Terminal */ PrintInfo(&huart2, aDelString, COUNTOF(aDelString)); } else { PrintInfo(&huart2, aRXBufferUser, 1); } PrintInfo(&huart2, aTextDetectionResult, COUNTOF(aTextDetectionResult)); sprintf((char *) baudrate_string, "%u bps \n\n\r", (unsigned int) baudrate); PrintInfo(&huart2, baudrate_string, strlen((char *) baudrate_string)); } }
四:代码分析:
UART 外设初始化后,启动 UART/超级终端通信(板向 PC 终端控制台发送信息消息)。
由于此示例的目标是说明所有自动波特率检测模式的使用,因此将对 4 种模式中的每一种循环执行相同的过程。此过程可描述如下:
邀请用户选择新的波特率值,并相应地配置超级终端(从超级终端看到的通信现在将使用新的波特率值)提示符还指示从超级终端发送的预期字符,以触发自动波特率检测机制。
USART2 已初始化,并选择了自动波特率检测模式
在 STM32 UART 实例上启动接收(预期为 1 个字符)。等待期间,LED4 闪烁(每 100 毫秒切换一次)。
收到后,将检查 UART 标志,以确保在自动波特率检测过程中不会发生错误。如果成功,STM32 UART 端的波特率已自动更新(BRR 值)。检索此值,并使用新计算的波特率值将消息发送给用户。
如果 “ ...BRR 中的波特率值已调整为 XXX ...”消息在超级终端上正确接收,这意味着检测到的波特率值是准确的(用于从超级终端发送字符的波特率被正确检测到)。值可能与超级终端配置中设置的初始值略有不同。
如果执行成功,LED4 将亮起。如果遇到错误,LED4 每 500 毫秒切换一次。
五:测试截图如下: