Thierno Barry
Thierno Barry

Reputation: 123

STM32: Receiving data via USART

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

Answers (2)

Linosa
Linosa

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

atoK
atoK

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

Related Questions