简体   繁体   English

STM32:通过USART接收数据

[英]STM32: Receiving data via USART

I'm working on STM32 Discovery (F10x family), and I'm trying to send and receive data through USART1. 我正在研究STM32 Discovery(F10x系列),并且正在尝试通过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. uart_putc可以正常工作,但是uart_getc被困在while循环中,而while条件似乎永远都不成立。
Does someone know what is wrong with this code? 有人知道这段代码有什么问题吗?

The USART_FLAG_RXNE flag stands for RX buffer Not Empty. USART_FLAG_RXNE标志代表RX缓冲区不为空。 If there's data in the RX buffer the flag is SET and not RESET. 如果RX缓冲区中有数据,则标志为SET而不是RESET。

That's why your code is stucked in the while loop. 这就是为什么您的代码被困在while循环中的原因。

I think that there is no problem with your while loop. 我认为您的while循环没有问题。 By the way you have written the while, it will be executed until RXNE flag becomes SET, right? 通过您编写while的方式,它将一直执行到RXNE标志变为SET为止,对吗? And that (RXNE == 1) means , there is something in your RX buffer. 并且(RXNE == 1)意味着,您的RX缓冲区中有东西。 So when this happens the while loop would no longer be executed. 因此,当发生这种情况时,将不再执行while循环。

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. 在我看来,问题可能是溢出错误标志,我的意思是当您不读取RX缓冲区并擦除RXNE标志直到接收到新数据时,然后设置溢出错误标志而不是RXNE标志。 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. 在这种情况下,您需要清除ORE标志才能返回正常的接收模式,如果您使用的是HAL库,则可以通过LL_USART_ClearFlag_ORE(USARTx)进行操作。 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循环无限的原因,您可以将此条件添加到while中: LL_USART_IsActiveFlag_ORE(USARTx)就像这样:

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. 最后,我认为通过将内核时钟频率设置得足够快,以使UART工作频率和波特率可以帮助您减少覆盖错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM