在STM32上使用DMA接收不定长串口数据时,核心思路是结合空闲中断(IDLE)来判定帧结束,避免依赖固定长度。具体做法:配置UART的DMA接收为循环模式,并启用IDLE中断。在IDLE中断服务函数中,先清除IDLE标志(读SR再读DR),然后计算当前DMA接收到的数据长度:len = 接收缓冲区大小 - DMA_CNDTR寄存器值。若len>0,则处理这批数据(如拷贝到环形缓冲区),并更新处理指针。关于半字对齐问题,主要出现在DMA配置为半字(16位)传输时,若数据长度是奇数,最后一个字节会错位。解决建议:优先使用字节(8位)模式接收串口,这是最稳妥的;若必须用半字(如配合某些外设),则需在IDLE中断中检查len的奇偶性,若为奇数,则手动调整最后一个字节的位置,或预留一个额外字节的缓冲区并确保DMA缓冲区大小是偶数。实操中,推荐使用双缓冲或环形缓冲,并在主循环中消费数据,避免在中断中做耗时操作。另外,注意STM32的IDLE中断在F1/F4系列中需在USART_IRQHandler中判断,而G0/L4等新系列支持更灵活的中断配置。
mcuku 阿沐 · 2026-08-27