问题: 我在项目中最初用的是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.的设备一起做长时间测试,做对比试验,目前暂未出现问题。 但网上的开发者说并不建议这样粗暴对策,我也暂不明确会有什么副作用,因此目前还在寻找更好的方法。 请问大佬们是否有什么建议? 感激不尽。 |
各位大神,这个怎么解决!
哪位大哥有stm32f103c8t6的keil编程实例源码呀?求
STM32H747的串口加DMA
能在一个程序中同时使用TIM的callback和uart的callback函数吗?
Cubemax 生成的文件夹选项包含Core文件夹
TCP客户端 周期性 发送数据,一段时间后会突然停止,是什么原因。
STM32F103VCT6有64K的RAM?
多路ADC使用DMA模式有没有教程呀,芯片STM32L151
cubemx配置开发板引脚但已经被占用
cubemx升级6.11后,左侧congfiguration选项出不来,鼠标转圈
应是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库写的,这样可能要大改了。
如果你有逻辑/总线分析仪甚至示波器,可以试着看一下出现问题的原因。不过你这个似乎是随机发生的,追查的难度还是很大的。