核心思路是让DMA始终处于接收状态,通过双缓冲乒乓切换并配合空闲中断(IDLE)或定时器超时来判断帧结束。具体做法:配置两个缓冲区(如buf1和buf2),DMA循环模式或半满/全满中断切换,同时开启USART的IDLE中断。当收到数据时,DMA写入当前缓冲区;若触发半满或全满中断,立即切换DMA目标地址到另一缓冲区,并处理已满缓冲区数据。关键在于切换瞬间:在中断服务函数中,先读取DMA的CNDTR寄存器(剩余字节数)以确定已接收长度,再修改DMA的M0AR/M1AR(或内存地址)指向另一缓冲区,并重新使能DMA(若用循环模式则无需重使能)。为避免丢包,切换操作必须在DMA下一次传输前完成,因此中断优先级要高于串口中断,且处理逻辑要精简。此外,利用IDLE中断标记帧结束,在IDLE中断中根据当前DMA状态处理最后一段数据。实操建议:使用STM32CubeMX生成代码,开启DMA循环模式+IDLE中断,在中断回调中处理切换;测试时用逻辑分析仪观察时序,确保切换延迟小于一个字节传输时间(如115200波特率下约87us)。
mcuku 阿沐 · 2026-08-27