如何使用HAL库在STM32F1上永久保持uart RX中断使能

5
我看到HAL提供了以下用于接收串行数据的中断函数:HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size),它基本上是设置rx中断并返回。
当接收到的字节数达到Size时,将调用HAL_UART_RxCpltCallback()
HAL在执行此回调之前禁用rx中断

问题:
传入字节的数量将是可变的(从1到~100),我需要将它们放入环形缓冲区。
因此,我将Size设置为1,并在回调函数中再次调用HAL_UART_Receive_IT()以重新启用中断,并且如果板子每隔一段时间发送1或2个字节,则可以正常工作,但是超出这个范围的字节会丢失

我的猜测是它们被错过了,因为它们到达了中断禁用-启用之间

是否有办法使中断永久运行而不覆盖HAL Cube生成的代码?
如果没有,是否有一种干净的方法来覆盖涉及的功能?
是否有什么我忽略了而避免找到此解决方案的方法?


1
这似乎是一个已知的问题,没有简单的解决方案:https://dev59.com/2mAf5IYBdhLWcg3wOQm2 - Ross Ridge
1
似乎DMA是将数据从任何外设写入任何内存缓冲区(包括环形缓冲区)的方法(DMA设置)。而DMA中断是在接收时处理所有数据甚至其一半的简单方法。 - Yuriy
这并不完全回答你的问题。但我认为尝试使用Keil IO驱动程序可能是值得的。以下是您可以找到适用于您的MCU的链接:https://www.keil.com/dd2/pack/ - Long Smith
4个回答

2
使用DMA的循环缓冲区(用于接收)似乎是符合您要求的解决方案。这将始终提供RX中断(您只需配置一次即可)。
对于类似的要求,通常我使用一个1字节的循环缓冲区来处理数据。接收处理将在ISR中完成。

2

试试这个

__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);

0
您可以尝试使用轮询方法而非中断方法来进行UART通信。 轮询方法:UART将不会返回任何数据,直到它接收到由“Size”参数指定的数据量。

2
问题在于“大小”是可变的,而我的应用程序对时间非常敏感,这就是我首先选择中断的原因。 通过编辑HAL函数UART_Receive_IT,使传入的字节直接进入环形缓冲区,从而使其正常工作,并且不会禁用中断。 - Gerard Vuyk

0

我认为你需要放置一个特殊字符来表示消息的结束,或者你可以自己制定协议,例如消息头、消息长度、内容和校验和,并且使能一个字节的中断,在中断处理程序中存储接收到的缓冲区,直到找到消息中的最后一个字节,然后将其发送给主任务(在RTOS的情况下),或者设置一个全局标志。 顺便说一下,请确保设置适当的接收字节数大小。

HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

内部

HAL_UART_RxCpltCallback

请检查 HAL_UART_Receive_IT 的返回值,它可能会返回错误,并且需要实现。
void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle);

并检查UART总线是否存在错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接