[STM32L4] STM32L431KCUX UART 中断接收最多只能收 49 字节超过就卡死

[复制链接]
79|10
石榴大王 发表于 2026-6-18 23:04 | 显示全部楼层 |阅读模式
我的固件通过 UART 中断回调搭配三段状态机处理串口数据:
状态 1:循环单次接收 1 字节,等待帧头标记;收到标记后,调用UART_Receive_IT读取下一字节(消息长度),切换到状态 2;
状态 2:用上一步读到的长度作为总字节数,调用UART_Receive_IT一次性接收整条报文;
状态 3:全部数据接收完成后解析报文。
短报文完全正常;当发送总长 147 字节长报文时,状态 3 ***不会触发。调试观察huart2->RxXferCount从 147 递减到 98 后不再变化,UART 接收中断服务函数UART_RxISR_8BIT不再进入,状态机卡住,直到软件超时触发接收终止。
发送工具使用 RealTerm;
卡死时硬件流控 RTS/CTS 引脚均为低电平;
接收超时从 20ms 拉长至 1s,无改善;
UART 溢出标志 ORE 未置 1,无硬件溢出;
接收缓冲区尺寸远大于 147 字节,不存在越界;
改为分批次 32 字节分段调用UART_Receive_IT:第一批正常接收,累计收到 49 字节后第二批直接卡死;
多次调用UART_Receive_IT之间不需要手动复位 UART,是否理解有误?
请问什么原因会导致 UART 接收中途停止触发中断?还有哪些调试手段可以排查?

公羊子丹 发表于 2026-6-19 08:30 | 显示全部楼层
我之前踩过一模一样的坑,大概率是连续调用Receive_IT没判断返回值!回调里直接调用很容易返回HAL_BUSY,串口直接锁死,你打印下每次调用的返回状态看看是不是这个问题。
周半梅 发表于 2026-6-19 08:31 | 显示全部楼层
别在RxCpltCallback里做复杂报文解析,中断里耗时操作会拖慢接收,数据一快直接中断卡死。建议只存数据打标志,解析丢主循环跑,我改完就没出现过49字节截断。
帛灿灿 发表于 2026-6-19 08:32 | 显示全部楼层
你有没有查NVIC中断优先级?如果有定时器、ADC这类更高优先级中断频繁抢占串口,大数据接收中途就会停中断,试着把UART中断优先级调高再测试长报文。
童雨竹 发表于 2026-6-19 08:33 | 显示全部楼层
HAL库这个锁机制真的坑死人,连续多次开接收很容易锁死huart句柄。你可以单步跟踪__HAL_LOCK那段代码,大概率是锁没正常释放导致中断不再触发。
万图 发表于 2026-6-19 08:34 | 显示全部楼层
先换IDLE空闲中断搭配DMA接收试试,彻底放弃分段Receive_IT。DMA一次性收完整帧,不会出现中途断中断,长报文处理比纯中断稳定太多,适合百字节数据。
Wordsworth 发表于 2026-6-19 08:35 | 显示全部楼层
虽然你说ORE没置位,但会不会有FE/PE帧错误没清?HAL库检测到错误会直接关闭接收中断,你在ISR里加代码把所有串口错误标志全部清除再重试。
Bblythe 发表于 2026-6-19 08:36 | 显示全部楼层
千万不要连续无间隔调用Receive_IT,上一次接收没就绪就开下一次直接BUSY卡死。加个判断,等huart状态为READY再发起下一段接收请求。
Pulitzer 发表于 2026-6-19 08:37 | 显示全部楼层
硬件流控虽然电平正常,但长报文时RealTerm下发太快,芯片内部FIFO塞满也会停中断。你先关掉RTS/CTS重新测试,排除流控逻辑干扰。
Uriah 发表于 2026-6-19 08:38 | 显示全部楼层
卡死的时候直接读取USART状态寄存器SR,看RXNE、IDLE这些标志位状态,能定位是硬件停止接收还是HAL库软件锁死,比单纯看RxXferCount更直观。
Clyde011 发表于 2026-6-19 08:38 | 显示全部楼层
分段接收别用固定32字节分片,改用单字节循环接收+环形缓冲区,不用一次性读一大段。规避多次调用Receive_IT冲突,实测能解决49字节就卡死的限制。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

216

主题

216

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部