☰
ADC/DAC原理与实战:从采样量化到PCB布局的完整解析
2026/10/5 7:25:26 网站建设 项目流程

1. DAC/ADC到底在干什么:从信号链说起

做电路设计这些年,ADC和DAC这两个词几乎被我写烂了。不管是传感器采集、音频处理、电源监控还是波形发生,只要涉及模拟与数字的边界,就绕不开这对“翻译官”。这几天重新翻了翻DAC和ADC的原理,结合平时调试中踩过的坑,想着整理一篇笔记出来,给刚入门的朋友一个参考,也给自己温习一遍。

先说一个最容易被新手忽略的认知:ADC和DAC解决的问题不是“电压数值是多少”,而是“怎么把一个连续变化的物理量,变成一个有限精度、有限速度的数字序列”,或者反过来。模拟世界是连续的,数字世界是离散的,这个“离散化”的过程才是所有原理的核心。你用单片机采集一个电压、输出一个波形,本质上都在做这个翻译动作。

这篇东西不会只讲定义和公式,我会把采样保持、分辨率、量化噪声、参考电压这些概念放到真实的电路设计场景里聊,再结合我实际调试过的STM32平台、前端RC滤波、PCB布局这些内容,把原理到实践的路走一遍。适合刚开始接触数据采集的嵌入式工程师、硬件工程师,也适合那些已经会用ADC但总觉得“数据不太对”的人。

2. 核心概念:分辨率、采样率与那些“看不见的误差”

要说清ADC/DAC原理,绕不开几个基础概念。这部分的公式不复杂,但理解透了能帮你省掉大量后续调试时间。

2.1 分辨率不是“位数”那么简单

很多人一开口就问“你是几位的ADC”,好像12位就是比10位高一档,16位就是天花板。位数确实直接决定分辨率,但分辨率的真正含义是“能被分辨的最小电压变化”,也就是1个LSB对应的电压值。

计算公式很简单:LSB = Vref / 2^N,其中N是位数,Vref是参考电压。举个例子,STM32F103内置的是12位ADC,如果参考电压是3.3V,那么每个LSB对应的电压就是3.3 / 4096 ≈ 0.8057mV。所以当有人问“如果单片机ADC输入口电压为1V,采样得到的值是多少”,你直接算:1V除以0.8057mV,约等于1241。这个数值就是理论上应该出现在ADC数据寄存器里的原始值。

但这里有个很容易踩的坑:这个计算成立的前提是参考电压必须是纯净的3.3V。如果Vref引脚上的纹波有50mV,那么整个转换结果就会跟着一起飘。我见过一个项目,ADC读数在1020到1260之间大幅跳变,排查了一整天,最后发现是参考电压芯片的输出电容太小,导致低频纹波全部灌进Vref了。所以请记住一句话:ADC的精度永远不会超过它的参考电压精度。

另外,DAC的分辨率也是同样的道理。例如STM32F4的DAC是12位,输出范围0到3.3V,写寄存器值2048时理论输出就是1.65V。但如果你后面接的运放电路偏置不对,实测出来可能偏了十几毫伏,这时候别急着骂DAC,先量一下参考电压和运放供电再说。

2.2 采样率、采样周期与信号带宽

采样率决定你能观察多快的信号。奈奎斯特定理要求采样频率至少是信号最高频率的两倍,否则会出现混叠。比如你要采集一个10kHz的正弦波,理论上采样率至少要20kSPS。但这只是理论,实际应用中我总是会留出至少四到五倍的余量,原因有两方面:一是真实信号的频谱往往不是干净的单一频率,谐波分量可能更高;二是前端滤波器的滚降特性不可能做到理想矩形,总有过渡带。

关于“ADC采样周期”,这里想多说几句。ADC完成一次采样转换,远不是“启动后立刻出结果”那么简单。以逐次逼近型(SAR)ADC为例,一次转换可以分为采样阶段和转换阶段。采样阶段里内部采样电容通过开关网络接入输入信号,这时采样开关的导通电阻和外部源阻抗会构成RC电路,需要时间充电;转换阶段才是逐位逼近的过程。

如果你查STM32的数据手册,会发现每个通道都有一段“最小采样时间”和“最小转换时间”的要求。外部信号源阻抗越高,采样时间就要越长。最简单粗暴的估算是:源阻抗每增加一个数量级,采样时间至少翻倍。我调试过一个光电二极管放大电路,运放输出直接进ADC,因为运放带宽较低导致输出阻抗偏大,采样时间设成1.5周期时读数忽高忽低,改成7.5周期后稳定下来,原理就在这里。

2.3 量化噪声、信噪比与有效位数ENOB

把连续的模拟电压映射到有限个离散码值,必然产生误差,这个误差叫量化误差。理想N位ADC的量化噪声均方根值约为LSB/sqrt(12)。量化噪声对信噪比的影响可以用一个很常用的公式估算:SNR = 6.02N + 1.76dB。一个理想的12位ADC,理论信噪比约74dB。

但现实中没有理想的12位ADC。芯片内部的参考电压噪声、比较器失调、电容失配都会让实际SNR比理论值低。所以我们更关心的是有效位数ENOB:ENOB = (SINAD - 1.76) / 6.02。芯片手册上标的“12位ADC”,ENOB可能只有10.7位到11.3位。做高精度采集时,我一般直接看SINAD指标而不是位数,因为这决定了你的系统动态范围到底有多少。

这个SNR公式还告诉我们一个残酷的事实:每多一位有效分辨率,约等于要提升6dB信噪比。而每提升3dB信噪比,如果靠降噪声来实现,意味着噪声功率要减半。所以你会发现,提高有效位数的本质是降低系统总噪声,包括输入噪声、参考噪声、时钟抖动和电源耦合噪声。这也是为什么原理上简单的东西,实际做起来总是很难。

3. 常见ADC/DAC架构拆解:选型时心里得有谱

ADC和DAC的内部架构有很多种,每种架构的优劣差异巨大。选型时不能只看位数和采样率,要看应用场景。

3.1 SAR型ADC:中等速度中等精度的全能选手

逐次逼近型ADC是目前微控制器内置ADC中最常见的架构,STM32全系基本都是SAR结构。它的工作原理可以类比成“用天平称重”:先用1/2满量程电压去比较,如果输入电压大于这个电压,最高位置1,否则置0;然后再用剩余范围的1/2去比较,依次类推,N位就比N次。

SAR ADC的优点是功耗低、体积小、转换速度快(通常能做到几百kSPS到几MSPS),而且没有流水线延迟,启动后很快出结果,非常适合单通道或多通道轮询采集。缺点也很明显:对前端驱动电路要求高,因为每次采样都是电容充放电,会从信号源抽取瞬态电流;如果外部RC滤波器的电容太大,反而会让采样电容充不满,导致读数偏低。

我在做ADC端口电路设计时,经常看到有人在输入口加一个0.1uF的电容滤噪声。这个思路本身没问题,但对SAR ADC来说,大电容和源阻抗形成的RC时间常数可能超过采样时间,导致动态误差。相对稳妥的做法是电容选小一点,比如1nF到10nF之间,或者用运放做缓冲器驱动ADC输入,把源阻抗压低。

3.2 Δ-Σ型ADC:高分辨率的另一种玩法

Δ-Σ(Delta-Sigma)ADC的原理跟SAR完全不同。它用的是一种叫做“过采样加噪声整形”的技术:以远高于奈奎斯特频率的采样率对信号采样,然后通过反馈环路把量化噪声推到高频段,再用数字滤波器把高频噪声滤掉,从而换取高分辨率。

这类ADC最典型的应用是音频、精密测量、称重传感器前端。24位分辨率、几百SPS采样率的Δ-Σ芯片很容易买到,价格也不贵。但它有个重要特点:需要外部配一个RC滤波器。很多文章都在讨论“∑-δ ADC前端RC滤波设计”,实际上这层RC滤波的核心目的不是滤除带外信号,而是作为内部开关电容采样器的电荷缓冲,让外部运放能更稳定地驱动ADC。

这个RC的值选择有讲究。电阻太小,运放驱动容易不稳定;电阻太大,采样瞬态引起的压降会在电容上形成误差。电容太小起不到电荷缓存作用,电容太大又会让建立时间变长。按照我实验过的经验,对于常见的ADS1256、CS5532这类芯片,R取1kΩ到5kΩ、C取0.1uF到1uF是比较合理的起点,具体数值最好根据运放输出阻抗和ADC采样时钟做一次仿真确认。

另外,Δ-Σ ADC的输入结构通常是差分形式,内部有一个开关电容输入级,会周期性抽取电荷。如果你用单端信号源直接接,共模噪声和电荷抽取的不对称会被当成有效信号放大。所以建议差分驱动,或者在单端输入端额外加一级调理电路。

3.3 DAC的常见内部结构:R-2R与电流舵

DAC的原理相对简单一点,但也分好几派。最常见的是R-2R梯形网络,它用一组精确的电阻网络把数字码等比例转换成电压或电流。这种结构设计简单、成本低,但对电阻的绝对精度和温度系数要求很高,所以高精度的R-2R DAC一般都会做激光调阻或者出厂校准。

另一种常见结构是电流舵型DAC,它用一组并联的电流源,按二进制权重决定哪些电流源被接入输出端。电流舵DAC速度快、精度高,高速波形发生器和射频信号源里大多用这种结构,但面积和功耗相对大。

我做单片机DAC输出时,最常用的还是STM32内置的电压输出型DAC。它的输出能力比较弱,不能直接驱动沉重负载,一般后面要接一级运放缓冲。如果你要生成一个相对干净的波形,记得在DAC输出引脚到运放之间放一个小电容,比如100pF左右,滤掉DAC内部开关电容的毛刺,但电容也不能太大,否则波形边沿会变钝,带宽被压低。

3.4 选型时的硬指标与隐藏陷阱

选ADC/DAC芯片时,除了位数、采样率、接口类型这三个大项,我还特别关注以下几个参数:INL/DNL、失调误差、增益误差、参考输入电流和电源抑制比PSRR。

其中DNL(微分非线性)和INL(积分非线性)对系统精度的意义我在实际中体会最明显。DNL表示相邻两个码对应的模拟量间隔与理想LSB的偏差,如果DNL超过1 LSB,就可能出现失码,也就是某一个数字码永远得不到。INL表示实际转换曲线与理想直线的最大偏差,它决定了整体精度上限。

还有一个容易被忽略的是“参考电压输入内阻”。有的ADC内部参考输入是纯电容负载,外部参考源需要足够的驱动能力。如果把一个高输出阻抗的分压电路直接接到Vref引脚,随着采样周期变化,参考电压会出现周期性的塌陷,导致转换结果出现固定模式的误差。解决方法是加一个运放缓冲器,或者在参考引脚就近放一个大容量的低ESR电容做储能。

4. 模拟前端与PCB布局:决定ADC/DAC精度的隐形战场

原理图看着都对,寄存器配置也没有问题,但采集到的数据就是不对,这种情况十有八九出在模拟前端和PCB布局上。下面这部分讲的全是我踩过坑之后的经验。

4.1 前端RC滤波的参数选择

很多入门者在ADC前面加RC滤波器时,会随手选一个典型值,比如100Ω加100nF,算出来的截止频率是15.9kHz,觉得够了。但从ADC的角度看问题就不一样:RC不但要滤掉外部噪声,还要配合ADC采样电容完成电荷转移。给SAR ADC当驱动的话,RC转折频率不能低于信号带宽的10倍,否则建立误差会直接影响最后的几位码值。

我给某传感器板卡做前端设计时,用的是一个三阶方式的组合:第一级用运放做成低通有源滤波器,第二级用1kΩ电阻和10nF电容组成RC,直接驱动SAR ADC。第一次测试时波形很漂亮,但采集的数据高位稳定、低位跳变严重,后来发现是运放输出端到ADC引脚之间的走线太细,寄生电感产生了振铃。换成短而宽的走线,并在ADC引脚正下方放一个100nF的去耦电容后,问题消失。

对于Δ-Σ ADC,前端RC往往承担着“抗混叠滤波”和“采样电荷缓冲”双重任务。如果RC带宽太宽,带外噪声进入调制器后会被噪声整形放大,导致SNR下降;如果RC太窄,有用信号被衰减或者建立时间受限。我的经验是先把目标信号最高频率定下来,然后RC带宽取信号最高频率的2到3倍,同时保证在采样频率处的衰减不低于20dB。

4.2 PCB布局中关于时钟与电源噪声的处理

ADC/DAC电路布板有一个核心矛盾:数字部分和模拟部分靠得近会互相干扰,靠得远又让走线变长。对于单芯片系统,比如STM32内置ADC,根本没有办法做完整的AGND和DGND物理分割,这时候更实用的策略是统一地平面加分区去耦。

先说要避开的3个PCB布局要点,也是我多次实测后提炼的:

第一,时钟信号必须远离模拟输入引脚。ADC在转换过程中,内部比较器的时钟跳变会产生很大的瞬态电流,这个电流在地平面上形成地弹噪声。如果晶振或时钟线走线过长且穿越模拟区,噪声会通过寄生电容耦合到模拟输入。我调试FSK信号采集方案时,把原来放在模拟输入边上的晶振挪到板边,并用包地隔离了一下,ADC底噪直接降了三分之一。

第二,电源走线和高dt/di的开关节点不能与模拟输入走线平行。如果你板上有Buck降压电路,开关节点的高频振铃很容易通过空间耦合到AD采样走线上。经验规则是:模拟走线与开关节点保持至少3倍线宽的间距,最好走线间加一条地线做隔离。

第三,去耦电容的接地过孔要紧挨着芯片电源引脚。很多设计者把电容放在芯片旁边但过孔打得很远,这个环路面积一大,去耦就失效了。正确的做法是让电源电流先流过电容,再过过孔回到地平面。我甚至会在Vref引脚附近并联两个电容:一个100nF滤高频,一个4.7uF做储能,实测效果比单电容好很多。

电源噪声对ADC信噪比的影响在低频段非常明显。如果你用万用表测电源纹波只有几mV,觉得没问题,但ADC的SNR可能已经被这个几mV的纹波限制住了。原因在于ADC的电源抑制比(PSRR)不是无限大,而且不同的电源频率下PSRR表现差异很大。一定要测电源纹波时顺便看频率,确认纹波是不是落在你信号带宽之内。

4.3 输入端口保护电路与阻抗匹配

ADC输入的过压保护是个老生常谈但总被忽略的问题。工业场景里,传感器输出线可能有静电放电或者瞬间短路,如果ADC输入端没有保护,一个电压尖峰就可能让芯片内部ESD二极管损坏。

我常用的保护结构是:在ADC输入端串联一个1kΩ电阻,然后在电阻后面并联两个钳位二极管,一个接到VCC,一个接到GND。这种结构能把输入电压限制在二极管压降之内,比单纯用TVS管方案省成本,而且对采样带宽的影响可以接受。需要注意,串联电阻和二极管结电容又会在输入端形成一个RC低通,如果信号频率较高,要重新核算带宽。

阻抗匹配的问题出现在高速采集场景。如果你用ADC采集的是射频或中频信号,信号源阻抗是50Ω或75Ω,而ADC输入阻抗不是标准的,就需要加匹配网络。匹配的目标一个是保证传输线上没有反射,另一个是给ADC的采样电容足够的充电电流。这时候仿真软件就很有用了,我用ADS和LTspice都做过输入端口的S参数仿真和瞬态仿真,可以提前把阻抗和建立时间问题暴露出来。

4.4 数据漂移、ADC采样矫正与软件滤波

硬件做得再稳,ADC的数据还是会漂。漂移来源很多:温度变化导致的参考电压漂移、运放的失调温度系数、信号源自身的老化等。解决漂移不能只靠硬件,软件矫正同样重要。

ADC采样矫正的核心思路是“两点校准”:在ADC量程内取两个已知的精确电压,采集对应的原始码值,然后用线性拟合算出实际的增益和失调。比如0V对应码值10,2.5V对应码值3050,那么实际电压值就可以用这两个点做一条直线映射。这个方法简单可靠,几乎所有需要较高精度的采集板我都加了。

软件滤波函数也是必修课。我在C语言里写过滑动平均、中值滤波和加权平均几种,发现不同场景效果差别很大。滑动平均适合平稳信号的噪声抑制,但对突发干扰没反应;中值滤波能去掉野值,但对连续慢变化的信号会引入延迟;加权平均适合带宽有限、实时性要求高的场合。

实际项目中我用的最多的是“中值加滑动平均”的组合:先取5个点做中值滤波,去掉偶然跳变,再对这5个中间值做滑动平均。这个思路比单纯一种滤波函数稳健很多,代码量也就十几行。但滤波函数会引入延迟,做高速闭环控制时要注意相位滞后的问题,这就需要结合控制周期来设计滤波器阶数。

5. 嵌入式实战:STM32平台上的DAC/ADC应用详解

原理再熟,最终要落到代码和实际板子上。STM32这类MCU内置的ADC/DAC是绝大多数工程师的入门平台,这里讲几个我实际调过的场景,既能复习原理,也能给读者一个可直接落地的参考。

5.1 用定时器触发DAC输出正弦波

用STM32F4的DAC输出一个正弦波,看起来很简单:查表、写寄存器、延时,再写下一个值。但如果要求波形稳定且频率精确,直接在主循环里延时输出是不行的,抖动太大。正确做法是用定时器触发DAC更新。

初始化思路是:定时器6配置成PWM模式或者更新事件模式,设置好预分频和自动重载值,使更新频率等于你期望的DAC输出频率乘以查表点数。然后使能定时器触发DAC转换的通道,也就是DAC的TIM6_TRGO触发源。每次更新事件到来时,DAC自动从数据寄存器读取新值并输出。

我把一段可用的代码结构贴在这里:

// 假设查找表大小为256点,目标正弦波频率1kHz // 则DAC更新频率需为256kHz // 定时器时钟84MHz,预分频84-1,自动重载1000-1,得到1MHz的更新频率 // 再通过DAC触发分频设置得到256kHz,或者直接让定时器更新为256kHz RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 | RCC_APB1Periph_DAC, ENABLE); TIM_TimeBaseInitTypeDef tim6; tim6.TIM_Prescaler = 84 - 1; tim6.TIM_Period = 328 - 1; // 84MHz / 84 / 328 ≈ 3.05kHz? // 这里根据实际频率需要重新计算,仅示意 TIM_TimeBaseInit(TIM6, &tim6); TIM_SelectOutputTrigger(TIM6, TIM_TRGOSource_Update); TIM_Cmd(TIM6, ENABLE); DAC_InitTypeDef dac; dac.DAC_Trigger = DAC_Trigger_T6_TRGO; dac.DAC_OutputBuffer = DAC_OutputBuffer_Enable; DAC_Init(DAC_Channel_1, &dac); DAC_Cmd(DAC_Channel_1, ENABLE);

代码里的分频值需要根据实际时钟频率和目标波形频率精确计算,我这里只是把触发关系写清楚。这类定时器触发的方案,好处是波形更新节拍完全由硬件控制,不占用CPU,而且相位抖动极小。

实际调试中要注意DAC输出缓冲器的带宽。STM32F4的DAC输出缓冲开启后,带载能力增强但高频响应会受限。如果输出1kHz正弦波完全没问题,但如果想输出50kHz以上的波形,缓冲器的压摆率可能让波形失真,这时可以考虑关闭缓冲,后面加外部运放。

5.2 三重模式ADC与注入通道的读取时机

STM32F103系列里有个“三重模式ADC”的功能,可以把三个ADC模块组合使用,实现对同一信号的同步采样或者交替采样。同步采样适合三相电流测量这类需要同相位捕捉的场景,交替采样则可以在不提高单个ADC采样率的情况下把等效采样率提升三倍。

三重模式最常见的坑是数据寄存器读取冲突。三个ADC转换结束后,数据统一放在ADC_CDR寄存器里,但这个寄存器是32位的,包含两个16位字段。如果读取时序没处理好,可能读到一半新数据又覆盖进来,导致数据错位。最稳妥的方式是通过DMA读取ADC_CDR,利用DMA的硬件同步特性避免数据撕裂。

注入通道是STM32 ADC的一个增强功能。规则通道的转换结果会被不断覆盖,但注入通道的结果存放在独立的寄存器中。正因如此,注入通道适合用在那些“不能被其他通道轮询打扰”的关键采样场景,比如电机控制中需要精确对齐PWM中心点的电流采样。

关于“什么时机读取注入通道结果”,我的建议是:不要用主循环轮询,而是在注入通道转换结束中断里读取。如果你用的是PWM中心对齐模式,把注入通道触发源配置成定时器的TRGO事件,这样每次PWM周期中心点都会自动触发一次电流采样,采样时刻和PWM载波严格对齐。读取的代码可以放在中断服务函数里,先把数据存到全局变量,主循环再去处理。

我调试过一个无刷电机驱动板,开始用规则通道轮询采电流,波形噪声大而且随占空比变化,后来改成PWM中心对齐触发注入通道,电流波形瞬间干净了。这一改动本质上是把采样时刻点从“软件随机延时”变成“硬件精确对齐”,效果非常明显。

5.3 DMA读取ADC数据时为什么会“紊乱”

“GD32E230 ADC DMA数据紊乱”这类问题在STM32上也很多见。最典型的现象是:通道顺序忽对忽错,数据错位,好像某一次转换的结果跑到另一个通道去了。

发生这个问题的本质原因是:DMA传输的数据长度与ADC转换完成事件没有同步。比如你配置了规则通道序列有4个通道,但DMA配置成循环模式且数据长度固定为4,一旦某次DMA请求发生时机不对,整个缓冲区的数据就会整体错开一个通道。

我对这个问题的排查思路是这样的:第一步,确认DMA的传输方向和外设地址是否配置对;第二步,确认数据宽度是否与寄存器位数匹配;第三步,检查DMA是否开启了“外设地址增量”模式,ADC数据寄存器是固定的,不能增量;第四步,也是最重要的,在DMA中断里加一个“帧完成”标志,主循环只在标志置位时才处理缓冲区,避免处理过程中缓冲区被覆盖。

还有一个我踩过的坑是缓存一致性问题。如果用DMA写入一个SRAM缓冲区,主循环读取这个缓冲区,编译器优化之后可能让CPU从寄存器缓存里取值,导致数据不更新。解决方式是把缓冲区定义成volatile类型,或者用特定指令做内存屏障。

5.4 用斜坡法仿真ADC的DNL

在写底层驱动或者评估一个ADC的线性度时,很多人会直接在硬件上测,但如果没有专业测试设备,用“斜坡法”也能得到初步的DNL数据。思路是给ADC输入端加一个缓慢变化的线性电压,记录每个数字码出现的次数。如果ADC是理想的,每个码出现的次数几乎一样;如果某个码的次数明显偏大,说明该码的宽度偏大,DNL为正;反之DNL为负。

我在量产测试程序里用过这个思路做快速筛选。具体实现是用DAC输出一个三角波,每次加一个非常小的步进,等待信号稳定后触发一次ADC转换,统计各码值出现次数。因为DAC本身也有DNL,这个方法测出来的DNL包含了DAC的误差,所以只能做相对筛查,但用来发现“失码”或者“气泡码”已经足够。

需要说明的是,斜坡法的斜坡速度要足够慢,慢到ADC在每个码区间内采样足够多的点数,否则统计误差会淹没DNL本身。我一般保证每个码至少有几十次采样,这样统计结果才可信。

6. 调试实录:我遇到的8个“原理正确但实践翻车”的案例

原理都明白了,还是要看实际操作。这一节整理几个我做过的项目里最有代表性的调试经历,每个问题背后的原因都值得记录。

6.1 电源耦合导致的信噪比恶化

某次为工业仪表设计4-20mA信号采集板,PCB布局时偷懒,把Buck电感放在ADC输入连接器附近,第一版样机出来后,ADC读数在50Hz和150Hz附近有明显毛刺。示波器测量输入引脚上是干净的,但FFT频谱分析显示信号上有高次谐波。

排查过程比较曲折,最后用近场探头沿着走线扫,发现最严重的位置就是Buck电感正下方的模拟输入端走线。解决方案很简单,把这段走线改到板子的另一层,并且在上层铺了一块完整地平面做屏蔽,毛刺瞬间下降了20多dB。从那以后我形成了习惯:电源类噪声排查一定要配合近场探头和频谱分析,单纯看时域波形很容易漏掉高频干扰。

6.2 参考电压芯片选型不当导致的采集误差

另一个项目里,我为了节省成本选了一款最大输出100mA的参考电压芯片给ADC供电,结果每次ADC采样瞬间,参考电压就跌落将近10mV。因为SAR ADC在采样阶段需要一个较大的瞬态电流,参考源供电能力不足就会周期性塌陷。

后来我试过在参考引脚附近加大电容,有一定改善,但治标不治本。换了一个输出电流更大的参考芯片,并在其输出端并联一个10uF钽电容和100nF陶瓷电容,参考电压的瞬态跌落才被压到1mV以内。这个案例告诉我:参考源不仅要有精度,还要有足够的电流驱动能力和对瞬态负载的响应速度。

6.3 采样时间不足引发的“非线性”

有一个用STM32F103采集电位器分压电压的应用,电位器阻值10kΩ,直接从中间抽头进ADC。理论上分压值很线性,但采集结果在量程中间出现两三个“台阶”,像是DNL特别差。查了代码发现采样周期设成了最小值1.5个周期,而10kΩ源阻抗与ADC的内部采样电容10pF左右的RC时间常数根本不匹配。

把采样周期改成7.5周期后,台阶消失,线性度恢复正常。这个案例非常适合初学者理解采样保持时间的重要意义:ADC不是瞬时完成电压捕捉的,它要把外部电压“灌”到内部电容上,如果充电时间不够,结果自然偏低。从此以后凡是用高阻源直接接ADC,我都会算一遍RC时间常数。

6.4 DAC输出波形毛刺与缓冲器带宽

用STM32F4的DAC生成20kHz正弦波,用示波器看输出波形,每个点都有尖峰毛刺,波形看起来像是被“口水”淹没。起初怀疑DAC的输出缓冲有问题,查手册发现DAC更新瞬间内部开关会产生电荷注入毛刺,这个毛刺的宽度很窄但幅度不小。

解决方法是输出端加了一级Sallen-Key低通滤波器,截止频率设为信号频率的3倍。滤波后波形干净了很多。但要注意,低通滤波器会带来相移,如果后续要对波形做相位敏感处理,就要把滤波器的相频特性考虑进去,或者改用一个相位更平坦的贝塞尔滤波器。另外如果DAC后面接的是高输入阻抗的负载,可以适当增大滤波电阻以减小电容负载对DAC输出的影响。

6.5 测温NTC电路的非线性补偿

NTC热敏电阻的阻值随温度非线性变化,直接分压进ADC读数后,低温段一个码对应0.05℃,高温段一个码对应0.5℃,如果直接线性映射,温度误差会非常大。这个问题原理上很好理解:NTC的阻值温度曲线本来就是指数形式的,ADC等距采样电压,自然不等距对应温度。

我最后用了查表加线性插值的方法:把温度区间分成几十个点,每隔5℃预先算好对应的ADC码值,实际运行时先查表找到所在区间,再用线性插值精确计算。这种方法比硬算指数公式更省CPU,也比一次多项式拟合更准确。类似的思路还可以用在任何非线性传感器信号处理上。

6.6 采样保持电容导致的串扰

多通道ADC的数据互相串扰是我遇到过的另一个棘手问题。用一个8通道ADC轮流采集8路信号,其中一路是高压信号,其他几路是微伏级信号,结果显示高压信号之后的下一个通道读数明显偏高。

原因是ADC内部的采样保持电容在测量高压通道后,残留了一部分电荷,下一个通道采样时这部分残留电荷没有完全放电。解决方式有两种:一是软件上在通道切换后丢弃第一次转换结果,也就是“Dummy Read”;二是硬件上在每个通道都加运放缓冲,把源阻抗降得很低,让残留电荷快速泄放。我实际项目中两种方法都用了,效果很稳定。

6.7 时钟抖动与采样孔径误差

高速ADC应用里,采样时钟的抖动会直接变成采样点上的电压噪声。假设输入信号是1MHz满幅正弦波,时钟抖动1ns,对应的电压误差约为满幅的0.6%左右。这个误差在高信噪比场景下是致命的。

有次我调试一块高速采集板,FFT测试出来的SNR怎么都达不到预期,后来发现采样时钟是从一颗普通有源晶振经过CPLD分频出来的,抖动指标很差。换成一颗专用的低抖动时钟芯片后,SNR立刻上去了好几个dB。从那以后,凡是对动态范围有要求的设计,我都会把采样时钟的RMS抖动作为一个硬指标来评估。

6.8 数字电源噪声对模拟性能的干扰

最后说一个非常容易踩的坑:MCU的数字电源和模拟电源共用一个LDO。MCU高速运行、GPIO翻转、Flash读取都会在数字电源上产生毛刺,这些毛刺通过公共电源阻抗耦合到模拟部分,ADC性能就会劣化。

解决方案最彻底的是给模拟部分单独用一个低噪声LDO,并在两者之间用磁珠或者0Ω电阻做隔离。如果板面积有限,至少也要保证模拟电源引脚的去耦电容独立,并且数字部分的电流不要经过模拟地去耦电容的过孔。很多时候,一个毫不起眼的电源布局问题,会让原本不错的ADC芯片表现得跟地摊货一样。

7. 快速排查手册与最后的经验总结

平时帮同事看板子,也会被问到很多重复性的问题,这里整理一个速查表,把频率最高的问题、原因和排查方法放在一起,方便读者在实际项目中对照使用。

现象常见原因排查顺序/解决办法
ADC读数大幅跳变参考电压噪声大,或采样时间不足先查参考源纹波,再增大采样周期,看是否改善
数据整体偏低源阻抗过高或采样电容未充满计算RC时间常数,增加采样保持时间,或加缓冲器
通道间数据串扰采样保持电容电荷残留通道切换后丢弃第一次转换结果,或增加运放缓冲
DAC输出毛刺DAC内部电荷注入或电源干扰输出加低通滤波器,检查模拟电源去耦
DMA数据错位DMA与外设事件不同步核对DMA配置,外设地址固定,增加完成标志,小心volatile
低频周期波动电源纹波或地环路干扰用频谱分析确认纹波频率,隔离电源地回路
高速信号采集SNR低采样时钟抖动大换低抖动时钟源,检查时钟布线包地
温度变化读数漂移参考电压温漂或运放失调温漂选择低温度系数参考源,做两点校准

调试ADC/DAC电路说白了就是一句话:先别急着怀疑芯片,从信号源、参考源、时钟、电源、PCB布局这五个方面逐一排查,大部分问题都能定位。

我自己在实际操作中最深的体会是,ADC和DAC的电路设计,真正的门槛不在原理图阶段,而在版图和调试阶段。原理图只要芯片选得合理、外围电容电阻放到位,基本不会出大问题;但PCB布局一旦马虎,所有原理上的优势都会被噪声吃掉。而调试阶段,示波器只是最基础的工具,频谱分析和近场探头能帮你看到更深层的问题。

再分享一个小技巧:ADC/DAC电路改版后,第一次上电不要直接接真实信号测试,先用一个低噪声的直流电压源输出几个已知电压点,分别测试DAC的码值对应关系,确认ADC/DAC链路的基本精度正常,再接入真实信号。这样做的好处是,如果后面出了问题,你能迅速分清是前端信号调理的问题,还是ADC/DAC本身配置的问题。

做电路设计这行,很多时候不是懂了多少高深的理论,而是把原理落到细节里,把每个元件的特性都考虑到位。希望这篇关于DAC/ADC原理与电路设计的笔记,能帮你少踩几个我踩过的坑。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询