首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我在STM32F407VET中使用UART中断方法时遗漏了一些字符

我在STM32F407VET中使用UART中断方法时遗漏了一些字符
EN

Stack Overflow用户
提问于 2019-06-03 21:22:44
回答 3查看 1.8K关注 0票数 1

我在中断模式下使用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);
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 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并不总是在他们的代码中做出明显或合作的选择)

票数 3
EN

Stack Overflow用户

发布于 2019-06-04 01:54:57

实际上,这里几乎所有的东西都是错的。不要以这种方式清除RXNE标志。当uC从数据寄存器读取数据时,该位由硬件清0。不要在中断处理程序中使用阻塞函数。

如果使用HAL,请使用回调函数。

我的建议是首先阅读uC文档和HAL手册,然后开始编程。

票数 0
EN

Stack Overflow用户

发布于 2019-06-04 02:32:22

此外,您可能正在超载USART。为了确认,在9600波特率下试一下,如果丢弃的字符较少,那就是你的问题。在这种情况下,您需要使用HW握手,或者添加一个缓冲区,并且不在IRQ处理程序中进行传输,而是在主循环中进行传输。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56428300

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档