别再让 CPU 累死在“搬砖”上!一文彻底搞定 STM32 的 DMA 神技

张开发
2026/4/15 17:06:54 15 分钟阅读

分享文章

别再让 CPU 累死在“搬砖”上!一文彻底搞定 STM32 的 DMA 神技
前言在电赛或实际项目中你一定遇到过这些崩溃瞬间小车跑着跑着串口接收的数据突然丢包了或者为了用 ADC 采集 5 个红外传感器的值在while(1)里不断加上delay_ms()等待转换完成导致 PID 计算严重滞后。为什么会这样因为你的 CPU 正在“搬砖”。今天我们来请一位“快递员”——DMA来彻底解放你的 CPU。一、 什么是 DMA一个通俗的比喻想象一下CPU 是工地的包工头负责核心的算法计算和逻辑判断外设比如串口、ADC是砖窑内存SRAM是仓库。没有 DMA 时轮询或中断砖窑每产出一块砖收到1字节数据包工头就要放下手中的高数图纸停止 PID 计算亲自跑去把砖搬到仓库。如果数据量极大包工头会活活累死根本没时间画图纸。有了 DMA 时DMA 就像是包工头花钱雇来的专属快递团队。包工头只需交代一句“把串口的 100 字节数据搬到那个数组里搬完了叫我。”然后包工头就可以继续去算他的 PID 了。期间的数据搬运完全不需要占用 CPU 任何资源二、 DMA 的两大经典实战场景ADC 多通道高速采集循迹小车/多轴无人机当你需要同时采集多个模拟量比如 5 路红外循迹、电池电压时如果用软件触发不仅代码繁琐还会打断主循环。DMA 绝杀开启 ADC 的连续转换模式并绑定 DMA。ADC 只要一转换完DMA 瞬间将数据自动存入你定义的数组中。你只需要在想用的时候直接去读数组里的变量即可数据永远是最新的UART 不定长数据接收ESP8266 WIFI/激光雷达通讯这是无数新手的噩梦。串口数据发得太快单片机进中断太频繁导致主程序卡死或数据溢出丢包。DMA 绝杀配合串口的**空闲中断IDLE Interrupt**使用。配置 DMA 接收数据当一帧数据发送完毕串口总线空闲时触发一次空闲中断。CPU 只需要在空闲中断里去取走完整的一包数据即可。原本接收 100 个字节需要进 100 次中断现在只需进 1 次三、 玩转 DMA 的三个核心要素配置 DMA 看似复杂其实只要告诉它“三个 W”Where to Where (源地址与目的地址)数据从哪来比如USART1-DR到哪去比如Rx_Buffer数组。What size (数据宽度)每次搬运的是 8 位Byte、16 位Half-Word还是 32 位WordADC 通常是 16 位。Walk how (地址自增模式)串口寄存器地址是不变的所以“源地址不自增”但存入数组时地址需要往后移所以“目的地址自增”。四、 总结在资源极其有限的单片机中榨干每一滴硬件性能是工程师的必修课。学会使用 DMA不仅能让你的代码看起来更加高级、整洁更能让系统的实时性和稳定性产生质的飞跃。今日互动你在使用串口接收长字符串时是否遭遇过由于中断嵌套导致单片机直接死机HardFault的情况你当时是怎么解决的欢迎在评论区分享你的“排雷”经验

更多文章