Skip to main content
johan2
Associate
November 25, 2014
Question

How are you supposed to use HAL_UART_Receive in STM32Cube ?

  • November 25, 2014
  • 2 replies
  • 1251 views
Posted on November 25, 2014 at 18:52

I am implementing a command parser that receives data on a serial port. My need is to read one byte at a time and when I recive a full command I will handle it.

I look at the example in STM32Cube_FW_L0_V1.1.0\Projects\STM32L053R8-Nucleo\Examples\UART\UART_TwoBoards_ComPolling\Src\main.c

In line 152:

  if(HAL_UART_Receive(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE, 5000) != HAL_OK)

  {

    Error_Handler();  

  }

I have modified this to lower the timeout value and set RXBUFFERSIZE to 1 and call the function in a loop.

However I think the original code is not a good example since if the function HAL_UART_Recive gets timeout the function will return HAL_TIMEOUT and the code will end up in the Error_Handler with a while(1) loop.

If just ignoring this by not calling Error_Handler when getting HAL_TIMEOUT and call the function HAL_UART_Recive once more it will return HAL_BUSY. And it seems like no way to get out of this. So I think this example is broken if it would serve as an example on how to use HAL_UART_Receive with a timeout.

So if possible if someone could share with me a code snippet where you can read bytes once at a time in a loop from UART with correct error handling I would be happy.

    This topic has been closed for replies.

    2 replies

    johan2
    johan2Author
    Associate
    November 27, 2014
    Posted on November 27, 2014 at 15:39

    I ended up with using the stm32snippetsl0 library for doing this. This was much more straightforward.

    I think that the STM32Cube library needs more work before you can actually base your work on this.

    diego2
    Visitor II
    November 28, 2014
    Posted on November 28, 2014 at 23:08

    yes you right, is not a good example by far, the problem is, the function is expected a fixed number of characters within a timeout, i think this approach is fine but the function needs to return the number of the actual bytes received after a timeout, This is what i did with interrupts.

    /*hotboards.org*/uint8_t RxBuffer[10];   

    /*Buffer donde se respalda la informacion recivida*/

    uint8_t RxByte;         

    /*Byte de recepcion temporal*/

    __IO ITStatus stat = RESET;

    /*Bandera que indica si transmisor esta libre*/

    UART_HandleTypeDef UartHandle;

    /*declaramos estructura tipo uart*/

    int

    main(

    void

    )

    {     

       GPIO_InitTypeDef GPIO_InitStruct;

    /*declaramos estructura tipo gpios*/

       HAL_Init();

    /*incializamos libreria cube*/

       

       __GPIOA_CLK_ENABLE();            

     /*habilitamos reloj del puerto A*/

       

    /*configuramos pin 8, 9 y 10 en modo salida push-pull*/

       GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;

       

       GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

       GPIO_InitStruct.Pull = GPIO_NOPULL;

       GPIO_InitStruct.Speed = GPIO_SPEED_FAST;

       

    /*aplicamos configuracion*/

       HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

       

    /*declaramos las opciones para configurar el modulos UART2, 9600 baudrate,

       8bits, 1 bit de stop, sin paridad y sin control de flujo */

       UartHandle.Instance = USART2;

       UartHandle.Init.BaudRate = 9600;

       UartHandle.Init.WordLength = UART_WORDLENGTH_8B;

       UartHandle.Init.StopBits = UART_STOPBITS_1;

       UartHandle.Init.Parity = UART_PARITY_NONE;

       UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;

       UartHandle.Init.Mode = UART_MODE_TX_RX;

       UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;

       

    /*inicilizamos uart1 con los parametros anteriores*/

       HAL_UART_Init(&UartHandle);

       

    while

    (1)

       {

           

    if

    (HAL_UART_GetState(&UartHandle) == HAL_UART_STATE_READY)

    {

    /*Receptor esta libre para mnadar interupcion por recepcion*/

        HAL_UART_Receive_IT(&UartHandle, &RxByte, 1);

    }

           

    if

    (stat == SET)

    /*llego cadena completa por serial*/

           {

               stat = RESET;

    /*limpiamos la bandera*/

               

    if

    (memcmp(

    ''uno\r''

    , RxBuffer,

    sizeof

    (

    ''uno\r''

    )-1) == 0)

               {   

    /* si fue la palabra led\r invierto led en A8 */

                   HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8);

               }

               

    else

    if

    (memcmp(

    ''dos\r''

    , RxBuffer,

    sizeof

    (

    ''dos\r''

    )-1) == 0)

               {   

    /* si fue la palabra led\r invierto led en A9 */

                   HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9);

               }

               else

    if

    (memcmp(

    ''tres\r''

    , RxBuffer,

    sizeof

    (

    ''tres\r''

    )-1) == 0)

               {   

    /* si fue la palabra led\r invierto led en A10 */

                   HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_10);

               }

           }

       }

    }

    /*

    Funcion callback que respalda los caracteres llegados e informa cuando llego el caracter \r que significa fin de cadena*/

    void

    HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)

    {   

       

    static

    uint32_t i = 0;

       RxBuffer[i] = RxByte;     

    /*se respalda dato*/

       i++;                      

    /*incremento indice*/

       

    if

    (RxBuffer[i-1] ==

    '\r'

    )

    /*fin de cadena?*/

       {

           stat = SET;           

    /*activo bandera de cadena completa*/

           i = 0;                

    /*reinicia indice*/

       }

    }