自动检测budrate串口stm32

Auto detect budrate serial stm32

IHello :) 我有一个 STM32L031K6 并且我使用 CubeMx;我想要一些 auomatiser 我的接收功能是添加自动检测传输速度(波特率)我该怎么做。 我没有在网上找到代码示例如何操作:/

Usart.c

UART_HandleTypeDef huart2;

/* USART2 init function */

void MX_USART2_UART_Init(void)
{

  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_EVEN;
  huart2.Init.Mode = UART_MODE_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.OverrunDisable = UART_ADVFEATURE_OVERRUN_DISABLE;
  huart2.AdvancedInit.DMADisableonRxError = UART_ADVFEATURE_DMA_DISABLEONRXERROR;  
 huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_AUTOBAUDRATE_INIT;

      /* Configure the AutoBaudRate method */
  huart2.AdvancedInit.AutoBaudRateMode = UART_ADVFEATURE_AUTOBAUDRATE_ONSTARTBIT; //Mode 0

  /* Enable AutoBaudRate feature */
  huart2.AdvancedInit.AutoBaudRateEnable = UART_ADVFEATURE_AUTOBAUDRATE_ENABLE;

  /* Wait until Receive enable acknowledge flag is set */
  while(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_REACK) == RESET)
  {} 

  /* Wait until Transmit enable acknowledge flag is set */ 
  while(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TEACK) == RESET)
  {} 

  /* Loop until the end of Autobaudrate phase */
  while(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_ABRF) == RESET)
  {}

  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  } 
}

Main.c

int main(void)
{
    //Initialisation de la carte STM32L031K6
    HW_Init(); 
  while (1)
  {
  }

Hardware.c /* 初始化 */

void HW_Init(void)
{  
    /* Remise à zéro de tous les périphériques, Initialise l'interface flash    */
    /* et System Timer (SysTick) */
  HAL_Init();

    /* Configuration de l'horloge à 8Mhz pour notre cas */
  SystemClock_Config();

  /* Initialisation tous les périphériques configurés GPIO (Led verte) */
    /* et USART2*/
  MX_GPIO_Init();
  MX_USART2_UART_Init();

    /* If AutoBaudBate error occurred */
  if (__HAL_UART_GET_FLAG(&huart2, UART_FLAG_ABRE) != RESET)
  {}
  else
  {  
    /* Wait until RXNE flag is set */
    while(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_RXNE) == RESET)
    {}

    /* Wait until TXE flag is set */   
    while(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_TXE) == RESET)
    {}

      /* Receive data */
        HAL_UART_Receive_IT(&huart2, Rx_data, 1);

  }
}

IRQ_Receive.c /* 中断后接收 */

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    //Tester L'UART selectionner en l'occurence pour nous c'est l'USART2
    if (huart->Instance == USART2)
    {  
        /* Appeler notre fonction receive qui permet de sauvegarder chaque octet */
        /* reçu dans un Buffer */
        Receive();
        HAL_UART_Receive_IT(&huart2, Rx_data, 1);   
    }
}

非常感谢

有两种方法。

要么使用 "brute force" 试错法,在这种情况下不断更改波特率,检查所有 UART 标志是否有错误,然后重复直到找到正确的标志。不利的一面是它是 "slow",您可能需要检查尽可能多的接收数据字节,因为有可能的波特率。您也可能会丢失字节,因为您不知道在更改波特率时接收到的字节位于何处。即假设连续传输。

一种更简单、更快速的解决方案是将 UART 接收线连接到具有输入捕获功能的定时器引脚。只需测量两个边缘之间的时间。取 x 个样本,以便确定您在某处捕获了最短的接收脉冲。最短的接收脉冲应等于一位。并且由于1/t=f,只需将一位的时间取反即可得到频率=波特率。