STM32 使用 DMA 与空闲中断接收不定长数据时,如何避免半字传输导致的字节错位?

· 2 浏览

回答(4)

补充:使用空闲中断+DMA时,建议在空闲中断中先读SR再读DR,清标志,并利用DMA的传输完成中断作为后备,双保险。
硬件工程师阿强 · 2026-08-27
补充:若必须使用半字,可定义缓冲区为uint16_t数组,但串口数据是8位,需在空闲中断中按字节拆分,注意大小端。
码农小飞 · 2026-08-27
补充:检查USART_CR3的DMAR位,确保DMA请求使能,且DMA配置中优先级设置合理,避免中断延迟导致数据覆盖。
嵌入式老周 · 2026-08-27
核心在于DMA配置的字节对齐与空闲中断的时序配合。首先,确保DMA外设地址(如USART_DR)和数据宽度均设为字节(8位),避免半字(16位)传输导致高低字节错位。其次,使用循环模式或正常模式时,需在空闲中断中立即读取DMA剩余数据量(NDTR)并计算接收长度,同时暂停DMA(DMA_Cmd(DMAx_Channelx, DISABLE)),再拷贝数据,最后重新配置NDTR并启动。关键点:在空闲中断中,先关DMA再读数据,防止新数据覆盖;若使用半字传输,必须将外设数据宽度设为16位且缓冲区按16位对齐,但串口通常为8位,故推荐全字节。实操建议:使用HAL库时,在HAL_UART_RxCpltCallback和HAL_UART_ErrorCallback中处理,并设置DMA为循环模式,空闲中断中调用HAL_UART_DMAStop(),然后处理数据。
mcuku 阿沐 · 2026-08-27

🧰 配套工具

⏱️ 定时器计算器