我正在使用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条件永远不会成立。
有人知道这段代码有什么问题吗?
答案 0 :(得分:2)
USART_FLAG_RXNE标志代表RX缓冲区非空。如果RX缓冲区中有数据,则标志为SET而不是RESET。
这就是你的代码被困在while循环中的原因。
答案 1 :(得分:-1)
我认为您的while循环没有问题。 通过您编写while的方式,它将一直执行到RXNE标志变为SET为止,对吗?并且(RXNE == 1)意味着,您的RX缓冲区中有东西。因此,当发生这种情况时,将不再执行while循环。
在我的想法中,问题可能是溢出错误标志,我的意思是当您不读取RX缓冲区并且擦除RXNE标志直到接收到新数据时,然后设置溢出错误标志而不是RXNE标志。在这种情况下,您需要清除ORE标志才能返回正常的接收模式,如果您使用的是HAL库,则可以通过LL_USART_ClearFlag_ORE(USARTx)
进行操作。
但是要确保这是导致while循环无限的原因,您可以将此条件添加到while:LL_USART_IsActiveFlag_ORE(USARTx)
中,就像这样:
while (!LL_USART_IsActiveFlag_RXNE(USART1) && !LL_USART_IsActiveFlag_ORE(USART1))
请注意,这段时间与
相同while (LL_USART_IsActiveFlag_RXNE(USART1) == 0 && LL_USART_IsActiveFlag_ORE(USART1) == 0)
您已经在使用。
如果这是您的问题,那么有一些方法可以改善您的数据接收算法:
第一个是使用中断来接收数据。
第二个方法是通过在函数中的参数和变量之前使用易失性关键字,强制编译器将变量保留在寄存器中,以加快执行速度。
最后,我认为通过将内核时钟频率设置得足够快,以使UART工作频率和波特率可以帮助您减少覆盖错误。