想象你站在一座海关口岸的桥头。桥的这边,是模拟世界——声音、温度、压力,一切都在连续地流动,细腻得没有边界;桥的那边,是数字世界——芯片里只有一串串 0 和 1,刻板却精确。STM32 就是这座桥的守桥人。它手里握着两位翻译官:一位负责把模拟世界连绵不断的方言,翻成数字世界能记录的词条;另一位负责把冰冷的词条,再朗读成真实世界听得懂的声音。本文带你围观翻译官是怎么记笔记、怎么同时应对多位来宾、怎么请秘书帮忙归档、又是怎么把笔记复述成一场抑扬顿挫的演讲的。看完你会明白,信号进来再出去,不过是翻译官的一天罢了。
学好 ADC/DAC,等于打通了嵌入式系统连接真实世界的「任督二脉」——无论是传感器采集还是波形输出,你都能精准掌控信号的来龙去脉,这是每一位嵌入式与 AIoT 工程师的硬核基本功。
目录
可视化演示
本节配有交互动效(进入视口后自动加载,约 3KB)。
模拟与数字世界:会议的两种语言
想象一场国际会议。一端是经验丰富的民间艺人,用连绵不断的声音讲述故事,声音的每一个起伏都承载着情绪——这就是模拟世界,细腻、连续、没有边界。另一端是刻板的文书员,只认白纸黑字的代码,每一个符号都非 0 即 1——这就是数字世界,离散、精确、不容含糊。如果没人翻译,两边完全无法交流。STM32 就像会议主办方,请来了两位翻译官:ADC 把艺人的话语翻译成文书员能记录的数字,DAC 把文书员的记录还原成会场能听懂的声音。
模拟世界里,温度、声压、光照都是连续变化的物理量;数字世界里,处理器只能处理 0 和 1 组成的离散量。要让 STM32 感知温度,必须把连续电压变成一串数字;要让扬声器发声,又必须把数字变回连续电压。任何嵌入式测控系统都绕不开这对「出入关」。传感器、执行器、控制器之间的信号链路,本质就是「模拟→数字→处理→数字→模拟」的循环。
在 STM32 中,模拟信号体现为引脚上连续变化的电压,数字信号则是二进制表示的采样值。一个典型的正弦电压信号可以写成连续函数:
理解了两种语言的天壤之别,你就明白为什么要请翻译官了。接下来,我们翻开 ADC 的笔记本,看看他是怎么把连绵的话音切成一个个词条记下来的。
- 瞬时电压 v(t)表示在任意时刻 t,信号线上对应的电压值,单位是伏特。
- 振幅 A决定波形最高点到平衡位置的距离,A 越大信号越「响亮」。
- 正弦函数 sin描述电压值随时间按正弦规律上下摆动,是自然界最常见的波形之一。
- 相位角 2πftf 是信号频率,t 是流逝的时间,二者相乘后的角度决定此刻波形处于上升还是下降阶段。
ADC工作原理:翻译官的笔记法
翻译官拿到一段连续话语,第一件事不是全文抄写,而是每隔几个字记一个关键词。能记多快、记多准,决定了后半段复述的质量。这个「每隔一段时间取一个词」的动作,就是采样。现场声音变化越快,笔记就要记得越勤,否则漏掉的关键词会让整段话变味。
不过这里藏着一个坑:说话人语速太快时,翻译官上一个词还没记完,下一句话就过去了。ADC 内部因此装了一个「暂停键」——采样保持电路。在记词的瞬间,它把电压稳稳「夹住」,让后级的量化电路从容读数,读完了再松手迎接下一个词。这正是「采样-保持」两个阶段的由来:采样期跟踪输入,保持期冻结电压。
STM32 的 ADC 采用逐次逼近型(SAR)结构,工作方式像「猜数字」游戏:先猜中间值,比较一下实际电压比它大还是小,再折半调整,N 次比较后就能逼近到 2^N 分之一的精度。配合采样保持电路,一次完整转换要经历采样、保持、比较、编码四个阶段。要让复述不走音,采样频率必须满足奈奎斯特定理:
翻译官把记笔记的频率和精度掌握好,还原度就有了基本盘。但「熟练」不等于无限提速,而是按需配置。下一节,我们看看他的词汇量、笔速和嗓门到底该怎么调。
- 采样率 f_sADC 每秒采样的次数,相当于翻译官每秒记多少个关键词。
- 信号最高频率 f_max被采集信号里频率最高的成分,相当于演讲者飙到的最高音。
- 系数 2奈奎斯特定理给出的最小倍数,少于 2 倍时高频成分会伪装成低频混叠信号。
- 严格大于号 >极限情况等于 2 倍也不够,必须留出裕量才有工程意义。
关键参数配置:词汇量、笔速与嗓门
同样是翻译,专职同传的词汇量、语速和麦克风音量都经过精心设置。ADC 也有三个对应的旋钮:分辨率管词汇量,采样时间管笔速,参考电压管嗓门。三个旋钮配合得好,翻译才既快又准还不破音。
分辨率决定数字码能表达多少等级。8 位只有 256 个等级,12 位有 4096 个等级——就像翻译官用「大约三伏三」描述电压,还是用「精确到 0.8 毫伏」描述电压,细腻程度完全不同。采样时间则是采样电容充电的时长,充电不足就相当于翻译官没听清就落笔,误差会直接写入笔记。参考电压是 ADC 的「嗓门基准」,它定义了满量程对应的电压上限,嗓门不稳,所有翻译都跟着跑调。
STM32 中,采样时间由寄存器配置,可选的系数从 1.5 到 239.5 个 ADC 时钟周期不等。以 12 位 ADC 为例,单次转换总时间由采样时间和固定逼近时间组成:
旋钮没有绝对好坏,只有匹配不匹配。给慢速温度信号配高速采样是浪费,给高频信号配低采样则必然失真。把嗓门(参考电压)稳住,翻译才不走音。接下来,看看翻译官怎么同时应对多位来宾。
- 转换总时间 T_conv从启动采样到数据寄存器收到稳定结果的完整耗时。
- 采样时间 T_sample可配置的采样电容充电窗口,窗口越宽电压越接近真实值。
- 固定系数 12.512 位逐次逼近需要 12 次比较,再加若干周期开销,手册给出 12.5 个周期。
- ADC 时钟周期 T_ADC_CLKADC 模块的时钟周期,由 PCLK2 分频得到,是时间计量的基本节拍。
多通道扫描:一场多位来宾的圆桌会谈
圆桌会谈来了八位来宾,会场却只有一个话筒。翻译官只能轮流听每个人说几句,再快速切换到下一位。STM32 的 ADC 通常只有一个转换核心,但通过内部多路开关,可以依次切换采集多个输入引脚——这就是多通道扫描模式。
STM32 把需要轮流服务的通道分成两组。规则通道组像「普通来宾」,按预设名单依次发言,适合周期性的常规采集;注入通道组像「VIP」,可以随时插话,打断规则组的转换去处理紧急事件,适合突发性的高优先级采样。谁先谁后、每个通道排在第几位,都由通道序列器(sequence)统一调度。
假设规则序列里安排了 M 个通道,每个通道转换时间均为 T_conv,那么扫完一整轮、拿到全部通道各一个数据点所需的时间就是:
翻译官轮番接待多位来宾游刃有余,但如果每位来宾都在滔滔不绝地连续发言,翻译官根本没时间整理笔记。这时候需要一位秘书替他把记好的词条搬到后台——这就是 DMA。
- 扫描总时间 T_scan完成一轮所有通道采集的耗时,相当于翻译官绕圆桌一整圈。
- 通道数量 M规则序列里配置的通道个数,来宾越多,轮一圈越久。
- 单通道转换时间 T_conv每个通道一次完整转换所需时间,由上一节的采样时间和逼近时间决定。
- 乘积关系 ×串联排队模式使总耗时线性累加,这也是多路采集刷新率的直接瓶颈。
DMA连续采集:专职秘书自动归档
没有秘书的会议,翻译官记完一页纸就要亲自跑一趟档案室,回来时演讲已经过去半句了。DMA 就是这位秘书:数据从外设到内存的搬运全程由它代劳,CPU 可以安心处理算法,不必为搬数据打断思路。
ADC 每完成一次转换,都会把结果丢进数据寄存器。DMA 收到触发信号后,自动把寄存器里的数据搬到内存数组,搬完一个再等下一个,完全不需要 CPU 介入。连续采样时,DMA 以「半满中断」为界,把缓冲区一分为二:CPU 处理前半部分数据的同时,DMA 继续向后半部分搬运,两块区域交替使用——这就是双缓冲机制,能有效避免「一边写一边读」的冲突。
缓冲区越大,CPU 处理越从容,但内存资源有限。DMA 的搬运压力与采样率直接挂钩,每秒需要搬运的字节数可以这样估算:
秘书把笔记整理得井井有条,CPU 拿到的是一份份完整档案,而不是满地碎片。不过翻译不只是「听进来」,还有「说出来」——出境翻译官 DAC 该登场了。
- 搬运速率 R_byteDMA 每秒钟需要从外设搬到内存的数据量,也就是秘书的工作强度。
- 采样率 f_sADC 每秒产生的样本数量,采样越快,秘书越忙。
- 每样本字节数 B_sample一个采样结果在内存中占用的字节数,12 位数据通常按 2 字节存储。
- 乘积关系 ×总搬运量与采样率、样本宽度同步增长,评估 DMA 带宽是否够用时看它。
DAC波形生成:把笔记复述成演讲
出境翻译官的工作与 ADC 正好相反:文书员递来一张写满代码的纸条,他照着纸条上的每个词,用模拟世界的声音朗读出来。DAC 的每个数字输入码,都对应一个输出电压,码变,电压跟着变,读出来的声音就有了起伏。
如果输入码按时间连续变化,输出就是一个接一个的电压台阶——连起来看就是阶梯波。台阶越密、越矮,越接近平滑的原始波形。工程上最常用的波形是正弦波,实现方法是查找表:提前计算好一个周期内每个采样点的值,存成一张表,DAC 按地址逐点输出,配合定时器控制输出节奏,就能稳定复现正弦波。想要阶梯波,则只需让码值按固定步长递增或递减。
DAC 输出电压与数字码的关系非常简洁:
翻译官朗读得再标准,音量也很有限。DAC 的输出驱动能力很弱,通常需要运算放大器缓冲后才能真正驱动扬声器或执行机构——就像复述的声音要通过麦克风扩音才能传遍全场。最后,我们来给会议现场做「声学装修」。
- 输出电压 V_outDAC 引脚上真正呈现的模拟电压值,是朗读出来的「声音大小」。
- 数据寄存器 DORCPU 写入 DAC 的数字码,相当于纸条上写着的词条编号。
- 总等级数 2^NN 位 DAC 能表示的量化等级总数,12 位对应 4096 档。
- 参考电压 V_REFDAC 的满量程基准,相当于翻译官能朗读的最大音量。
工程实战要点:会场的声学装修
翻译官再厉害,如果会议室里空调轰鸣、地板漏音,听众照样听不清。ADC 的精度同样会被噪声、电源纹波和地回路干扰拖下水。很多项目的精度瓶颈不在芯片本身,而在外围设计。
几个经典手段值得牢记。第一,参考电压引脚并联 0.1μF 和 1μF 去耦电容,把参考电压这个「嗓门基准」稳住;第二,模拟地与数字地单点汇合,避免数字电路的高频开关噪声串入模拟回路;第三,对慢变化信号重复采样取平均,用软件手段对抗随机噪声。只要噪声是随机的,平均法就有奇效:
会议室装修好了,翻译官的功力才能完整释放。ADC/DAC 这对「出入关」,从此成为你手中的信号桥梁。配置只是入场券,对噪声的敬畏才是高精度的护城河。
- 平均后噪声 V_noise,avg经过 M 次平均后,输出中残留的随机噪声大小。
- 单次噪声 V_noise一次采样中混入的随机噪声幅度,它可正可负。
- 平均次数 M对同一电压重复采样的次数,M 越大平均效果越好。
- 根号关系 √M随机噪声按统计规律部分抵消,因此只按根号 M 衰减而不是按 M 衰减。
AI 应用场景
工业现场多路温度巡检
阶段:数据采集与预处理
解决的问题:传统方案用 CPU 轮询逐通道读取 ADC,多通道同步性差且占用大量算力。采用 ADC 多通道扫描 + DMA 连续采集后,ADC 硬件自动轮流采集各路信号,DMA 把数据成批搬入内存,CPU 只负责温度滤波与超限判断,算力占用大幅下降。
具体案例:注塑机料筒有 8 路热电偶,温度信号变化缓慢。工程师配置 ADC 扫描模式轮询 8 个通道,采样率 1kHz,DMA 环形缓冲保存最新 256 组数据,控制算法直接读取缓冲区的均值,实现了 0.1℃ 分辨率的稳定温控。
医用超声设备自检信号源
阶段:信号生成与激励
解决的问题:超声探头自检需要频率高度稳定的正弦波,模拟振荡器受温度和老化影响漂移严重。改用 DAC + 查找表生成数字正弦波,频率由定时器精确控制,幅度由 DAC 码值决定,稳定度和一致性远超模拟方案。
具体案例:便携超声诊断仪每日开机自检时,固件从 256 点正弦查找表中逐点读取码值,通过 DAC 输出 2.5MHz 正弦激励信号,再经放大后激励探头,检测回波通路是否正常。
无人机电调相电流采样
阶段:实时控制反馈
解决的问题:FOC 电机控制需要精确的相电流,采样窗口极短,错过桥臂导通的中间时刻就采不到真实电流。利用 ADC 注入通道的插话能力,由定时器触发在精确时刻启动转换,再配合 DMA 双缓冲连续搬运,电流环可以跑到 20kHz 以上。
具体案例:穿越机电调采样两路相电流,注入通道在 PWM 中点捕获电流值,DMA 半满中断交替切换缓冲区,CPU 在中断里执行电流环计算,电机响应既快又顺。
Python 演示
# -*- coding: utf-8 -*-"""模拟 STM32 的 ADC 采样与 DAC 重建Python 演示: 模拟信号 -> ADC 量化 -> DMA 搬运 -> DAC 重建"""import math # 会议参数: 现场信号是一个 1kHz 正弦波TARGET_FREQ = 1000.0DURATION = 0.004N_POINTS = 2000 # 翻译官配置: 采样率, 分辨率, 参考电压ADC_SR = 4000RES_BITS = 8VREF = 3.3LEVELS = 2 ** RES_BITS # 1. 生成带噪声的模拟信号(会议室现场嘈杂)analog = []for i in range(N_POINTS): t = i * DURATION / N_POINTS noise = math.sin(2 * math.pi * 7000 * t) * 0.05 analog.append(math.sin(2 * math.pi * TARGET_FREQ * t) + noise) # 2. ADC 采样: 翻译官每隔固定时间记一个关键点N_ADC = int(ADC_SR * DURATION)samples = []for i in range(N_ADC): t = i / ADC_SR idx = min(int(t * N_POINTS / DURATION), N_POINTS - 1) vin_scaled = (analog[idx] + 1) / 2 * VREF code = int(vin_scaled / VREF * LEVELS) code = max(0, min(LEVELS - 1, code)) samples.append(code) # 3. DMA 搬运(秘书归档): 将采样码整体复制到内存缓冲区sample_buffer = samples[:] # 4. DAC 重建: 翻译官照着笔记复述, 采用零阶保持rebuilt = []for i in range(N_POINTS): t = i * DURATION / N_POINTS idx = min(int(t * ADC_SR), N_ADC - 1) vout = sample_buffer[idx] / LEVELS * VREF rebuilt.append(vout / VREF * 2 - 1) # 5. 误差统计: 重建波形与原始波形的差距rmse = math.sqrt(sum((a - b) ** 2 for a, b in zip(analog, rebuilt)) / len(rebuilt))print("采样点数: %d, 分辨率: %d 位, 量化等级: %d" % (N_ADC, RES_BITS, LEVELS))print("DMA 缓冲区大小: %d 字" % len(sample_buffer))print("前 8 个采样码(翻译官笔记):", samples[:8])print("重建 RMS 误差: %.4f" % rmse)
ADC_SR = 4000设置 ADC 采样率 4kHz,相当于翻译官每秒记 4000 个关键点。noise = math.sin(2 * math.pi * 7000 * t) * 0.05构造 7kHz 高频噪声,模拟会议室里的嘈杂背景音。code = int(vin_scaled / VREF * LEVELS)把连续电压映射成 0~255 的数字码,这是 ADC 量化的核心一行。code = max(0, min(LEVELS - 1, code))限幅保护,防止量化结果超出 8 位范围,相当于翻译官确认笔记不越界。sample_buffer = samples[:]模拟 DMA 一次搬运,把采样码整体复制进内存缓冲区。vout = sample_buffer[idx] / LEVELS * VREF数字码反算回电压,对应 DAC 寄存器码值到模拟电压的还原公式。rmse = math.sqrt(sum(...) / len(rebuilt))计算重建波形与原始波形的均方根误差,量化评估采样配置是否合理。
常见误区
误区反正 STM32 ADC 能配到几十 MHz 时钟,采样率拉到最高肯定最保险,数据越多越精确。
正解采样率越高,数据量、DMA 带宽、存储空间和功耗全部跟着涨,CPU 处理不过来时反而会丢数据。采样率只需满足奈奎斯特定理,并留出一定裕量即可。就像翻译官笔记记得过密,整理时反而抓不住重点,适中的节奏才是最优解。
为何常见:直觉上「多记不吃亏」,忽略了嵌入式系统资源有限,任何指标都是有代价的。
误区12 位 ADC 能分辨 3.3V/4096≈0.8mV,所以它量出的电压一定有 0.8mV 的精度。
正解分辨率只是「最小刻度」,真实精度还受参考电压噪声、电源纹波、输入阻抗和布局影响。如果参考电压本身飘了 10mV,刻度再细也白搭。就像尺子最小刻度 1mm,但尺子热胀冷缩,量出来的数照样不准。
为何常见:混淆了「刻度精细」与「测量准确」,把理论分辨率当成实际精度。
误区DMA 会自动把 ADC 数据搬到内存,配置完成后一切自动运行,CPU 可以完全放手。
正解DMA 只是搬运工,搬运完成和半完成时仍会产生中断。如果不在半传输中断里及时处理已满的半块缓冲区,数据会被新数据覆盖。双缓冲 + 中断协同是连续采集的标配,CPU 必须在合适的时机「接货」。
为何常见:把「DMA 传输数据」误解为「数据已被妥善处理」,忽略了传输与处理是两个环节。
误区DAC 输出引脚有 3.3V 电压,直接接扬声器或电机就能工作。
正解DAC 输出的是电压信号,驱动电流能力极弱,带不动感性或大功率负载。必须经过运算放大器缓冲或功率放大级才能驱动实际执行器。就像翻译官朗读的声音不需要扩音器,但要让全场几千人听清,必须接上麦克风和功放。
为何常见:电压数值看起来正确,忽略了驱动能力(电流)才是带负载的关键。
面试题
Q1. STM32 中 ADC 的核心作用是什么?
- A.把数字信号转为模拟信号
- B.把模拟信号转为数字信号← 正确答案
- C.放大微弱的模拟电压
- D.生成固定频率的脉冲波
答案:B。ADC(模数转换器)的职责就是把连续变化的模拟电压转成离散的数字码,相当于「入境翻译官」。A 说的是 DAC,C 是运放的职责,D 是定时器/PWM 的职责。
Q2. 采样保持电路的主要作用是什么?
- A.缩短单次转换时间
- B.在转换期间保持电压← 正确答案
- C.滤除输入高频干扰
- D.放大输入信号幅度
答案:B。采样保持电路在采样时刻把输入电压「冻结」,让逐次逼近电路有稳定的读数时间。它不负责滤波或放大,也不能缩短转换时间,因此 B 正确。
Q3. 某模拟信号最高频率为 10kHz,理论上最低采样率应选?
- A.8kHz
- B.12kHz
- C.20kHz← 正确答案
- D.30kHz
答案:C。根据奈奎斯特定理,采样率必须严格大于信号最高频率的两倍,即 20kHz 是理论下限。8kHz 和 12kHz 都低于两倍,30kHz 虽然可行但不是「最低」选择。
Q4. 12 位 ADC、参考电压 3.3V,一个 LSB 对应的电压约为?
- A.0.81mV← 正确答案
- B.0.40mV
- C.1.65mV
- D.0.21mV
答案:A。一个 LSB = V_REF / 2^N = 3.3V / 4096 ≈ 0.806mV,即每个最低位代表约 0.81mV 的电压台阶。其余选项均为错误换算,记住公式即可。
Q5. 逐次逼近型 ADC 完成 N 位转换大约需要多少个时钟周期?
- A.N/2 个周期
- B.2N 个周期
- C.N+1 个周期左右← 正确答案
- D.与 N 无关固定 1 个
答案:C。逐次逼近型 ADC 每一位都需要一次比较判断,N 位就需要 N 次比较,再加上少量开销,STM32 12 位 ADC 典型转换时间为 12.5 个 ADC 时钟周期,与 C 描述的「N 加少量周期」一致。
Q6. 下列哪些是 ADC 工程的合理配置策略?
- A.多通道采集选择扫描模式← 正确答案
- B.连续采样时配合 DMA 搬运← 正确答案
- C.采样率拉到最高最稳妥
- D.按信号频率选择采样率← 正确答案
答案:ABD。扫描模式适合多通道轮流采集,DMA 能减轻 CPU 搬运负担,采样率应依据奈奎斯特定理按信号频率选择。C 忽略了功耗、内存与带宽代价,是不合理的策略。
Q7. 关于 DMA 在 ADC 连续采集中的说法,正确的是?
- A.DMA 可自动将结果搬到内存← 正确答案
- B.半满中断可用于切换缓冲← 正确答案
- C.DMA 能直接分析数据含义
- D.DMA 能减轻 CPU 负担← 正确答案
答案:ABD。DMA 负责数据搬运,半满中断让 CPU 在处理半块数据时另一块继续写入,从而实现双缓冲。DMA 只搬运不分析,因此 C 错误,A、B、D 正确。
Q8. 12 位 DAC 写入码值 2048,参考电压 3.3V,输出电压约为?
- A.3.30V
- B.1.65V← 正确答案
- C.0.82V
- D.2.48V
答案:B。V_out = DOR / 2^N × V_REF = 2048 / 4096 × 3.3V = 1.65V。写入满量程一半的码值,输出恰为参考电压一半,这是 DAC 最常用的中点电压。
Q9. 下列哪些措施能有效提升 ADC 采集精度?
- A.参考电压引脚加去耦电容← 正确答案
- B.多次采样结果取平均← 正确答案
- C.尽量缩短采样时间
- D.优化模拟地与数字地← 正确答案
答案:ABD。去耦电容稳定参考电压,多次平均抑制随机噪声,地回路优化减少干扰串入,三者都能提升精度。C 缩短采样时间会让采样电容充电不足,反而降低精度。
Q10. STM32 ADC 规则通道组与注入通道组的区别是?
- A.规则通道优先级更高
- B.注入通道可打断规则转换← 正确答案
- C.规则通道能打断注入转换
- D.两组通道完全等价
答案:B。注入通道具有插话能力,可以在规则通道转换过程中插入执行,适合响应突发事件;规则通道按序列器顺序执行。因此 B 正确,A、C、D 均为错误描述。