在嵌入式里选ADC,我经常跟身边的人说一句话:指标好查,难点全在那些数据手册不会主动提醒你的地方。AD7680这颗16位逐次逼近型(SAR)模数转换器,就是很典型的例子。它来自ADI,速度和功耗都控制得不错,适合做电池供电的便携仪器、电压电流监测、传感器采集这类对精度有要求但又不想把整套模拟链路搞得太复杂的场景。这篇文章我会把SAR ADC的逐次逼近原理、AD7680的关键参数怎么理解、硬件上电源和PCB布局要注意什么、SPI驱动时序怎么配合,再到软件校准和滤波的落地方法,按实际做项目的顺序一次讲清楚。看完之后你可以直接拿它来评估自己的设计是否合适。
1. 逐次逼近的原理:AD7680是怎么测出16位精度的
1.1 从一次天平称重说起
逐次逼近寄存器型ADC,英文叫Successive Approximation Register ADC,常简称为SAR ADC。要理解它的工作方式,最直观的办法是用天平称重来类比。
你想称一袋米,手上有一套标准砝码:128克、64克、32克、16克、8克、4克、2克、1克。称量过程是:先放128克砝码,如果比米重,就把它拿掉,如果是米更重,就保留。接着放64克砝码,同样比较,重则拿掉,轻则保留。这样一轮一轮下来,八个砝码每枚都尝试一遍,最终所有被保留砝码的重量之和,就是米的重量。
SAR ADC做的事情完全一样,只不过它用的“砝码”是一组二进制权重,这些权重由内部的电容阵列和DAC产生。如果ADC是16位的,它就有16个二进制权重,从最大位MSB到最小位LSB依次试探。整个过程分两个阶段:采样阶段先让采样电容跟踪输入电压,转换阶段再由比较器配合DAC逐位逼近。每一轮都只有一个比较动作,结果非0即1,所以SAR ADC的转换周期很短,而且权力分明:一次转换结束,输出就是这一时刻的真实电压数字码,不存在跨周期的累积效应。
1.2 电荷再分配型SAR的内部工作过程
如果拆开AD7680这类电容型SAR ADC的内部模型,它大致由四部分组成:采样保持电路、比较器、SAR逻辑寄存器、以及一个电荷再分配型电容DAC。
在采样阶段,开关会接通输入信号,让内部一排电容充电,电容上的电荷大小正比于输入电压。接下来开关断开,输入被“冻结”在这个电容阵列上。转换开始后,SAR逻辑先把最高位置1,控制电容DAC输出一个相当于一半满量程的电压,跟输入信号在比较器里比一下。如果输入大于这个试探电压,最高位就保留1;反之,这一位清零。接着再置下一位,继续比较。这个过程进行16次,内部一个16位的数字码就一点一点“逼近”了真实输入。
因为这样的结构天然不需要时钟去等待一串数据的建立,所以每次转换得到的都是独立结果,俗称“无流水线延迟”。这就带来一个很实用的好处:如果你是做多通道扫描采集,可以一路采样、一路转换、一路读结果,不需要像某些ADC那样等现象稳定。AD7680对单点采样、快速切换通道这类使用方式非常友好,这也是它在一些测试测量前端里频繁出现的原因。
1.3 AD7680在整个SAR家族中的定位
ADR家有很多SAR ADC,AD7680属于里面比较有代表性的一颗入门级精密器件。很多工程师会拿它做高精度电池电压监测、便携数据记录仪或者工业传感器采集。它的典型特征是单通道、16位、最高100kSPS左右吞吐率,接口是完全兼容SPI的串行接口,封装很小,QFN或MSOP规格都有,板子上不太占地方。
我个人的感受是,AD7680并不是那种“装上去就能出奇迹”的芯片,它的好结果完全依赖你对电源、参考电压和输入驱动的理解。如果你之前只用过MCU内置的12位ADC,第一次切换到这颗芯片时,反而可能会觉得“怎么这么多讲究”。但只要把这几块理顺了,它稳定工作起来的上限,是内置ADC很难比得上的。把普通ADC和精密ADC之间的这道门槛迈过去,AD7680是个很好的练手对象。
2. AD7680的核心亮点:参数背后的价值判断
2.1 16位分辨率与量化噪声阈值
先看一个基本概念。理想N位ADC的理论信噪比SNR等于6.02N+1.76dB。按这个公式,16位ADC的理论SNR约为98dB,而12位内置ADC的理论SNR只有74dB左右。看起来只差了4位,换算成动态范围,差不多是24dB,也就是电压分辨能力差了16倍。
量化噪声的均方根有效值可以表达为LSB除以根号12,而LSB等于满量程除以2的N次方。拿3.3V参考电压举个例子,16位ADC的LSB是3.3/65536,大约50μV。这意味着如果你想把测量误差控制在1mV以内,整个模拟链路里任何一个环节的噪声都不能超过几十微伏的量级。这个数字放在12位ADC上完全不是事,放在16位ADC上就成了硬指标。
我在这里想强调一点:选16位ADC不是因为“位数大听起来厉害”,而是因为你的测量需求真正到了毫伏甚至微伏级别。判断方法很简单——你先算算自己系统里最关心的最小信号变化是多少,再把这个值除以满量程,看需要几位才能分辨出来。算完之后,该用12位还是16位自然就清楚了。
2.2 100kSPS吞吐率与采样建立时间
AD7680的吞吐率达到100kSPS级别,也就是说每秒钟能完成十万次转换。对很多传感器采集场景来说,这个速度已经非常宽裕。不过这里我要提醒一个容易被忽略的概念:采样周期不等于转换时间。
SAR ADC在每一次真正转换之前,都有一个采样时间,这个时间内采样电容要完成对输入信号的“充电”。如果输入信号源的输出阻抗很高,或者前端RC滤波器的电阻选得过大,采样电容在采样窗口内可能还没来得及建立到足够精度,芯片就开始做逐次逼近了。这种情况下读到的数据,即使ADC本身是好芯片,也会出现不可预测的偏差。
一个工程上的经验是:信号源阻抗尽量控制在几百欧到一两千欧以内,如果信号源内阻高,最好在ADC前面加一级运放缓冲,或者使用大一点的采样电容搭配合理RC。很多初次接触SAR ADC的工程师,拿到AD7680测不准数据,第一反应是怀疑芯片坏了,最后查来查去,发现是输入驱动没做好。
2.3 低压低功耗:2.3V到5.5V的适用性
支持2.3V到5.5V的宽供电范围,这是AD7680一个很大的实用亮点。现在大量嵌入式系统主电源是3.3V,也有不少电池供电设备工作电压在2.5V到4.2V之间,这颗芯片可以直接挂在这些电源轨上使用,省掉了额外生成基准电压的麻烦。
功耗方面,AD7680的典型功耗在毫瓦级别甚至更低。在100kSPS满速跑的时候耗电也不大,如果采用间歇采样或者待机模式,功耗还能进一步压下去。这一点特别适合便携式仪表和电池驱动的数据记录仪,长时间挂机采集的时候,功耗优势会直接体现在续航里。
还有一个容易被忽略的点是AD7680内部带有自己的转换时钟,外部主控只需要提供SPI读取用的SCLK时钟。转换过程本身不依赖SCLK来计时,这样SCLK上的时钟抖动不会直接影响转换精度,对布线和使用要求都宽松了一些。
2.4 参考电压复用:省出来的BOM与引入的挑战
AD7680有个特别有意思的设计:它的输入范围直接做到0到VDD,基准电压的参考源也取自VDD。也就是说,这颗芯片并没有单独的参考电压引脚,电源电压同时充当了参考电压。这样设计最大的好处是省掉了一颗独立基准源芯片和相关去耦电路,BOM成本降低了,电路结构也简单了很多。
当然,任何简化都是有代价的。参考电压等于电源电压,就意味着电源上的任何纹波都会以参考电压的形式直接进入转换结果。如果你用的是DC-DC供电,开关频率附近如果有几十毫伏的纹波,16位精度很容易被打回原形。实际设计中我通常会在VDD前面加一级低噪声LDO,或者至少用合适的磁珠配合大电容把DC-DC的高频毛刺隔离掉,再给AD7680供电。
3. 硬件设计:从电源去耦到PCB布局的关键细节
3.1 电源与参考电压的去耦方案
对于AD7680来说,VDD既是电源也是参考源,去耦设计属于重中之重的环节。常规做法是先在VDD引脚附近放一个10μF左右的钽电容或陶瓷电容,稳住低频能量,再用一个0.1μF的低ESR陶瓷电容紧贴芯片电源引脚,解决高频阻抗。陶瓷电容建议选X7R或C0G材质,容值受温度和电压影响小,不容易出现“标称10μF实际只有几μF”的尴尬情况。
如果系统里同时存在数字电路和模拟电路,我强烈建议把AD7680的电源单独从主电源轨分出来,中间串一个磁珠或者用一个低噪声LDO供电。这样开关电源的高频噪声会被磁珠吸收一部分,LDO再对低频纹波做一次抑制。AD7680这种电源即基准的芯片,你给它喂多干净的电,它就能回你多干净的数据。
还有一个小技巧是:如果你测得的数据低位总是跳动,优先改造电源,而不是盲目加大软件滤波。软件滤波治标不治本,电源脏这个根子不解决,加大滤波窗口只会让系统响应变慢,但底噪还是在。我踩过很多次这样的坑,最后都是回头处理供电才真正解决问题。
3.2 规避时钟抖动与电源噪声的三个PCB布局要点
这部分我直接给出三个经过多次验证的PCB布局要点,照做能省掉很多后期调试时间。
第一,模拟地与数字地单点连接。AD7680的AGND和DGND引脚要分别走线到“同一个”地平面汇合点,而不是让数字电流绕一大圈从模拟区域回流。一个实用的做法是在ADC芯片下方开一个干净的地岛,所有模拟地线上到地岛,然后通过一个狭窄的通道和数字地连接,相当于只留一个汇流点,这样数字开关噪声就不会在整个地平面到处乱窜。
第二,SPI信号线一定要和模拟输入、参考走线拉开距离。SCLK边沿很陡,上升下降过程中会产生很强的容性耦合,如果SCLK长时间贴着输入信号线平行走线,几毫米的长度就能把毛刺耦合到模拟端。实在无法避开的时候,可以在SCLK和模拟线之间铺一条接地铜皮做隔离。
第三,去耦电容和RC滤波电容的回路面积要尽量小。每个电容的地端应该就近打过孔到地平面,不要绕远路。回路面积小,则环路天线效应弱,外部电磁干扰不容易被收进来;反之,即使电源本身干净,回路面积大了也照样能把噪声采进来。我见过一些板子,明明电源滤波做得很好,最后因为电容摆放太远,高频干扰把16位精度直接拉垮,改成贴近引脚后立刻恢复正常。
3.3 输入驱动电路与RC滤波取值
AD7680的输入属于典型的SAR型输入结构,采样瞬间会产生一个瞬态反冲,然后靠RC网络里的电容把电压稳定住。通常设计是在ADC输入端前面加一个RC低通滤波器,再接一颗运放做缓冲。
RC滤波的取值要在噪声抑制和信号建立之间找平衡。R选得太大会拉长建立时间,特别是在采样窗口比较短的场景下容易出问题;R选得太小,过滤高频噪声的能力又会变弱。实际项目中常见的组合是R取几十欧到几百欧,C取1nF到10nF,然后在具体采样率下根据数据手册推荐的驱动电路去仿真验证。如果信号本身是电池电压这样变化很慢的信号,R和C可以稍微取大一点,因为对带宽的要求不高。
运放的作用不能省。用轨到轨输出、单位增益稳定的运放做电压跟随器,把传感器或前级电路的输出阻抗降下来,然后再驱动ADC输入端,这样ADC的采样反冲由运放来承担,信号源本身不会被干扰。带隙基准、热电偶这类高阻信号源,如果直接接到AD7680上,基本不可能得到稳定的16位数据。
3.4 多通道复用时要注意的串扰问题
如果AD7680前面接了模拟开关或者多路复用器,比如用一片8选1模拟开关来轮流采集8路电压,就要特别注意通道间的串扰。SAR ADC采样瞬间会有反冲电流,从这个通道的采样电容反向流向信号源,如果各路共用一个前端,很容易把这个反冲串到相邻通道上,导致测量结果互相污染。
解决办法有两个方向。一是每个通道都部署独立的RC滤波网络,让反冲电流先被本通道的电容吸收,不至于到处乱跑;二是软件上在切换通道之后特意丢弃第一次或前两次转换结果,等前端稳定后再读取有效值。这两招配合使用,多通道采样的首点毛刺基本能解决。对BMC或者电源监控这类需要轮询多路电压的系统,这个经验尤其有价值。
4. 软件驱动:SPI时序、校准与滤波的落地实现
4.1 读懂AD7680的SPI读取时序
AD7680的串行接口和教科书版的SPI不完全一样。它不需要复杂的寄存器配置,每次转换就是把CS拉低,然后用SCLK把数据从SDO引脚一位一位读出来。问题是具体的数据位排列、CS拉低的时机、SCLK是上升沿采样还是下降沿采样、一次完整转换需要几个时钟周期,这些都藏在数据手册的时序图里。
我吃过一次亏,第一版固件按普通SPI模式读写,结果读回来的数据总是不对。后来用示波器抓了CS、SCLK和SDO三根线,发现我的片选时机提前了整整一个时钟周期。所以拿到这颗芯片,第一件事建议先写一个最简单的循环读取代码,每次CS拉低、读16位、CS拉高,把数据打印出来,再和输入电压比一比。
用MCU的硬件SPI外设去对接时,需要根据手册帧格式选模式。如果帧格式特殊,硬件SPI不好配合,用GPIO模拟时序可能更省心。100kSPS的吞吐率下,GPIO模拟SPI的速度完全够用,而且时序可控性更强,调试起来也比较直观。
4.2 采样周期、转换周期和BUSY的正确处理
SAR ADC启动一次转换后,需要等待一个固定的转换时间,之后才能安全地读取结果。AD7680没有独立的EOC引脚,但有一个机制:在转换进行期间,SDO会维持一个忙状态电平,等转换完成后才返回可以正常读数的状态。更准确的说法要看手册里具体的帧格式,不同CS工作模式下表现会有差异,但一个共同点是:你必须在正确的时隙里给SCLK,读到的数据才有效。
软件上最容易犯的错是刚拉低CS就去读,芯片还没转换完,SDO上根本没有有效数据,读回来的只是乱码或者上一位的残留。实际工程经验是:在输出SCLK之前,先预留足够的延时,或者通过查询SDO状态来判断转换是否结束。Stm32这类MCU上用硬件SPI时,如果DMA访问总线太急,也可能在转换还没完成时就把数据采走了,所以用DMA读AD7680时,要对DMA启动时机和CS时序做仔细规划。
4.3 用三点校准修正系统误差
任何ADC都有失调误差、增益误差,外部还有电阻分压误差和参考电压偏差。两点校准可以修正一条直线,但它假设ADC和前端电路是完全线性的,现实里并不是这样。如果你想在某个量程内榨出更好的精度,我推荐用三点校准。
三点校准的做法:分别给ADC输入三个已知电压,比如零点、满量程附近、中间某个电压,把对应的ADC原始读数记下来。然后做分段线性插值,把原始码映射成修正后的实际电压值。当采样值落在第一段时,用第一个点和第二个点连线去计算;当采样值落在第二段时,用第二个点和第三个点连线去计算。
这套校准方法对16位ADC很适用,因为它的非线性通常比较平缓,用三段折线去逼近已经能获得比较理想的效果。尤其当你通过电阻分压把高电压降到ADC量程内,分压电阻本身有精度误差和温漂,软件校准几乎是必须做的一道工序。需要注意的是,校准只对你固定的采样链路有效,改变量程电阻、参考电压或换了运放之后,要重新校准。
4.4 几段C语言滤波代码的实战选择
AD7680输出的16位原始数据在没有任何滤波的情况下,总会带一点白噪声。我之前做过一个采集板,最后数据低两位一直跳,后来用滑动平均把噪声压了下去。下面这段是嵌入式里最常用的滑动平均滤波代码,适合有实时性要求但不希望信号滞后的场景。
#define ADC_FILTER_LEN 16 static uint16_t buf[ADC_FILTER_LEN]; static uint32_t sum = 0; static uint8_t idx = 0; uint16_t adc_filter(uint16_t new_val) { sum -= buf[idx]; sum += new_val; buf[idx] = new_val; idx = (idx + 1) % ADC_FILTER_LEN; return (uint16_t)(sum / ADC_FILTER_LEN); }注意累加变量必须是uint32_t,因为16个16位数据的最大累加值接近1,048,560,已经超过uint16_t的范围了。窗口长度16意味着系统响应会有一定滞后,如果你需要快速响应,可以把窗口缩短到8;如果噪声很大,可以加长到32,具体在滞后和噪声之间做取舍。
还有一种常用的一阶低通滤波,代码更短,延迟更可控。
static float filtered_val = 0.0f; float adc_lpf(float new_val, float alpha) { filtered_val += alpha * (new_val - filtered_val); return filtered_val; }alpha一般取0.1到0.5之间。值越小滤波越强,但响应越慢;值越大响应越快,但噪声抑制变差。实际使用的时候我习惯先把ADC原始码转成实际电压值再滤波,这样alpha的含义也更直观。想再稳一点,还可以先用中位滤波剔除异常毛刺,再做一次滑动平均,对付工业现场脉冲干扰效果很好。
5. 应用场景与选型建议
5.1 哪些项目更适合外扩AD7680
外扩一颗AD7680最典型的理由是“内置ADC不够用,但Σ-Δ又太慢太复杂”。比如便携式红外测温仪,传感器输出电压需要精确放大后用16位精度采样,MCU内置12位ADC的量化噪声太大,Σ-Δ型的转换延迟又会让测温响应变慢,这时候AD7680这种100kSPS、无延迟的SAR ADC就非常合适。
再比如电源管理里的电压监控,BMC通过外部ADC读取多路电压时,通常需要够快的采样速度和不错的精度,同时功耗还不能大。用AD7680配一个模拟开关做轮询,既能保证精度,又不会占太多主控资源。还有电池内阻测试、称重传感器前端、精密仪器仪表后端采集,这些都是很典型的应用。
如果系统的采样率只需要每秒几十次,信号又是缓变类型,那我可能更倾向于推荐Σ-Δ ADC,而不是AD7680。选型不能只看分辨率,还得看你的信号特性和实时性要求。
5.2 AD7680与内置ADC、Σ-Δ ADC的对比
这里把三类常见的ADC放在一张表里对比,方便选型。
| 项目 | AD7680这类SAR ADC | MCU内置12位ADC | Σ-Δ ADC |
|---|---|---|---|
| 分辨率 | 16位,精度明显更高 | 12位,常规够用 | 16~24位,超高精度 |
| 转换方式 | 逐次逼近,一次转换即完成 | 逐次逼近或过采样 | 过采样+数字滤波 |
| 输出延迟 | 无延迟,适合多路复用 | 较低,具体看MCU实现 | 有群延迟,不适合快速切换信号 |
| 功耗 | 毫瓦级甚至更低 | 较低 | 相对较高 |
| 外围需求 | 需要干净电源和输入驱动 | 集成度高,但精度受限 | 需要高性能时钟和数字滤波算法 |
| 适合信号 | 快速变化、多通道轮询 | 常规控制和简单采集 | 低频高精度,如称重、温控 |
做项目时我会这样选:信号频率高、要多通道扫描、精度要求16位左右,用SAR;信号变化慢、对精度要求极苛刻、可以接受延迟,用Σ-Δ;只是做个阈值检测或者简单显示,直接拉个MCU内置ADC就行,但别指望它测微伏级信号。
5.3 常见问题排查速查表
做AD7680周边设计时,有几个问题出现的频率特别高,我整理成速查表,方便你定位。
| 现象 | 可能的根因 | 处理方式 |
|---|---|---|
| 读回数据全是0或者满量程 | SPI时序不对、输入电压超出范围、CS控制错误 | 用示波器抓CS/SCLK/SDO波形,对比手册时序图;检查VDD与输入电压 |
| 低几位持续跳动 | VDD纹波大、参考噪声高、输入源阻抗过大 | 加强VDD去耦、串磁珠或加LDO;增加RC滤波,必要时加运放缓冲 |
| 数据随温度明显漂移 | 参考电压温漂、分压电阻温漂、运放失调温漂 | 使用低温度系数电阻和低温漂基准;软件定时校准 |
| 多通道切换后第一个点异常 | 采样建立时间不够、通道间串扰 | 丢弃首点数据、增加前端RC建立时间、通道间用独立RC滤波 |
| 读数有周期性突变 | 开关电源纹波耦合、数字总线噪声 | 检查VDD纹波、重新布局SPI走线、模拟区域与数字区域隔离 |
如果问题不在上表里,最直接的排查办法是先短接ADC输入端到GND,看读数是否稳定在零点附近;再把输入端接到VDD,看是否稳定在满量程附近。两步都正常,问题大概率在前端电路;两步不正常,再回头查供电和时序。
做AD7680这类外置SAR ADC的驱动,我个人的体会是不要试图把软件滤波当成万能补丁。电源做干净、参考电压稳住、输入阻抗匹配好,这三件事做好,数据自然就漂亮了。好多时候我一开始怀疑软件写得不对,最后发现都是硬件细节埋了雷。如果你正准备拿这颗芯片做设计,建议先把供电和输入驱动想清楚,再写代码,这样能省下大量的调试时间。等这一套流程走顺了,再去看更大分辨率的Σ-Δ ADC或者更高速度的SAR ADC,你会发现整个模拟设计的方法论都是通的。