HAL_UART_Transmit_DMA()第一次调用完美运行,第二次直接返回HAL_BUSY。这个坑,几乎每个用STM32 HAL库的人都踩过。
1、真相:DMA传完不等于串口发完
很多人以为DMA把数据搬到TDR寄存器就结束了。错。
HAL库的状态机靠UART的TC中断来判断传输是否真正完成。DMA传完只是第一步,串口把数据实际发到线路上才算完。如果TC中断没被正确处理,gState会一直卡在HAL_UART_STATE_BUSY_TX,第二次调用自然被拒。
2、四个高频杀手
杀手一:中断标志没清
回调函数里不清标志,下一次传输直接被阻塞。必须加:

杀手二:DMA通道没释放
第二次调用前,旧通道还占着。正确做法是先停再启:

杀手三:缓冲区没对齐
动态分配的内存地址可能不满足DMA对齐要求,第二次分配的地址一变,直接硬件异常。用__attribute__((aligned(4)))或memalign()。
杀手四:Cache一致性
开了DCache的芯片,DMA读的是缓存旧数据。传输前后必须调用SCB_CleanDCache_by_Addr()。
本文凡亿教育原创文章,转载请注明来源!

扫码关注






































