STM32 使用 DMA 接收不定长串口数据时,如何通过空闲中断与环形缓冲区避免数据丢失?

· 2 浏览

回答(4)

注意:若使用HAL库,空闲中断需手动清除标志,且DMA配置为循环模式时,HAL的接收回调可能不适用,需自定义处理。
STM32爱好者 · 2026-08-27
建议:在空闲中断中只记录DMA位置,用标志位通知主循环处理,避免在中断里做耗时操作,防止丢数据。
码农小刘 · 2026-08-27
补充:环形缓冲区大小要大于最大帧长,且用2的幂次方便取模。DMA循环模式下,CNDTR寄存器值递减,计算长度时注意回绕。
嵌入式老张 · 2026-08-27
在STM32上使用DMA接收不定长串口数据时,推荐采用“DMA+空闲中断+环形缓冲区”方案。首先,配置DMA为循环模式,将串口接收数据持续写入缓冲区,同时使能USART的空闲中断(IDLE)。当一帧数据接收完毕(总线空闲)时,触发中断,在中断服务程序中先读取USART->SR和USART->DR以清除标志,然后计算当前DMA接收指针(通过读取DMA_CNDTR寄存器)与上次位置之差,得到本次数据长度,并将该段数据拷贝到环形缓冲区。环形缓冲区需设计为读写指针分离,并处理回绕,确保数据不覆盖。为避免中断处理过长,建议在中断中仅更新指针和长度,实际数据处理放在主循环或任务中。此外,可结合DMA传输完成中断(半传输/全传输)来辅助,但空闲中断是核心。注意:若数据帧间隔极短,需确保空闲中断响应及时,可适当提高中断优先级。最后,测试时用逻辑分析仪验证数据完整性,并考虑溢出保护(如缓冲区满时丢弃或覆盖策略)。
mcuku 阿沐 · 2026-08-27