Skip to main content
Bryan Guo
Associate II
April 27, 2017
Solved

HAL_UART_Receive() always timeout.

  • April 27, 2017
  • 9 replies
  • 7958 views
Posted on April 27, 2017 at 06:18

Hi all,

I met a strange problem that if I input something via a terminal before I call 

HAL_UART_Receive(); It will always timeout. And it will not recover until I reboot the board.

My code is as bellow.  What can I do to reset the status? Or enable the interrupt again?

while (1)

{

sprintf(aTxBuffer,'\r\nSTM32CubeMX rocks %d times \t', ++nbtime);

HAL_UART_Transmit(&huart2,(uint8_t *) aTxBuffer, strlen(aTxBuffer), 5000);

uart_rst = HAL_UART_Receive(&huart2,(uint8_t *) aRxBuffer, 2, 2000);

if(uart_rst==HAL_OK)

{

HAL_UART_Transmit(&huart2,(uint8_t *) str_ack, strlen(str_ack), 5000);

}

else if(uart_rst==HAL_TIMEOUT)

{

HAL_UART_Transmit(&huart2,(uint8_t *) str_to, strlen(str_to), 5000);

}

else

{

HAL_UART_Transmit(&huart2,(uint8_t *) str_err, strlen(str_err), 5000);

}

HAL_Delay(2000);

/* USER CODE END WHILE */

/* USER CODE BEGIN 3 */

}

/* USER CODE END 3 */

}

#uart
This topic has been closed for replies.
Best answer by Guenael Cadier
Posted on May 02, 2017 at 10:02

Hi,

My understanding of what could happen : as soon as Receiver is enabled (CR1_RE bit set to 1, I think this is your case), if a character is received, RXNE flag will be set to 1. On 2nd character received, if first one has not been read from RDR, data could not be transferred to RDR, and then Overrun error flag is raised. Then, any other data received while OVR is set is lost.

To make sure that above scenario corresponds to your use case, please check value of RXNE and OVR flags prior calling Receive procedure in case you entered some characters before.

If you want to discard previously received characters, you could clear OVR and RXNE flags prior calling

HAL_UART_Receive()

.

Let me know if this helps.

Regards

Guenael

9 replies

Bryan Guo
Bryan GuoAuthor
Associate II
April 27, 2017
Posted on April 27, 2017 at 14:54

I also tried HAL_UART_Receive_IT().  It can enter the callback only once.

Guenael Cadier
Guenael CadierBest answer
ST Employee
May 2, 2017
Posted on May 02, 2017 at 10:02

Hi,

My understanding of what could happen : as soon as Receiver is enabled (CR1_RE bit set to 1, I think this is your case), if a character is received, RXNE flag will be set to 1. On 2nd character received, if first one has not been read from RDR, data could not be transferred to RDR, and then Overrun error flag is raised. Then, any other data received while OVR is set is lost.

To make sure that above scenario corresponds to your use case, please check value of RXNE and OVR flags prior calling Receive procedure in case you entered some characters before.

If you want to discard previously received characters, you could clear OVR and RXNE flags prior calling

HAL_UART_Receive()

.

Let me know if this helps.

Regards

Guenael

Bryan Guo
Bryan GuoAuthor
Associate II
May 3, 2017
Posted on May 03, 2017 at 07:13

I add the code __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF|UART_CLEAR_OREF); before calling HAL_UART_Receive_IT().  It works. 

tian leixin
Visitor II
March 7, 2018
Posted on March 07, 2018 at 17:04

I get a trouble when using this function!

HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

HAL_UART_Receive 

when the rx data length less than size or equal with size,it works.When I try to send more data ,this function can't receive data any more

code as follow:

while(1)

{

res = HAL_UART_Receive(&console_uart,test,10,2000);

if(res == HAL_OK)

{

}

else if(res == HAL_TIMEOUT)

{

printf('timeout\n');

}

else if(res == HAL_BUSY)

{

printf('busy\n');

}

printf('%s',test);

memset(test,0,100);

}

}

Guenael Cadier
ST Employee
March 8, 2018
Posted on March 08, 2018 at 09:31

Hi

leixin.tian

‌,

Am I right ?

If you transmit 8 chars, you get 'timeout' output + string print

If you transmit 10 chars, you get test buffer printed out (string print)

If you transmit 12 chars, you get test buffer printed out (string print), then 'timeout'

In case of 12 chars sending, issue could be that while you are processing output of message and buffer printf (10, further characters received (11th and 12th) are leading IP to Overrun error case.

Once overrun has been encountered, RXNE flag will not go High again till OVR flag is cleared. Could you check value of OVR flag in SR/ISR register of your UART, when you consider reception is frozen ?

Note than depending on test buffer content, %s print could output more than the 10 chars received ...

Regards

Guenael