这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » STM32 » NUCLEO-U083RC学习历程18-学习串口自动检测波特率

共1条 1/1 1 跳转至

NUCLEO-U083RC学习历程18-学习串口自动检测波特率

助工
2025-01-09 19:29:42     打赏

今天和大家分享一下,如何使用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 毫秒切换一次。

五:测试截图如下:

0109-1.png





关键词: NUCLEO-U083RC     串口     自动检测     波特率    

共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]