1. DMA 基础概念:什么是 DMA、DMA 与 CPU 的数据搬运对比、DMA 在单片机中的作用
各位同学,咱们今天正式开讲 DMA。说实话,我刚开始做嵌入式那会儿,对 DMA 的理解就是「一个能自己搬数据的东西」。但真正用起来才发现,这里面的门道比想象中多得多。咱们今天就把 DMA 的底裤扒干净,从最基础的概念讲起。
1.1 什么是 DMA?
DMA,全称 Direct Memory Access,直接存储器访问。说白了,就是硬件自带的一个「数据搬运工」。它不需要 CPU 插手,自己就能把数据从 A 点搬到 B 点。
我习惯这么跟新人解释:DMA 就是一个专门干苦力活的硬件模块。CPU 是老板,DMA 是搬砖工。老板只需要告诉搬砖工「把这块砖从仓库搬到工地」,搬砖工自己就干完了,老板可以继续算账、开会、写代码。
核心定义:DMA 是一种允许外设与存储器之间、或存储器与存储器之间直接传输数据的硬件机制,传输过程不需要 CPU 参与。
你想想看,如果没有 DMA,CPU 就得亲自干这个活——从外设读一个字节,存到内存,再读下一个字节,再存……这得多浪费?CPU 可是用来跑算法、做决策的,不是用来当搬运工的。
1.2 DMA 与 CPU 的数据搬运对比
咱们直接上表格,一目了然:
| 对比项 | CPU 搬运 | DMA 搬运 |
|---|---|---|
| 搬运方式 | 逐字节/逐字读取→写入 | 硬件自动批量传输 |
| CPU 占用 | 100% 占用,无法做其他事 | 仅初始化时占用,传输过程释放 |
| 传输速度 | 受限于 CPU 主频和指令周期 | 接近总线极限速度 |
| 适用场景 | 小数据量、实时性要求不高的场合 | 大数据量、高速传输、实时性要求高的场合 |
| 代码复杂度 | 简单,直接读写寄存器 | 需要配置 DMA 控制器,稍复杂 |
| 功耗 | CPU 全速运行,功耗高 | CPU 可进入低功耗模式,整体功耗低 |
我记得有一次做项目,用 STM32F4 采集 ADC 数据,每秒要采 100k 个点。一开始我用 CPU 轮询读取,结果 CPU 占用率直接飙到 85%,系统其他任务全卡死了。后来换成 DMA,CPU 占用率降到 5% 以下,还能顺便跑个 FFT 算法。这就是差距。
我的经验:判断要不要用 DMA,就看两个指标——数据量是否大于 100 字节,或者传输频率是否高于 1kHz。只要满足一个,就优先考虑 DMA。
1.3 DMA 在单片机中的作用
DMA 在单片机里到底能干啥?我总结了四个核心作用:
- 解放 CPU——让 CPU 从繁琐的数据搬运中解脱出来,专心做计算和控制。
- 提高传输速度——DMA 的传输速度接近总线带宽,比 CPU 逐字节搬运快得多。
- 降低系统功耗——DMA 传输时 CPU 可以休眠或降频,特别适合电池供电设备。
- 实现后台传输——DMA 可以在后台持续搬运数据,CPU 同时处理其他任务,实现真正的并行。
具体到实际应用,我列几个常见场景:
- ADC 数据采集:连续采集多通道模拟信号,DMA 自动将结果存入内存缓冲区。
- DAC 波形输出:DMA 从内存读取波形数据表,自动送给 DAC 生成模拟信号。
- SPI/I2C 通信:DMA 自动收发数据包,CPU 只在完成时处理一次中断。
- UART 串口收发:DMA 处理大数据量的串口通信,比如蓝牙模块的数据透传。
- 存储器拷贝:内存到内存的 DMA 传输,用于快速复制大数组或缓冲区。
- 显示刷新:LCD/OLED 的显存刷新,DMA 自动将图像数据送到显示接口。
避坑指南:我曾经在一个项目中,用 DMA 做 SPI 通信,结果发现数据总是错位。查了两天才找到原因——DMA 的传输宽度和外设的数据宽度不匹配。SPI 是 8 位,DMA 配置成了 16 位,结果高低字节全乱了。所以配置 DMA 时,传输宽度一定要和外设寄存器宽度一致。
1.4 DMA 的工作流程
咱们用一张图来理解 DMA 的完整工作流程:
流程其实很简单:CPU 先配置好 DMA 的源地址、目标地址、传输长度、触发源等参数,然后 DMA 就等着。外设一发出请求,DMA 立刻开始搬数据。搬完了,触发一个中断告诉 CPU「活干完了」。CPU 这时候再去处理缓冲区里的数据。
记住这个原则:DMA 负责「搬」,CPU 负责「算」。各司其职,互不干扰。
1.5 DMA 的三种传输模式
不同单片机的 DMA 模式略有差异,但主流的有三种:
| 传输模式 | 描述 | 典型应用 |
|---|---|---|
| 外设→内存 | 从外设数据寄存器读取数据,存入内存缓冲区 | ADC 采集、UART 接收、SPI 接收 |
| 内存→外设 | 从内存读取数据,写入外设数据寄存器 | DAC 输出、UART 发送、SPI 发送 |
| 内存→内存 | 从一个内存地址拷贝数据到另一个内存地址 | 数据缓冲区拷贝、图像数据搬运 |
嗯,这里要注意:内存到内存的传输,有些低端单片机不支持。比如早期的 STM32F1 系列,DMA 只能在外设和内存之间传,不能内存到内存。选型的时候一定要看数据手册。
1.6 本章小结
咱们今天把 DMA 的基础概念捋了一遍。说白了,DMA 就是一个硬件级的 DMA 控制器,专门负责数据搬运,让 CPU 腾出手来做更重要的事。它的核心价值就三个字:快、省、稳——速度快、省 CPU、传输稳定。