
问题: 我在项目中最初用的是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.的设备一起做长时间测试,做对比试验,目前暂未出现问题。 但网上的开发者说并不建议这样粗暴对策,我也暂不明确会有什么副作用,因此目前还在寻找更好的方法。 请问大佬们是否有什么建议? 感激不尽。 |
STM32F103RET6 FLASH擦除失败问题
stm32编码器模式计数问题
STM32H745启动与烧录问题
STM32G0b1 USB device cdc显示设备描述符请求失败
STM32CUBEMX最新版本6.14.1出现BUG
请问 cubemx 有计划支持生成基于 ATfE 编译器的 cmake 项目吗
设置RDP等级为2的同时,有什么办法可以确保后续还能够烧录程序
工程移植都有哪些需要注意的地方?
关于使用cubemx配置stm32g473re的opamp工作模式:Programmable gain amplifier mode with external filtering
关于ASM330LHH TR调试中的问题
应是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库写的,这样可能要大改了。
如果你有逻辑/总线分析仪甚至示波器,可以试着看一下出现问题的原因。不过你这个似乎是随机发生的,追查的难度还是很大的。