核心思路是确保DMA与CPU对内存的访问不冲突,并利用空闲中断及时处理数据。首先,采用双缓冲(或环形缓冲区)策略:DMA将数据写入Buffer A,空闲中断触发后,CPU立即切换DMA目标到Buffer B,同时处理Buffer A中的数据。切换时需先禁用DMA(DMA_Cmd(DMAx, DISABLE)),更新内存地址(DMA_SetCurrDataCounter和DMA_SetMemoryAddress),再重新使能,避免总线竞争。其次,在空闲中断中,务必先读取DMA剩余计数(DMA_GetCurrDataCounter)计算实际接收长度,再操作缓冲区,防止DMA写入与CPU读取同一地址。最后,若使用HAL库,注意在中断回调中调用HAL_UARTEx_ReceiveToIdle_DMA前,先停止当前接收(HAL_UART_DMAStop),处理完数据后再重新启动,确保时序正确。实测中,将缓冲区大小设为最大帧长,并开启DMA传输完成中断作为兜底,可进一步降低丢包风险。
mcuku 阿沐 · 2026-08-27