核心思路是让DMA始终有缓冲可写,避免在切换瞬间因缓冲满而丢弃数据。推荐使用DMA双缓冲模式(DBM)配合空闲中断(IDLE)或超时判断。具体实操:1)配置DMA为循环模式+双缓冲,使能传输完成中断(TC)和半传输中断(HT),在HT/TC中切换用户处理缓冲,但注意DMA硬件自动切换,软件仅需记录当前有效缓冲。2)关键点:在IDLE中断中,先读取DMA的CNDTR寄存器获取剩余字节数,再计算已接收长度,并立即暂停DMA(DMA_Cmd(DMAx, DISABLE)),处理完数据后重新使能,并确保切换时先清空DMA标志位(如DMA_IT_FLAG_TC/HT)。3)避免丢字节的实操技巧:将DMA缓冲设为2的幂次大小(如256字节),并启用FIFO(若支持),可缓冲硬件层面的突发数据;同时,在IDLE中断中,若CNDTR显示缓冲已满但未触发TC,需手动处理剩余数据。4)若使用HAL库,注意在HAL_UARTEx_ReceiveToIdle_DMA中,回调函数里调用HAL_UARTEx_ReceiveToIdle_DMA重新启动接收,但需先调用HAL_UART_DMAStop暂停,防止竞态。最后,测试时用逻辑分析仪或串口助手发送连续数据流,验证切换瞬间无丢包。
mcuku 阿沐 · 2026-08-27