我是STM32和freerto的新手。我需要编写一个程序来通过UART端口从模块发送和接收数据。我必须向该模块发送(传输)数据(例如。M66)。然后我会回来做一些其他任务。一旦 M66 发送响应,我的 seial-port-receive-function(HAL_UART_Receive_IT) 必须被调用并接收该响应。我怎样才能做到这一点?
HAL_UART_Receive_IT
的工作方式是将其配置为将指定数量的数据接收到给定的缓冲区中。你给它你的缓冲区,它将读取接收的数据和你想要接收的字节数。然后它开始接收数据。一旦收到如此数量的数据,HAL_UART_RxCpltCallback
就会调用一个回调函数(从 IRQ),您可以在其中对这些数据执行任何操作,例如将其添加到某种队列中,以便稍后在任务上下文中进行处理。
如果要表达我与使用 HAL 的 UART 模块相关的经验,它并不是您不知道您希望提前接收的数据量的通用用途的最佳模块。在您提到的M66调制解调器的情况下,这种情况将一直发生。
要解决此问题,您有两种选择:
-
在UART的情况下,除了初始化函数之外,根本不使用HAL函数。实现您自己的UART中断处理程序(大多数代码可以从HAL中的处理程序复制),在接收数据时,您将接收的字节放在RTOS任务中处理的接收字节队列中。在此任务中,您将实现协议分析。这是我个人使用的方法。
-
如果您确实想使用 HAL,但也要使用发送不同数据量的模块,请调用
HAL_UART_Receive_IT
并指定每次要接收 1 个字节。这将起作用,但(可能)比第一种方法慢得多。假设您以后想要实现一些TCP/IP通信(您提到了M66 GPRS模块),您可能不想这样做。
您应该尝试以下方法。
在 NVIC 中启用 UARTX Rx 中断。 设置中断优先级。 在 EXTI 中取消屏蔽中断请求。
然后在向量中使用 USARTX 中断处理程序函数定义。
每当从 USARTX 接收数据时,都会自动调用此函数,您可以从 USARTX 接收数据寄存器复制数据。
我宁愿建议另一种方法。您可能希望存档更高的速度(假设 921600 个 bods),并且中断方式会因此而变慢。
您需要使用数据端检测功能实现 DMA 传输。在循环模式下的 DMA 模式下运行 USART。您将有两个活动要服务。第一个是 DMA 结束的中断(然后您将数据从当前尾指针复制到缓冲区的末尾以避免数据覆盖)和 USART 空闲中断 - 这将检测接收的结束。