如何在 STM32F1 上使用 HAL 库永久启用 uart RX 中断
Posted
技术标签:
【中文标题】如何在 STM32F1 上使用 HAL 库永久启用 uart RX 中断【英文标题】:How to keep uart RX interrupt enabled forever using HAL library on a STM32F1 【发布时间】:2016-08-08 02:23:02 【问题描述】:我看到 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 生成的代码? 如果不是,那么覆盖所涉及功能的干净方法是什么? 我是否缺少一些可以避免需要找到此解决方案的东西?
【问题讨论】:
这似乎是一个没有简单解决方案的已知问题:***.com/questions/24875873/stm32f4-uart-hal-driver 似乎 DMA 可以将数据从任何外围设备写入任何内存缓冲区,包括环形缓冲区(DMA 设置)。而 DMA 中断是在接收时刻处理所有数据甚至其一半数据的简单方法。 这并不取决于您的问题。但我认为尝试 keil io 驱动程序可能是值得的。这是您可以为您的 mcu 找到它们的链接 keil.com/dd2/pack 【参考方案1】:您可以通过轮询方法而不是中断方法尝试 UART。 轮询方式:UART在接收到“Size”参数指定的数据量后才会返回。
【讨论】:
问题是“大小”是可变的,而我的应用程序对时间要求很高,这就是我首先使用中断的原因。通过编辑 HAL 函数UART_Receive_IT
使其工作,因此传入字节直接进入环形缓冲区并且不会禁用中断【参考方案2】:
我认为您必须输入一个特殊字符来指示按摩的结束,或者您可以制定自己的协议,例如消息头、消息长度、内容、校验和 并为一个字节启用中断,并在中断处理程序中存储接收到的缓冲区,直到找到消息中的最后一个字节,然后在 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 总线是否有错误。
【讨论】:
【参考方案3】:试试这个
__HAL_UART_ENABLE_IT(&huart2, UART_IT_RXNE);
【讨论】:
【参考方案4】:带有 DMA(用于接收)的循环缓冲区似乎是满足您要求的解决方案。这将始终提供 RX 中断(您只需配置一次)。
对于类似的要求,我通常使用 1 字节的循环缓冲区来处理数据。接收处理将在 ISR 中完成。
【讨论】:
以上是关于如何在 STM32F1 上使用 HAL 库永久启用 uart RX 中断的主要内容,如果未能解决你的问题,请参考以下文章