cancel
Showing results for 
Search instead for 
Did you mean: 

How are you supposed to use HAL_UART_Receive in STM32Cube ?

johan2
Associate II
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.

2 REPLIES 2
johan2
Associate II
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
Associate
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*/

   }

}