1. DMA基础概念:什么是DMA、DMA与CPU数据搬运的区别、DMA在嵌入式系统中的作用

各位同学,咱们今天聊聊DMA。说实话,我刚入行那会儿,觉得DMA就是个“数据搬运工”,没啥了不起的。直到有一次做高速数据采集项目,CPU被中断占得死死的,系统几乎卡死——我才真正意识到,不懂DMA,嵌入式开发就少了一条腿。

1.1 什么是DMA

DMA,全称Direct Memory Access,直接存储器访问。说白了,就是硬件自己搬数据,不用CPU插手。

我习惯这么理解:DMA是一个专门干“数据拷贝”的硬件模块。它有自己的地址总线和控制逻辑,能在内存和外设之间、内存和内存之间,自动完成数据传输。

核心定义:DMA是一种允许外设或内存直接交换数据,而不需要CPU逐字节参与的硬件机制。

举个例子,ADC采样了1024个点,传统做法是CPU每次读一个数,存到数组里。有了DMA,你只需要告诉它:“从ADC数据寄存器搬1024个数到内存地址0x20001000”,然后它自己干完,最后给你发个中断说“搞定了”。

1.2 DMA与CPU数据搬运的区别

这个对比很关键。我见过不少工程师,觉得DMA可有可无,反正CPU也能搬。嗯,咱们看看区别:

对比项 CPU搬运 DMA搬运
执行方式 逐条指令执行,每次搬一个字节/字 硬件自动完成,一次可搬整个数据块
CPU占用 全程占用CPU,无法做其他事 仅初始化时占用,传输过程CPU可干别的
传输速度 受限于指令执行速度,通常较慢 接近总线带宽,速度远快于CPU
适用场景 小数据量、非实时、简单控制 大数据量、高速、实时性要求高
功耗 CPU全速运行,功耗较高 DMA模块功耗远低于CPU
编程复杂度 简单,直接读写寄存器 需要配置DMA控制器,稍复杂

你想想看,CPU搬数据就像你亲自去仓库搬箱子,搬一箱就少一箱的精力。DMA呢,就像雇了个搬运工,你只需要告诉他“搬到哪儿”,然后自己可以去写代码、做算法、处理逻辑。

我的经验:在STM32F4上做过测试,CPU用循环搬1024个16位数据大约需要50μs,而DMA只需要不到5μs。10倍的差距,在高频采样场景下就是能不能跑得动的区别。

1.3 DMA在嵌入式系统中的作用

DMA的作用,我总结为三个核心价值:

  • 解放CPU:让CPU从繁琐的数据搬运中解脱出来,专注于控制、计算和协议处理
  • 提升吞吐量:数据搬运速度接近总线极限,适合高速外设(ADC、DAC、摄像头、以太网)
  • 降低延迟:DMA传输的启动延迟远小于中断响应延迟,适合实时性要求高的场景

我曾经做一个多通道音频采集项目,8路麦克风同时采样,每路48kHz、16位数据。如果用中断方式,CPU几乎100%在响应中断,连滤波算法都跑不动。换成DMA后,CPU占用率降到15%左右,还能同时做FFT和音频编码。

避坑指南:DMA不是万能的。小数据量(比如几个字节)用DMA反而更慢,因为配置DMA通道的开销比CPU直接搬还大。我一般以64字节为分界线,小于这个数就让CPU搬。

下面这张图,是我画的一个DMA工作流程,帮你直观理解:

DMA传输工作流程 CPU DMA控制器 内存 外设 ① 配置DMA ② 启动传输 ③ 数据流 ④ 写入内存 ⑤ 传输完成中断 关键流程说明: CPU只需配置DMA的源地址、目标地址、数据长度和传输方向,然后启动DMA。后续传输完全由DMA硬件自动完成,CPU可并行处理其他任务。

1.4 DMA的典型应用场景

在实际项目中,DMA最常见的几个用武之地:

  • ADC连续采样:配置DMA自动将ADC转换结果搬入缓冲区,CPU定期处理
  • DAC波形输出:DMA从波形表搬数据到DAC,实现无CPU干预的连续波形输出
  • SPI/I2C通信:大数据包收发时,DMA自动处理,CPU只负责协议解析
  • 内存拷贝:比如从摄像头缓冲区搬到显示缓冲区,DMA比memcpy快得多
  • 定时器触发传输:结合定时器,实现精确周期的数据传输

一句话总结:DMA就是嵌入式系统的“硬件搬运工”,让CPU从苦力活中解放出来,去做更有价值的事。