stm32-usart-uart-dma-rx-tx 是一个示例 / 工具集合,演示了如何把 STM32 的 UART(USART/LPUART)和 DMA 结合起来,高效做接收(RX)和发送(TX)。重点是:在你不知道要接多少字节的情况下,还能用 DMA 长期稳定地接收数据并通知上层处理。
它能解决什么痛点
-
• CPU 被串口中断/轮询反复打断,系统性能下降 → 用 DMA 把数据搬到内存,CPU 去做别的事。
-
• 接收长度未知,传统 DMA 要提前写好长度导致不行 → 用循环模式 + IDLE/RTO + HT/TC 组合来识别“包”边界。
-
• 串口速率高(>1Mbps)或者有大数据爆发时,普通中断/轮询容易丢数据 → DMA 高速搬移,减小丢包风险。
-
• 发送大块数据会卡住 CPU → 用 DMA TX(normal 模式),发送过程中 CPU 不阻塞。
核心思想
-
• RX:把 DMA 配成 circular(环形)模式,让它不停往一个固定大小的 buffer 写;再通过三个事件来知道什么时候处理数据:
-
• HT(半传中断)、TC(传完中断)是 DMA 的;
-
• IDLE(空闲线)或 RTO(接收超时)是 UART 的。
三者结合,可以在不知长度的情况下,及时安全地把已收到的数据交给应用处理,避免覆盖未处理数据。 -
• TX:把要发的内存地址和长度写进 DMA,normal 模式,DMA 传完发一个 TC,CPU 就知道可以继续发下一块了。很像把搬运工交给硬件。
安装 / 克隆 / 运行(一步到位)
-
• 克隆仓库(包含子模块):
-
• git clone –recurse-submodules https://github.com/MaJerle/stm32-usart-dma-rx-tx
-
• 用 STM32CubeIDE 打开 projects 目录下的对应例程(仓库里覆盖了多个 STM32 家族示例)。
-
• 例程基于 LL(Low-Level)驱动,配置:115200/8N1、DMA RX 为 circular 开启 HT/TC、DMA TX 为 normal。
-
• 按照 README 里说明选对板子和 DMA 通道、修改 pin 配置后直接编译烧写。
优点 / 好处
|
特性 |
好处 |
|
DMA RX(circular) |
极低 CPU 占用,能连续接收高速数据 |
|
DMA TX(normal) |
发送时不阻塞主线程,适合大数据量/日志输出 |
|
IDLE + HT/TC 组合 |
在长度未知时也能可靠切割包并及时处理 |
|
LL 驱动示例 |
易于理解底层机制,便于移植与修改 |
|
支持多家族 |
F1/F4/G0/G4/L4/H7/U5 等示例,适配广泛硬件 |
缺点 / 限制
-
• 需要你理解 NVIC 优先级,错误设置会导致数据乱读。
-
• IDLE/RTO 并非所有 STM32 都有(有些芯片不能用 IDLE,需要轮询)。
-
• 如果处理函数写在中断里,太慢会影响系统实时性 —— 推荐把中断只做通知。
-
• buffer 大小、baud、处理速度三者需要平衡,设计不当会丢包。
总结
如果你想在 STM32 上做稳定且高性能的串口收发,把 UART 和 DMA 配合起来是必经之路;关键在于用 circular buffer + HT/TC + IDLE/RTO 的“组合拳”,并做好中断优先级和数据处理策略。MaJerle 的仓库给了完整且可跑的参考例程,直接拿来改就是生产力。
项目地址:https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx