
问题: 我在项目中最初用的是HAL_UART_Receive_IT,HAL_UART_Transmit。每次在接收到数据后会在回调函数里再次调用HAL_UART_Receive_IT。 当高频进行串口数据收发时,发现有概率不能正常接收数据。 问题发生后断电重启后,又恢复正常。 根据各种调查外加查资料,发现主要原因应是 __HAL_LOCK 的直接返回,导致HAL_UART_Receive_IT 失败后不能再开中断。 stm32f103 HAL 库的 串口中断方式接收数据的函数HAL_UART_Receive_IT、发送函数 HAL_UART_Transmit_IT、HAL_UART_Transmit 的内部实现都有 __HAL_LOCK(huart); 根据其实现,若调用时发现已经上锁,则会直接返回 HAL_BUSY。 1.有人建议说使用 HAL_UART_Transmit_IT代替HAL_UART_Transmit,但是我看内部实现都有 __HAL_LOCK(huart),这样一来只是会减小上述问题发生的概率,并未解决问题,因此并未采用。 2.我尝试在原本HAL_UART_Receive_IT的地方都追加了返回值判断,一旦返回 HAL_BUSY,就去主循环每10ms重新调用一次 HAL_UART_Receive_IT,直到返回正确。 但是经过长时间测试,又发生了问题,无法接续正常收发数据了。 3.我尝试在 HAL_UART_Receive_IT的实现里,把__HAL_LOCK(huart) 注释掉,跟2.的设备一起做长时间测试,做对比试验,目前暂未出现问题。 但网上的开发者说并不建议这样粗暴对策,我也暂不明确会有什么副作用,因此目前还在寻找更好的方法。 请问大佬们是否有什么建议? 感激不尽。 |
STM32N6570-DK开发板,哪里还有卖的?
STM32H7R7 CubeMX无配置问题
如何解决用CubeMX生成代码时会将main.c文件中的汉字变成乱码的问题?
stm32ide怎么正确的导出项目
STM32F105RBT6 2025年 ROSH REACH 报告
用NanoEdge Ai训练多分类后输出概率一直为一样的值,传不同数据永远都是一样的概率
STM32F723ZET6使用ADC捕获标准正弦波并通过USB主动上报,正弦波重新拟合后存在凹陷峰?
STM32CubeMX 使用"FW_F1 V1.8.6"生成FreeRTOS代码缺少"freertos_mpool.h"?
你好,我的setting里面设置都没有问题。但是显示failed download cortexm3
STM32N6 cubeAI部署时用的内存是在内部还是外部?
应是HAL_UART_Transmit里Lock生效后,HAL_UART_Receive_IT拿不到锁,直接返回的HAL_BUSY
之前在其他博客里也发现了对ORE的说明,建议在HAL_UART_ErrorCallback 里做清标志的动作。
尝试后发现问题还发生,然后才对HAL_UART_Receive_IT 下手的... 不过也还是没有完全弄清楚。
LL库还没有用过,听说是新出的,如果直接上LL估计有不少东西要重写吧...
感谢分析讲解。 之前看了下uart 收发函数里LOCK的内容,他们之间有关系的可能就是huart->ErrorCode = HAL_UART_ERROR_NONE; 这个东西。 后面在中断处理时候会做为判断条件。
至于耗时问题,因为现在发送时用的是HAL_UART_Transmit,如果执行得慢,会阻塞LOCK,这个问题就比较容易发生了。 有考虑过把HAL_UART_Transmit 变更为HAL_UART_Transmit_IT,这样阻塞时间就会短得多。只会LOCK几个赋值
/* Process Locked */
__HAL_LOCK(huart);
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX;
/* Process Unlocked */
__HAL_UNLOCK(huart);
但是毕竟理论上还是存在发生问题的可能性的,所以就没有改 HAL_UART_Transmit_IT,直接去动HAL_UART_Receive_IT 了= = 但是感觉太粗暴,不怎么合理,问题倒是还没有再现出来。。。
(以前跑几十次测试就能测出来,现在跑了五千多次了...)
至于中断的使用,目前除了UART,都是CubeMX配置外设后自动配好的,级别默认都是0,就没有去改:
请问DMA 方式可以避免当前这种问题的么? 还没有用过,需要学习一下。 如果可以,这貌似是比较合理的办法。
LL库的话到这个阶段貌似不太合适,因为其他代码也都是基于HAL库写的,这样可能要大改了。
如果你有逻辑/总线分析仪甚至示波器,可以试着看一下出现问题的原因。不过你这个似乎是随机发生的,追查的难度还是很大的。