Reputation: 123
I'm working on STM32 Discovery (F10x family), and I'm trying to send and receive data through USART1.
int uart_putc(int c, USART_TypeDef* USARTx)
{
assert_param(IS_USART_123_PERIPH(USARTx));
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USARTx->DR = (c & 0xff);
return 0;
}
int uart_getc (USART_TypeDef* USARTx)
{
assert_param(IS_USART_123_PERIPH(USARTx));
while (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == RESET);
return USARTx->DR & 0xff;
}
uart_putc
works finely but uart_getc gets stucked in the while loop, it seems like the while condition is never true.
Does someone know what is wrong with this code?
Upvotes: 2
Views: 15148
Reputation: 31
I think that there is no problem with your while loop. By the way you have written the while, it will be executed until RXNE flag becomes SET, right? And that (RXNE == 1) means , there is something in your RX buffer. So when this happens the while loop would no longer be executed.
In my idea the problem problem could be overrun error flag, i mean when you do not read RX buffer and that erase RXNE flag until new data is to be received, Then the overrun error flag become set instead of RXNE flag. and in this case you need to clear ORE flag in order to get back to normal receiving mode, you can do this via LL_USART_ClearFlag_ORE(USARTx)
if you are using HAL library.
But to make sure that this is the cause of infinite while loop, you can add this condition to the while : LL_USART_IsActiveFlag_ORE(USARTx)
and it would be like this :
while (!LL_USART_IsActiveFlag_RXNE(USART1) && !LL_USART_IsActiveFlag_ORE(USART1))
notice that this while is the same as
while (LL_USART_IsActiveFlag_RXNE(USART1) == 0 && LL_USART_IsActiveFlag_ORE(USART1) == 0)
That you have already been using.
If this is your issue then there is some methods to improve your algorithm of receiving data:
First one is to use interrupts for receiving data.
Second one is to force compiler to keep your variables in registers for faster execution by using volatile key word before parameters and variables in the function.
And finally i think that by setting your core clock frequency faster enough that your UART working frequency and baud rate might help you to reduce override errors.
Upvotes: 0
Reputation: 49
The USART_FLAG_RXNE flag stands for RX buffer Not Empty. If there's data in the RX buffer the flag is SET and not RESET.
That's why your code is stucked in the while loop.
Upvotes: 4