embeddedstm32uartbaud-ratestm32ldiscovery

Auto detect budrate serial stm32


IHello :) I have a STM32L031K6 and i use CubeMx; I want some auomatiser my reception function is adding automatic detection of transmission speed (baud rate) how I can do. i not find a code example online how to do it :/

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 /* Initalisation */

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 /* After interruption receive */

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);   
    }
}

thank you very much


Solution

  • There's two ways.

    Either use "brute force" trial & error, where you keep changing the baudrate, check all UART flags for errors, then repeat until you find the correct one. The down side of this is that it is "slow", you might need to check as many received data bytes as there are possible baudrates. You may also miss bytes, since you have no idea where in the received byte you are when you change the baudrate. That is, assuming continuous transmission.

    A simpler and faster solution is to wire the UART rx line to a timer pin with input capture feature. Simply measure the time between two edges. Take x number of samples so that you are certain that you caught the shortest received pulse somewhere. The shortest received pulse should be equivalent to one bit. And since 1/t=f, simply invert the time of one bit to get the frequency=baud rate.