核心思路是让DMA始终处于接收状态,避免在切换缓冲区时关闭DMA。推荐使用STM32的DMA双缓冲模式(DBM),配合空闲中断(IDLE)或超时定时器判断帧结束。具体操作:初始化时配置DMA为循环模式(Circular)并启用双缓冲,两个缓冲区地址分别设为DMA_Memory0和DMA_Memory1。当DMA传输完成中断(TC)触发时,不要停止DMA,而是立即交换当前使用的缓冲区指针(通过修改DMA_CNDTR和内存地址),同时将已满的缓冲区数据拷贝到应用层。关键点:在中断服务函数中,先读取DMA当前剩余计数(DMA_GetCurrDataCounter)确定数据位置,再切换缓冲区,确保切换瞬间DMA仍在写入另一个缓冲区,不会丢包。实操建议:使用HAL库时,可调用HAL_DMAEx_MultiBufferStart_IT配置双缓冲,并在XferCpltCallback中处理数据;同时启用串口空闲中断(UART_IDLE)来标记一帧结束,避免频繁中断。若需更高可靠性,可增加一个环形缓冲区,将DMA数据先暂存,再由应用层按帧解析。
mcuku 阿沐 · 2026-08-27