1. DMA 基础概念:为什么你的 CPU 不该干搬运的活

各位同学好,我是你们的嵌入式系统讲师。今天咱们开始《STM32F407 DMA 传输性能调优与调试实战》的第一章。

先问大家一个问题:你写单片机程序时,有没有遇到过这种情况——明明 CPU 主频不低,但一跑大数据量传输,系统就卡顿、响应变慢?

嗯,我刚开始做嵌入式开发那会儿也踩过这个坑。后来才发现,问题出在 CPU 干了太多「搬运工」的活。而 DMA,就是专门来解决这个问题的。

1.1 什么是 DMA?

DMA,全称 Direct Memory Access,直接存储器访问。说白了,就是硬件层面专门负责数据搬运的一个独立模块。

你可以把它想象成一个「专职快递员」:CPU 告诉它「把 A 地址的数据搬到 B 地址,搬完通知我」,然后 DMA 就自己干活去了,CPU 可以继续处理其他任务。

核心要点:DMA 是一种允许外设与存储器之间、或存储器与存储器之间直接传输数据的技术,传输过程不需要 CPU 参与。

在 STM32F407 上,DMA 控制器有 2 个(DMA1 和 DMA2),每个控制器有 8 个数据流(Stream),每个数据流支持最多 8 个通道(Channel)请求。这个资源量,说实话,在 Cortex-M4 系列里算很充裕了。

1.2 DMA 与 CPU 的关系:分工协作

很多人刚接触 DMA 时,会误以为 DMA 能「替代」CPU。其实不是这样。

CPU 是大脑,负责决策、运算、控制流程。DMA 是手脚,负责重复性的数据搬运。两者是协作关系,不是替代关系。

我画了一张图,帮大家理清这个关系:

DMA 与 CPU 协作关系图 CPU Cortex-M4 @168MHz DMA 控制器 DMA1 / DMA2 存储器 SRAM / Flash 外设 USART / SPI / ADC / TIM AHB 总线矩阵 多主多从架构 配置/启动 数据传输 数据传输 说明: CPU 配置 DMA 后即可处理其他任务;DMA 通过 AHB 总线矩阵直接访问存储器或外设;传输完成后通过中断通知 CPU。

从这张图可以看出:

  • CPU 负责配置 DMA、处理中断、执行应用程序逻辑
  • DMA 控制器 负责在存储器与外设之间、或存储器与存储器之间搬运数据
  • AHB 总线矩阵 提供多主多从的互联架构,让 DMA 和 CPU 可以并行访问不同的从设备

个人经验:我在做一款数据采集设备时,ADC 采样率 1Msps,每次采样 12 位,如果不使用 DMA,CPU 每 1us 就要响应一次中断去读数据。用了 DMA 后,CPU 占用率从 85% 降到了 12%。这个差距,你品,你细品。

1.3 DMA 传输的优势

DMA 的优势,说白了就三个字:省 CPU。但具体省在哪?我列个表给大家看:

对比维度 CPU 直接传输 DMA 传输
CPU 占用率 100%(传输期间无法做其他事) 仅配置和中断处理时占用(通常 <5%)
传输速度 受限于 CPU 指令执行速度 硬件级传输,可达 AHB 总线峰值带宽
实时性 受中断优先级和任务调度影响 独立硬件,响应延迟可预测
功耗 CPU 持续运行,功耗较高 CPU 可进入低功耗模式,DMA 独立工作
代码复杂度 简单直观,逐字节处理 需要配置 DMA 描述符,稍复杂
适用场景 小数据量、非实时、简单应用 大数据量、高实时、低功耗应用

这个表格很直观。但我想强调一点:DMA 不是万能的。对于几十个字节的小数据传输,配置 DMA 的开销可能比 CPU 直接搬还大。我见过有人为了传 4 个字节专门配了个 DMA——嗯,这属于杀鸡用牛刀。

1.4 DMA 的适用场景

根据我多年的项目经验,以下场景特别适合使用 DMA:

  1. 高速数据采集:ADC 连续采样、多通道同步采集
  2. 通信外设数据收发:USART、SPI、I2C 的大数据包传输
  3. 存储器间数据搬移:从 Flash 拷贝数据到 SRAM,或 SRAM 内部数据搬移
  4. 显示刷新:LCD 显存更新、图形缓冲区传输
  5. 音频处理:I2S 音频数据流传输
  6. 定时触发传输:配合定时器实现周期性数据搬移

避坑指南:我曾经在一个项目中,用 DMA 做 SPI 从机接收。结果发现 DMA 传输完成中断和 SPI 接收完成中断同时触发,导致中断嵌套混乱。后来我调整了中断优先级,并使用了 DMA 的 FIFO 模式才解决。这个坑,大家后面做实战时会遇到,我先提个醒。

1.5 STM32F407 DMA 资源概览

最后,给大家看看 F407 的 DMA 资源,心里有个数:

DMA 控制器 数据流数 通道数/数据流 FIFO 大小 支持的外设
DMA1 8 8 4 字 ADC、TIM、SPI、USART、I2C
DMA2 8 8 4 字 SPI、USART、I2S、SDIO、DCMI、CRYP