ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

STM32 ADC电压采集不准?分压电阻与采样时间的RC建立时间分析

STM32 ADC电压采集不准?分压电阻与采样时间的RC建立时间分析 先说个我自己的经历。有次做一块电池电压采集板STM32F103 的 ADC 直接测 12V 电池分压电阻随手按越省电越好选了 2MΩ 510kΩ结果读数一直在 11.5V 到 12.6V 之间跳怎么都稳不下来。当时还怀疑是电池波动换高精度万用表一测人家纹丝不动。后来用示波器戳 ADC 引脚才看清楚每次采样的瞬间引脚电压直接塌陷了一截问题就出在分压电阻输出阻抗太高而代码里只给了 1.5 周期的采样时间。这篇东西把 STM32 ADC 电压采集里分压电阻选择不当导致误差这条线完整讲透包括采样保持电路的原理、RC 建立时间怎么算、高阻值/低阻值/温漂这三类典型坑最后给出一套从选型到软件校准再到实测验证的完整流程。适合正在做电池电量检测、工业模拟量采集、仪器仪表项目的开发者也适合刚把 F103 跑通、想往深处看 ADC 机制的学生。1. 先搞懂分压电阻是怎么坑了 ADC 的采样保持与 RC 建立时间很多人以为 ADC 误差只来自基准电压和分辨率实际上分压电阻和 STM32 内部采样保持电路之间的相互作用才是隐藏在读数不准背后的头号元凶。1.1 ADC 量化只是最后一步采样保持才是误差源头STM32 内部是逐次逼近型SARADC转换过程分两阶段采样阶段把输入电压捕获到内部采样电容上保持阶段再把电容上的电压交给比较器逐个比特逼近量化。电容上存住的电压如果和实际输入不一致后面量化环节做得再精确也没用因为源头就是歪的。采样阶段在电路上的表现相当于一个模拟开关闭合外部信号源通过开关给采样电容充电。STM32F103 典型采样电容在 4pF 左右内部模拟开关导通电阻约 1kΩ。看起来参数不大但一旦外部源阻抗主要是分压电阻网络达到几十甚至几百千欧充电时间就被拉得非常长。这里最容易误解的地方是很多人觉得电压最终总会充满。理论上是这样但 SAR ADC 的采样窗口是固定且有限的。窗口关闭时电容上的电压如果没充到足够接近输入电压这部分差值就直接变成了转换误差。这个窗口由采样时间决定而大多数人恰恰忽略了采样时间的配置。1.2 分压器输出阻抗和采样电容构成的一阶 RC 等效模型分压电阻网络从 ADC 引脚往回看可以等效成一个电压源串联一个电阻。这个等效电阻就是分压器输出阻抗输出阻抗 Rout R1 × R2 / (R1 R2)也就是上臂和下臂电阻的并联值。这} 值才是决定采样误差的关键而不是单个电阻的阻值大小。比如 100kΩ 上臂配 10kΩ 下臂输出阻抗大约是 9.09kΩ2MΩ 配 510kΩ输出阻抗大约 406kΩ。两者差了四十多倍对采样建立时间的影响是数量级的。充电过程符合一阶 RC 响应公式Vc(t) Vin × (1 - e^(-t/τ))其中 τ (Rout RAD) × CAD。RAD 是内部模拟开关电阻CAD 是采样电容。把这些参数乘起来就得到时间常数它决定了引脚电压向实际输入电压逼近的速度。1.3 建立时间到底要多少一个计算示例以 STM32F103 为例ADC 满量程 3.3V12 位分辨率1LSB 3.3V / 4096 ≈ 0.806mV。如果要保证量化误差小于 0.5 LSB那么采样结束瞬间电容电压和输入电压的误差必须小于 0.403mV。假设分压网络输出阻抗 25kΩ比如上臂 200kΩ、下臂 28.6kΩ 的分压结构加上内部开关电阻 1kΩ采样电容 4pF时间常数 τ 26kΩ × 4pF 104ns。12 位 ADC 建立到 0.5 LSB 需要的时间是 t τ × ln(2^13) ≈ 104ns × 9.01 ≈ 937ns。如果代码里把采样时间配成 1.5 周期ADC 时钟 12MHz 下就是 125ns只有需要的 13%。用一阶公式算一下误差比例e^(-125/104) ≈ 0.30意味着采样结束瞬间电容电压只有目标值的七成左右换算到 3.3V 满量程误差高达 0.7V这已经不是毫伏级误差而是完全不可用。就算把采样时间提升到 7.5 周期625ns误差比例仍然有 e^(-625/104) ≈ 0.0025约 8mV折合 10 个 LSB。只有把采样时间拉到 239.5 周期约 19.96μs误差才能忽略不计。这个计算解释了为什么同样一块板子采样时间从 1.5 周期改成 239.5 周期之后读数忽然就准了。不是玄学是 RC 建立时间的数学结果。2. 我踩过的三个典型坑高阻值读数飘、低阻值发热烫、温漂起来结果全跑偏原理归原理实际项目里分压电阻的问题通常表现出完全不同的症状。下面这三个坑是我在多个项目里轮番踩过、也帮别人排查过多次的典型场景。2.1 坑一分压总阻值过大读数偏高且不断跳动去网上搜STM32 ADC 电压采集 跳动十个里面有八个是高阻值分压引起的。阻值动不动就是 1MΩ、2MΩ 级别理由是省电——没错静态功耗确实低了但代价是输出阻抗被推到几百千欧采样建立时间根本不够。这类故障有非常典型的表现用示波器测 ADC 引脚会看到采样开始瞬间引脚电压被拉出一个明显的凹陷然后缓慢回升但采样窗口已经关了相邻两次采样读到的值之间还有周期性波动因为引脚上耦合的工频噪声没有被足够低的源阻抗压制住随机干扰叠加在缓慢回升的斜坡上。这里要专门批一个经常在网上看到的馊主意在 ADC 引脚并联一个 0.1μF 电容就能滤除噪声。在低源阻抗场景下这个做法勉强有效但高阻值分压网络后面直接并联大电容问题会更严重。原理很简单采样瞬间内部电容会从外部大电容借电荷而大电容本身也是通过高阻值的分压网络充电的一旦被采样吸走一部分电荷在采样窗口内根本来不及通过分压电阻补充回来。结果就是引脚电压整体被拉低每次采样结果偏低而且还有残留电荷导致的非线性。如果在高阻值分压后面一定要加滤波电容正确做法是先加运放缓冲器再用低阻抗输出驱动力大电容和 ADC 引脚。没有缓冲器的情况下电容取值不要超过几百皮法同时采样时间必须按源阻抗和总电容重新计算。2.2 坑二总阻值过小功耗和自热问题反噬精度有些工程师看到源阻抗要低这句话就直接把分压电阻选成几百欧结果带来了另外一类问题。用 1kΩ 1kΩ 分压测 24V静态电流 12mA总功率 288mW两个 0805 封装电阻表面温度轻松超过 80°C烫得手指不能按上去。温度升高之后电阻阻值本身按照温漂系数发生变化。普通厚膜电阻温漂在 100ppm/°C 到 200ppm/°C温度上升 50°C阻值变化 0.5% 到 1%。也就是说为了降低源阻抗而引入的自热效应反而制造了一个比源阻抗误差更大的温度漂移误差源。更加隐蔽的问题是自热改变了上下臂电阻的温度梯度。分压电阻两只电阻散热条件往往不同比如上臂靠近发热器件、下臂紧贴大面积铺铜两者温度不一致即使标称温漂系数相同实际温漂也不匹配分压比就会随温度产生明显偏移。这类故障表现为刚上电时读数准确运行几分钟后数值缓慢漂移最终稳定在一个带固定偏差的值上。如果你发现设备开机准、越用越不准优先怀疑分压电阻自热和温漂。2.3 坑三温漂与上下臂失配温度场一变结果全跑偏温漂问题在户外设备或者温度跨度大的环境里尤其突出。分压比由两个电阻共同决定Vout Vin × R2 / (R1 R2)。如果 R1 和 R2 按相同比例漂移分压比其实还能保持不变但上下臂选用不同材料、不同封装、不同功率等级环境变化时两个电阻的温漂往往不一致分压比就跟着温度跑了。实际例子某设备用 75kΩ 和 10kΩ 分压上臂选了厚膜 1% 电阻下臂选了精密薄膜 0.1% 电阻。常温下标定没问题环境温度从 25°C 升到 55°C厚膜电阻按 150ppm/°C 漂移10kΩ 薄膜电阻按 25ppm/°C 漂移分压比变化率就有约 1% 的差距。对 12 位 ADC 来说这个误差相当于 40 个 LSB远超系统允许范围。选分压电阻的核心原则不是两只都要高精度而是两只必须同材料、同系列、尽量同温度系数让分压比对温度不敏感。两个 0.1% 25ppm 的金属膜电阻配对使用往往好过一个 0.1% 加一个 1% 的组合。故障表现根因快速判断方式读数偏高、跳动、不稳输出阻抗过高采样时间不足示波器测 ADC 引脚采样瞬间有凹陷读数偏低、长时间运行后漂移分压电阻过小导致自热阻值温漂触摸电阻温度明显偏高温度变化时读数系统性偏移上下臂温漂系数不匹配高低温箱或吹风机加热/降温对比读数3. 分压电阻选型实操从分压比算到温度系数的一整套流程避开这些坑的关键在于设计阶段就把参数定清楚。下面这套流程我在多个项目里用过基本可以直接照搬。3.1 第一步确定量程和分压比先确定被测电压最大值和 ADC 参考电压通常 3.3V。不要把满量程压得太满留出 20% 的裕量有利于后续校准和防止电压波动越界。比如测 0~24V按 3.0V 满量程计算分压比为 3.0 / 24 1/8。这时候下臂占比就是 1/8上臂占比 7/8选标称阻值时取近似组合就行。分压比的计算虽然简单但有一个细节容易忽略下臂电阻不是越大越好也不是越小越好它和上臂阻值共同决定了输出阻抗。在分压比固定的情况下两只电阻等比放大静态电流减小但输出阻抗同步变大等比缩小则相反。这一步的关键是后续在功耗、输出阻抗、采样时间三者之间找平衡。3.2 第二步根据应用场景定总阻值范围总阻值范围完全取决于系统是电池供电还是市电供电、采样频率要求多高、有没有运放缓冲。有运放缓冲的场景分压电阻可以放开手选大阻值因为运放输入阻抗极高几乎不从分压网络取电流输出端又能提供很低的阻抗给 ADC。此时 100kΩ 级别甚至 1MΩ 级别的分压电阻完全可用功耗问题也被化解。需要注意的是运放自身的输入偏置电流、失调电压、轨到轨输出能力这些指标会成为新的误差源。没有运放缓冲、直接接 ADC 的场景总阻值控制在 10kΩ 到 100kΩ 之间相对安全。低于 10kΩ 功耗偏大高于 100kΩ 需要把采样时间配置得很长才能保证精度。一个比较稳的起步值是上臂 75kΩ、下臂 10kΩ分压比 10/85 约等于 0.1176输出阻抗约 8.8kΩ配合 239.5 周期采样时间在 12MHz ADC 时钟下能建立得很干净。3.3 第三步精度和温漂规格怎么定分压电阻的精度直接决定初始误差上限。1% 精度的分压网络如果上下臂误差方向相反输出电压最多偏 2%对 12 位 ADC 来说就是 80 多个 LSB远超出精密测量的容忍度。做电池电量显示这类对精度要求不高的应用还能凑合但做工业变送器、测量仪表或者电化学传感器采集至少要用 0.1% 精度。温漂规格的优先级甚至比初始精度更高。初始精度可以通过软件校准消除但温漂是动态变化的软件校不掉。常规选择是 25ppm/°C 或更好的电阻温度变化 40°C 时阻值偏移只有 0.1%。上下臂尽量购买同批次同系列电阻或者直接用排阻/电阻网络组件这类元件内部配对一致性远好于两粒独立电阻。3.4 第四步滤波电容、保护器件和运放缓冲的取舍分压网络和 ADC 引脚之间如果需要加滤波电容取值必须和采样时间一起计算。经验做法是不加运放时滤波电容取 1nF 以下加了运放之后可以放宽到 100nF 甚至更大但运放输出到 ADC 引脚之间要留一个 100Ω 到 1kΩ 的串联电阻防止运放驱动大电容发生振铃。如果被测电压来自外部接口或者连接线可能被短路、插错ADC 引脚前必须加保护。串联一个 1kΩ 到 10kΩ 的限流电阻配合输入的钳位二极管或者一个双向 TVS 管可以有效防止高压直接冲击 MCU 引脚。有一类项目出问题是分压电阻开路导致高压直接灌到 ADC 引脚这种场景可以在 ADC 引脚对地并一个 3.3V 稳压管或者 TVS成本几毛钱换来的是一块主控板的命。应用场景总阻值范围分压电阻精度温漂指标是否加运放电池供电/待机态低功耗100kΩ ~ 1MΩ0.5%~1%50ppm/°C 以上需校准建议加一般仪器/工业采集10kΩ ~ 100kΩ0.1%~0.5%25ppm/°C 或更好可选高速采样/动态信号1kΩ ~ 10kΩ0.1%25ppm/°C 或更好强烈建议高精度基准型应用按运放要求0.05%~0.1%5~10ppm/°C必须加4. 软件侧补救和实测验证采样时间、校准和用数据说话的排查思路硬件定型后软件配置和校准同样能救回一部分精度。这部分内容如果你已经踩了坑可以直接照着改。4.1 采样时间配置先怼到最大再按实测下调STM32 的采样时间寄存器提供了多挡配置从 1.5 周期到 239.5 周期不等。调试阶段不要折磨自己直接配成最大采样时间跑一轮测量看误差水平。如果最大采样时间下读数稳定且精度符合要求再逐步减小采样时间直到精度临界点然后回退一挡留出余量。CubeMX 中 ADC 配置里可以直接选择采样时间HAL 代码如下ADC_ChannelConfTypeDef sConfig {0}; sConfig.Channel ADC_CHANNEL_1; sConfig.Rank ADC_REGULAR_RANK_1; sConfig.SamplingTime ADC_SAMPLETIME_239CYCLES_5; // 12MHz 下约 19.96us HAL_ADC_ConfigChannel(hadc1, sConfig);采样时间变长意味着单个通道转换周期变长多通道扫描时的总吞吐率会下降。高阻抗分压网络和高速采集是天然矛盾的如果你既要高源阻抗省电、又要多通道高速采集唯一出路是加运放缓冲而不是和采样时间较劲。4.2 过采样和数字滤波的适用范围STM32G4 系列自带硬件过采样可以把 12 位 ADC 的有效精度推到 16 位。F1 系列没有硬件过采样可以软件实现连续采样 16 次求平均等效提高 4 位有效位数代价是吞吐率降为原来的 1/16。数字滤波要分清场景。对稳定的直流电压采集滑动平均加中值滤波非常有效能干掉大部分随机噪声但对快速变化的动态信号过度滤波会把信号本身的瞬态抹平。实际项目中我通常先做粗大误差剔除——连续采 5 次去掉最大最小值再平均这种去极值平均方案实现简单对尖峰脉冲干扰有很强的抑制能力。4.3 两点校准和分段线性化分压电阻的初始误差、ADC 的失调误差和增益误差可以通过软件校准一次性补偿。做法很简单用精密可调电源输出两个已知电压记下 ADC 读得的原始值然后按线性插值计算。比如输入 1.00V 时 ADC 读数为 1240输入 3.00V 时 ADC 读数为 3715那么任意读数 D 对应的实际电压为V (3.00 - 1.00) / (3715 - 1240) × (D - 1240) 1.00这套两点校准能同时补偿比例误差和偏置误差。如果 ADC 在全量程内非线性明显可以做多点校准然后分段线性插值。对大多数应用来说3 到 5 个校准点已经能把误差压到一个很低的水平。校准完的系数要存到片内 Flash 或者外部 EEPROM 里掉电不丢失。需要提醒的是校准只能修正固定误差补偿不了温漂。如果你的板子工作温度范围很宽得做高低温下的二次校准或者选用超低温度系数的电阻从硬件上把温漂压下去。4.4 实测验证从故障现象倒推原因的一套排查链路遇到 ADC 读数不准的问题按下面这套链路排查比盲目改软件效率高得多第一步先用示波器看 ADC 引脚波形。如果采样瞬间有明显的电压跌落基本可以断定是源阻抗过高或者采样时间不足。把采样时间调到最大要是跌落消失问题定位在 RC 建立时间上。第二步用手摸分压电阻。如果温度明显高于环境温度说明阻值选得太低、功耗太大。试试把总阻值等比放大十倍再看数据是否有改善。第三步用精密万用表直接量 ADC 引脚的稳态电压。高阻抗数字万用表测出来的电压是最终充好电的值如果这个值本身就不对说明分压网络精度或者温漂有问题需要检查电阻规格。第四步把 ADC 输入短接到 GND 和 3.3V 各测一次。如果两个极值点的读数都不准说明 ADC 自身或者参考电压有问题先把基准源搞定再回来谈分压电阻。第五步对比软件校准前的原始误差曲线。用可调电源从低到高扫描若干个电压点记录 ADC 原始读数的误差分布。如果误差曲线接近一条直线用两点校准即可消除如果误差曲线呈现明显的弯曲就要怀疑分压电阻的非线性、PCB 漏电或者采样建立残留。我在实际项目里试过一组对比实验同一块板子分压电阻从 470kΩ 级别换成 20kΩ 级别采样时间从默认 1.5 周期改成 239.5 周期误差从 ±3.5% 直接降到 ±0.1% 以内。这个对比很有参考价值——很多时候精度不够不是因为 ADC 差而是前级电路根本没有给 ADC 一个看清楚的机会。拿到一块采集精度不够的板子先别急着怀疑 MCU把示波器探针戳到 ADC 引脚上往往比翻一天数据手册更管用。
返回列表