STM32 使用 DMA+双缓冲串口接收不定长帧时,如何避免缓存切换瞬间丢字节?

· 3 浏览

回答(4)

若允许,可改用串口硬件流控(RTS/CTS),在CPU忙时拉高RTS让对端暂停,从物理层杜绝丢字节。
硬件控阿明 · 2026-08-27
开启DMA的FIFO模式(如STM32F4),设置阈值,能吸收切换瞬间的突发数据,但需注意FIFO深度。
码农小飞 · 2026-08-27
用环形队列管理双缓冲,CPU只读队列,DMA只写,配合内存屏障,彻底避免竞争。
嵌入式老周 · 2026-08-27
核心思路是让DMA在双缓冲切换时保持连续接收,避免CPU介入造成的窗口期。具体做法:1)使用DMA的循环模式(Circular Mode)配合双缓冲(Memory-to-Memory或外设到内存),将两个缓冲区地址设为连续内存块(如数组[2][N]),并开启DMA传输完成中断(TC)和半传输中断(HT)。当HT触发时,CPU处理前半缓冲区,此时DMA继续写入后半;当TC触发时,处理后半,DMA写前半。这样切换由硬件自动完成,无丢字节。2)关键:在中断服务函数中,先读取DMA的CNDTR寄存器(剩余计数)确认当前写位置,再处理对应缓冲区,避免覆盖。3)若帧长不定,需结合空闲中断(IDLE)或超时判断帧结束,但不要关闭DMA,仅在空闲时解析数据。实操建议:优先使用STM32的HAL库中的HAL_UARTEx_ReceiveToIDLE_DMA接口,它已集成双缓冲和空闲检测。若用寄存器,确保配置DMA的PSIZE和MSIZE一致(如字节),并设置FIFO(若支持)以缓冲。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

🔗 波特率计算器