核心思路是让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