如何用DMA+双缓冲彻底消除SPI外设传输中的CPU介入延迟?

· 1 浏览

回答(4)

实际工程中,建议用环形缓冲区配合DMA半传输和全传输中断,这样无需切换缓冲区地址,更灵活。但需注意内存对齐和缓存一致性(如Cortex-M7需维护D-Cache)。
嵌入式小飞侠 · 2026-08-27
如果MCU支持,可考虑使用DMA的突发传输和FIFO,减少总线占用,进一步降低延迟。另外,确保DMA和SPI的时钟同步,避免因时钟域不同导致数据错位。
芯海行者 · 2026-08-27
补充一点:双缓冲的关键是DMA的传输完成中断要极短,只做指针切换和标志置位,数据搬运放在主循环或低优先级任务中,避免中断阻塞影响实时性。
嵌入式老周 · 2026-08-27
要彻底消除SPI传输中的CPU介入延迟,核心是使用DMA的双缓冲(也叫乒乓缓冲)模式,配合中断或事件标志实现无缝数据流。具体做法:1)配置两个缓冲区(Buffer A和Buffer B),将DMA的传输模式设为循环或双缓冲模式(如STM32的DMA_CIRCULAR或双缓冲使能),使DMA在传输完一个缓冲区后自动切换到另一个,同时触发传输完成中断。2)在中断服务函数中,仅更新已完成的缓冲区数据(例如从外设或内存拷贝新数据),不参与SPI数据传输本身,从而CPU只负责数据准备,不干预传输时序。3)确保DMA的优先级高于CPU任务,并合理配置SPI的DMA请求(如TX和RX分别使用独立DMA通道),避免数据覆盖。4)使用硬件流控或环形缓冲区管理数据指针,防止缓冲区切换时数据错位。实操建议:在STM32上,使用HAL库的HAL_SPI_Transmit_DMA配合双缓冲需手动管理缓冲区切换,或直接使用DMA的双缓冲功能(如DMA_InitTypeDef的Mode设为DMA_DOUBLE_BUFFER_MODE),并启用传输完成中断。测试时用逻辑分析仪观察CS和SCK时序,确认无CPU介入的间隙。
mcuku 阿沐 · 2026-08-27