我在中断模式下使用STM32F407VE的UART1。波特率是115200。我使用docklight串行窗口来读取UART输出。我一次发送15到20个字符。当我检查环回代码时,我发现缺少字符,如下所示。
我试着换了波特率。但是当我增加字符数时,同样的问题仍然存在。这是我的中断处理程序:
void USART1_IRQHandler(void) {
uint8_t data;
HAL_UART_IRQHandler(&huart1);
__HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE);
data = (uint8_t)(huart1.Instance->DR); //& (uint16_t)0x00FFU);
HAL_UART_Transmit(&huart1, (uint8_t *)&data, 1, 10);
}
发布于 2019-06-03 22:54:21
您正在接收一个字节并将该字节放入UART的TDR
寄存器中。它可能正在以相同的波特率运行,因此在传输完成之前,会收到一个新的接收中断。对HAL_UART_Transmit
的调用正在阻塞,并将检查传输是否正在运行。语句if(huart->gState == HAL_UART_STATE_READY)
将返回false
,因此将采用else
路径。这将导致返回值为HAL_BUSY
。这表明没有发生传输,因为其中一个仍在进行中。
你需要添加一个循环缓冲区来修复这个问题。将接收到的字节存储在中断处理程序中的存储容器中,程序的另一部分需要检查存储容器是否为空,如果不为空,则传输内容。在更新存储容器时,您需要禁用中断,因为可能会出现竞争条件。
您还可以在传输中添加传输结束字符,以指示可以安全地将其回显给您,从而避免竞争条件。如果你使用ASCII码,0x04
是一个很好的选择,因为它被定义为EOT
(传输结束)。
另一种选择是在中断模式下使用HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
接收设定数量的字节。
UART的库代码可以在以下位置找到:stm32f4xx_hal_uart.c
。STM的HAL可读性很好,很有启发性,你可以随意看看里面。它可以帮助将来找到其他的bug。(ST并不总是在他们的代码中做出明显或合作的选择)
发布于 2019-06-04 01:54:57
实际上,这里几乎所有的东西都是错的。不要以这种方式清除RXNE标志。当uC从数据寄存器读取数据时,该位由硬件清0。不要在中断处理程序中使用阻塞函数。
如果使用HAL,请使用回调函数。
我的建议是首先阅读uC文档和HAL手册,然后开始编程。
发布于 2019-06-04 02:32:22
此外,您可能正在超载USART。为了确认,在9600波特率下试一下,如果丢弃的字符较少,那就是你的问题。在这种情况下,您需要使用HW握手,或者添加一个缓冲区,并且不在IRQ处理程序中进行传输,而是在主循环中进行传输。
https://stackoverflow.com/questions/56428300
复制相似问题