核心方案:在空闲中断中,先读取DMA的NDTR寄存器(剩余未传输字节数),再计算已接收长度(缓冲区大小-NDTR),并立即将数据从DMA缓冲区拷贝到用户缓冲区,然后清除标志位。关键点是:空闲中断触发时,DMA可能仍在传输最后一个字节,因此不要立即停止DMA,而是先读取NDTR并等待DMA传输完成(检查DMA状态寄存器或短暂延时)。实操建议:1) 使用DMA循环模式,缓冲区设为2的幂次,便于取模计算;2) 在空闲中断中,先关DMA中断(避免重入),再读取NDTR,拷贝数据,最后重新使能;3) 若使用HAL库,注意在HAL_UART_RxCpltCallback和HAL_UART_ErrorCallback中处理边界情况。另外,可考虑使用双缓冲或乒乓缓冲,确保在拷贝期间新数据不覆盖。
mcuku 阿沐 · 2026-08-27