我在中断模式下使用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);
}
答案 0 :(得分:2)
您正在接收一个字节,并将该字节放入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)
在中断模式下接收一定数量的字节。
可以在stm32f4xx_hal_uart.c
中找到UART的库代码。 STM的HAL可读性强,信息灵通,可以随时查看。将来可以帮助发现其他错误。 (ST并不总是在其代码中做出明显或合作的选择)
答案 1 :(得分:0)
实际上,这里的所有内容都不对。不要这样清除RXNE标志。当uC从数据寄存器中读取数据时,硬件会将其清除。不要在中断处理程序中使用阻塞函数。
如果您使用HAL,请使用回叫功能。
我的建议首先阅读uC文档和HAL手册,然后开始编程。
答案 2 :(得分:0)
此外,您可能会超出USART。要确认,请以9600波特尝试,如果删除的字符较少,那就是您的问题。在这种情况下,您需要使用硬件握手,或者添加一个缓冲区,并且不在IRQ处理程序中进行传输,而是在主循环中进行传输。