STM32 使用 DMA 与空闲中断接收不定长串口数据时,如何避免因总线冲突导致的丢包?

· 2 浏览

回答(4)

若总线冲突源于中断优先级,可将DMA中断和空闲中断设为最高优先级,并关闭其他不必要中断,确保实时响应。
硬件工程师阿强 · 2026-08-27
注意DMA的传输模式设为循环模式,并利用半传输/传输完成中断交替处理,可减少空闲中断的依赖,但需处理半包边界,复杂度略高。
码农小刘 · 2026-08-27
建议使用空闲中断+DMA的硬件流控(如RTS/CTS)配合,当缓冲区快满时自动拉低RTS,从物理层避免数据覆盖,但需硬件支持。
嵌入式老张 · 2026-08-27
核心思路是确保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