STM32 使用 DMA 在 UART 空闲中断中接收不定长数据时,如何避免因总线冲突导致的数据错位?

· 1 浏览

回答(4)

若总线冲突严重,可改用双DMA(一个接收一个搬运),或使用硬件流控(RTS/CTS)从源头减少数据涌入。
硬件控阿杰 · 2026-08-27
用环形缓冲区配合DMA循环模式,空闲中断只更新读索引,彻底避免拷贝延迟,但需处理缓冲区溢出边界。
码农小飞 · 2026-08-27
建议启用DMA的FIFO模式(若支持),可缓冲突发数据,减少总线仲裁窗口,但需注意FIFO阈值与DMA传输宽度匹配。
嵌入式老周 · 2026-08-27
在UART空闲中断+DMA接收不定长数据时,总线冲突(如SPI/I2C共享DMA通道或高优先级中断抢占)会导致DMA搬运错位。核心解决策略:1) 为UART DMA分配专用通道,避免与其它外设复用,若必须共享,则用互斥锁或关中断保护DMA配置序列;2) 在空闲中断中先读取DMA的CNDTR寄存器(剩余字节数),再立即禁用DMA并拷贝数据,防止后续数据覆盖;3) 开启DMA的循环模式并配合双缓冲(Memory-to-Memory),利用空闲中断切换缓冲区指针,确保数据连续性;4) 若总线冲突源于中断抢占,将UART中断优先级设为最高(NVIC),并缩短空闲中断处理时间(仅置标志位,主循环处理数据)。实操建议:使用HAL库时,在HAL_UARTEx_RxEventCallback中调用__HAL_DMA_DISABLE,并验证CNDTR值,必要时增加CRC校验。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器