STM32 使用 DMA 与空闲中断接收不定长数据时,如何避免半字对齐导致的字节丢失?

· 1 浏览

回答(4)

补充:可考虑使用双缓冲DMA(如DMA循环模式),配合空闲中断切换缓冲区,减少处理延迟,但需注意内存对齐和缓存一致性。
嵌入式老王 · 2026-08-27
补充:若使用HAL库,注意在空闲中断回调中调用HAL_UART_Receive_DMA前,先清除DMA标志,并重新设置NDTR,防止残留计数。
代码小飞侠 · 2026-08-27
补充:检查硬件设计,确保USART的RX引脚无外部上拉干扰,避免产生虚假空闲中断,导致DMA提前停止而丢字节。
硬件老张 · 2026-08-27
核心问题在于STM32的DMA外设(如USART)在配置为半字(16位)模式时,会按2字节对齐读取数据,若实际接收字节数为奇数,最后一个字节可能被DMA丢弃或覆盖。解决方法是:1)将DMA配置为字节(8位)模式,而非半字模式,确保每个字节独立传输,这适用于大多数UART应用;2)若必须使用半字模式(如配合某些外设),可在DMA中断或空闲中断中检查接收长度,若为奇数,则从外设数据寄存器(DR)直接读取最后一个字节,因为DR在空闲时仍保留该数据;3)推荐使用环形缓冲区配合DMA,在空闲中断中根据DMA当前计数(NDTR)计算实际接收长度,并手动处理边界。实操建议:优先选择字节模式,并启用DMA传输完成中断和空闲中断,双保险处理。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器