1

我正在研究 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工作正常,但 uart_getc 卡在 while 循环中,似乎 while 条件永远不会为真。
有人知道这段代码有什么问题吗?

4

2 回答 2

3

USART_FLAG_RXNE 标志代表 RX 缓冲区非空。如果 RX 缓冲区中有数据,则标志为 SET 而不是 RESET。

这就是为什么您的代码卡在 while 循环中的原因。

于 2014-06-24T15:44:01.653 回答
0

我认为您的 while 循环没有问题。顺便说一句,你写了while,它会一直执行到RXNE标志变为SET,对吧?这 (RXNE == 1) 意味着,你的 RX 缓冲区中有东西。因此,当这种情况发生时,while 循环将不再执行。

在我的想法中,问题可能是溢出错误标志,我的意思是当您不读取 RX 缓冲区并且擦除 RXNE 标志直到要接收新数据时,然后设置溢出错误标志而不是 RXNE 标志。在这种情况下,您需要清除 ORE 标志才能恢复正常接收模式,LL_USART_ClearFlag_ORE(USARTx)如果您使用的是 HAL 库,则可以通过以下方式执行此操作。但是为了确保这是无限循环的原因,您可以将此条件添加到 while :LL_USART_IsActiveFlag_ORE(USARTx)它会是这样的:

while (!LL_USART_IsActiveFlag_RXNE(USART1) && !LL_USART_IsActiveFlag_ORE(USART1))

请注意,这个 while 与

while (LL_USART_IsActiveFlag_RXNE(USART1) == 0 && LL_USART_IsActiveFlag_ORE(USART1) == 0)

你已经在使用了。

如果这是您的问题,那么有一些方法可以改进您接收数据的算法:第一个是使用中断来接收数据。
第二个是通过在函数中的参数和变量之前使用 volatile 关键字来强制编译器将变量保存在寄存器中以便更快地执行。
最后,我认为通过将您的核心时钟频率设置得足够快,以使您的 UART 工作频率和波特率可以帮助您减少覆盖错误。

于 2019-11-27T20:47:47.303 回答