【嵌入式】面向 STM32 的 ADC 与 DMA 学习路线

1.

  • ADC:把外部的模拟电压,转换成 MCU 能处理的数字值。

  • DMA:不用 CPU 一次次手动搬数据,而是让硬件自动把数据从一个地方搬到另一个地方。

  • ADC + DMA:是嵌入式里非常经典的一组搭配。常见用法是:

    • ADC 负责采样
    • DMA 负责自动把采样结果搬到内存数组
    • CPU 再去处理这一批数据

2. ADC 是什么

2.1 全称

ADC = Analog to Digital Converter,模数转换器。

2.2 解决什么问题

MCU 内部只能真正处理数字量 ,但现实世界里很多信号是模拟量,比如:

  • 电位器电压
  • 传感器输出电压
  • 电池电压
  • 麦克风信号

ADC 的作用就是把这些连续变化的电压,变成一个离散的数字值。

2.3 直观理解

假设 ADC 参考电压是 3.3V,分辨率是 12 位:

  • 0V → 0
  • 1.65V → 大约 2048
  • 3.3V → 4095

也就是说,ADC 就像一个"电压翻译器":

  • 输入:模拟电压
  • 输出:数字值

2.4 要重点理解的 ADC 基本概念

(1)分辨率

比如 STM32F1 常见是 12 位 ADC。

12 位表示:

  • 一共可以表示 2^12 = 4096 个等级
  • 数字范围通常是 0 ~ 4095
(2)参考电压

ADC 是拿输入电压和参考电压范围做比较。

最常见可先理解成:

  • 输入范围:0 ~ 3.3V
  • 输出范围:0 ~ 4095
(3)采样时间

ADC 不是"碰一下马上出结果",需要一定采样时间。

采样时间过短,输入信号来不及稳定,结果可能不准。

(4)通道

ADC 可以采多个输入脚,每个输入脚一般对应一个 ADC 通道。

例如:

  • PA0 可能对应 ADC1_IN0
  • PA1 可能对应 ADC1_IN1
(5)单次转换 / 连续转换
  • 单次转换:采一次就停
  • 连续转换:一直采样不停
(6)规则通道组 / 扫描模式

如果要采多个通道,比如同时采 PA0、PA1、PA2,就会涉及扫描模式。


3. DMA 是什么

3.1 全称

DMA = Direct Memory Access,直接存储器访问。

3.2 解决什么问题

没有 DMA 时,数据搬运通常这样做:

  1. 外设准备好一份数据
  2. CPU 去读出来
  3. CPU 再写到内存

这样 CPU 会一直忙于"搬箱子"。

DMA 的作用就是:

让硬件帮你搬数据,CPU 可以少参与。

3.3 直观理解

可以把它想成仓库搬运工:

  • ADC 负责"生产数据"
  • DMA 负责"搬数据到数组里"
  • CPU 负责"看结果、做计算"

3.4 DMA 最常见的几个理解点

(1)源地址

数据从哪里来,比如:

  • ADC 数据寄存器
  • 串口接收寄存器
(2)目的地址

数据搬到哪里去,比如:

  • RAM 中的数组
(3)传输长度

一共搬多少个数据。

(4)是否循环模式
  • 普通模式:搬完这一次就停
  • 循环模式:搬完又从头开始,适合持续采样
(5)为什么它很重要

因为很多外设都在不断产生数据,比如:

  • ADC 连续采样
  • UART 接收数据
  • SPI 收发

如果每次都靠 CPU 读写,CPU 负担会很重。

DMA 可以明显减轻负担。


4. ADC 和 DMA 放在一起怎么理解

4.1 没有 DMA 的 ADC

流程通常是:

  1. 启动 ADC
  2. 等待转换完成
  3. CPU 读 ADC 结果寄存器
  4. 再启动下一次

这种方式适合:

  • 入门学习
  • 低频采样
  • 只采一个值

4.2 有 DMA 的 ADC

流程通常是:

  1. 配 ADC
  2. 配 DMA
  3. 启动 ADC + DMA
  4. ADC 每转完一次,DMA 自动把结果搬进数组
  5. CPU 只在合适时机处理数组里的数据

这种方式适合:

  • 连续采样
  • 多通道采样
  • 批量处理数据
  • 降低 CPU 负担

5. 为什么嵌入式开发里要学 ADC 和 DMA

非常常用。

ADC 常见应用

  • 采电位器,控制亮度/速度
  • 采电池电压
  • 采温度传感器
  • 采压力/光敏/霍尔等模拟量传感器
  • 音频前端采样(入门层面先概念理解)

DMA 常见应用

  • ADC 自动采样搬运

  • UART 接收缓存

  • SPI/I2C 大块数据搬运

  • DAC 波形输出

  • 高速采样系统

  • STM32 入门阶段来说,ADC + DMA 是非常值得做成 demo 的学习主题


6. 应该怎么学

不要一上来就"ADC+DMA+多通道+中断+滤波"全堆一起。

应该分层学。

第一层:先学 ADC 本身

目标:先搞清"采样"到底是怎么回事。

要学会的内容

  1. 什么是模拟量、数字量
  2. ADC 分辨率、参考电压、换算公式
  3. 单通道采样
  4. 轮询方式读取 ADC 值
  5. 把 ADC 原始值打印出来观察
  6. 把 ADC 值换算成电压

最适合第一个 demo

Demo 1:单通道 ADC 采样 + 串口打印数值

比如:

  • 用一个电位器接到 ADC 输入脚
  • 旋转电位器
  • 串口打印 ADC 原始值和电压值

会直接看到:

  • 电压变
  • ADC 数值跟着变

这个 demo 很适合建立直觉。


第二层:学 ADC 的结果怎么用起来

目标:让 ADC 不只是"打印值",而是驱动功能。

最适合你的第二个 demo

Demo 2:ADC 采样控制 LED 亮度(PWM 占空比)

逻辑:

  • ADC 采电位器
  • 把 ADC 值映射成 PWM 比较值
  • LED 亮度随旋钮变化

这个 demo 能把:

  • GPIO
  • 定时器 PWM
  • ADC

串起来。


第三层:再学 DMA

目标:理解"自动搬运数据"这件事。

要学会的内容

  1. 为什么需要 DMA
  2. DMA 的源地址、目的地址、长度
  3. 正常模式和循环模式
  4. ADC 为什么常和 DMA 搭配
  5. DMA 传输完成中断的基本概念

第三个 demo

Demo 3:ADC + DMA,连续采样到数组

逻辑:

  • ADC 连续采样
  • DMA 自动把结果放到 adc_buf[]
  • 主循环定期读取 adc_buf[0]
  • 串口打印这个值

这个 demo 的重点不是花哨,而是确认:

我没有手动每次去读 ADC 数据寄存器,但数组里的值在自动更新。

这就是 DMA 的价值。


第四层:多通道 ADC + DMA

目标:理解"扫描采样"和"数组对应关系"。

适合的第四个 demo

Demo 4:两个 ADC 通道 + DMA 扫描采样

比如:

  • 通道1:电位器 A
  • 通道2:电位器 B
  • DMA 把结果放进 adc_buf[2]

会看到:

  • adc_buf[0] 对应通道1
  • adc_buf[1] 对应通道2

这是后面做传感器采集的重要基础。


第五层:数据处理

目标:别只会采,还要会用。

可以继续追加的内容

  1. 均值滤波
  2. 滑动平均
  3. 去抖动 / 去毛刺
  4. 电压换算
  5. 阈值判断
  6. 校准概念

适合的 demo

Demo 5:ADC + DMA + 平均滤波 + PWM 控灯

这就开始更像一个完整小项目了。


7. 先搞懂的几个问题

ADC 方向

  1. 什么是模拟量,为什么 MCU 不能直接"理解"它?
  2. 为什么 3.3V 会变成 4095?
  3. 分辨率越高意味着什么?
    1 二分法的精度
  4. ADC 原始值怎么换算成电压?
  5. 为什么不同通道对应不同引脚?

DMA 方向

  1. 为什么说 DMA 能减轻 CPU 负担?
  2. DMA 到底搬的是什么?
  3. DMA 是从哪里搬到哪里?
  4. 什么叫循环模式?
  5. 为什么 ADC 连续采样时适合 DMA?

8. 推荐的实操路线

第 1 个学习输出

文档:ADC 基础原理学习笔记

内容包括:

  • 什么是 ADC
  • 12 位分辨率是什么意思
  • 0~3.3V 和 0~4095 的关系
  • 电压换算公式

第 2 个 demo

单通道 ADC 采样 + 串口打印

第 3 个 demo

ADC 控制 PWM 占空比,调节 LED 亮度

第 4 个学习输出

文档:DMA 基础原理学习笔记

内容包括:

  • 什么是 DMA
  • 为什么要 DMA
  • 普通模式、循环模式
  • ADC + DMA 的数据流

第 5 个 demo

ADC + DMA 单通道循环采样

第 6 个 demo

ADC + DMA 多通道采样 + 数据打印

第 7 个 demo

ADC + DMA + 平均滤波 + PWM 控灯

这条路线比较顺,而且每一步都能看到结果。


9. 学习时最容易踩的坑

ADC 常见坑

  1. GPIO 没配成模拟输入
  2. ADC 通道和引脚对不上
  3. 时钟没开
  4. 采样时间设置不合适
  5. 直接拿原始值当电压,不做换算
  6. 对参考电压理解不清

DMA 常见坑

  1. 源地址和目的地址搞反
  2. 数据宽度配置不匹配
  3. 缓冲区长度不对
  4. 没开循环模式却以为会自动刷新
  5. 以为 DMA 会"自动处理数据",其实 DMA 只负责搬运,不负责分析

11. 区分 ADC 和 DMA

ADC

负责"采"------把模拟电压变成数字值。

DMA

负责"搬"------把采到的数字值自动搬进内存。

ADC + DMA

一个负责生产数据,一个负责自动搬数据。

相关推荐
阿荻在肝了2 小时前
Agent实践三:基于Chroma的RAG检索
python·学习·agent
一支闲人2 小时前
研究STM32库函数 如何操作寄存器
stm32·单片机
徐子元竟然被占了!!2 小时前
数字证书学习
linux·网络·学习
lkforce2 小时前
MiniMind学习笔记--安装部署
笔记·python·学习·minimind
minglie12 小时前
zynq驱动SPI ST7735S LCD
学习
langmeng1102 小时前
Linux安装Kafka3.8.0版本不使用zookeeper
linux·运维·服务器
亚空间仓鼠2 小时前
Shell脚本详解:从理论到实践(二)
linux·运维·服务器
Orange_sparkle2 小时前
learn claude code学习记录-S05
学习
code_whiter2 小时前
初阶linux1(常见指令以及权限理解)
linux