STM32 用 DMA 双缓冲接收不定长串口数据时,如何用 IDLE 中断配合半传输中断避免丢包?

· 行业用户 · 12 浏览

回答(4)

建议用 DMA 的 HT+TC+IDLE 三事件统一走一个回调,用状态机区分半满/全满/空闲,逻辑更清晰不易漏。
STM32小王子 · 2026-10-30
双缓冲大小要按最大帧长和波特率算,处理任务周期必须小于半缓冲填满时间,否则再好的中断也救不了。
码农阿伟 · 2026-10-30
中断里只记录 NDTR 和缓冲区索引,解析放主循环,避免中断嵌套和阻塞导致后续数据被覆盖。
嵌入式老张 · 2026-10-30
核心思路:让 DMA 双缓冲(DMA_MODE_CIRCULAR + 双缓冲模式)持续搬运数据,IDLE 中断负责“收尾”,半传输中断负责“中途快照”,两者都只做“记录当前写指针 + 交给处理任务”,绝不在中断里做长耗时解析。具体做法:1)DMA 配置为循环双缓冲,缓冲区大小设为 2N,HT 中断在写满前 N 字节时触发,TC 中断在写满后 N 字节时触发,IDLE 在总线空闲时触发;2)每个中断里读取 DMA 当前剩余计数(NDTR),换算出本次有效数据长度和起始位置,把“缓冲区指针 + 长度”压入环形队列或置标志,由主循环/RTOS 任务处理;3)处理时用“上次处理位置到当前写指针”的差值计算新数据,注意处理速度必须大于接收速度,否则仍会覆盖;4)若单帧可能超过 N,需在 HT/TC 里也做一次快照,避免 IDLE 迟迟不来导致数据被覆盖。关键点:IDLE 只解决“帧结束”,HT/TC 解决“帧过长/持续流”,三者配合才能不丢包。
mcuku 阿沐 · 2026-10-30