帖子内容我看到了:楼主只用了一个 100kΩ 和 5kΩ 的限流电阻,没有分压,直接采 4.2V 左右的锂电(MCU 供电 5V,VREF 也是 5V)。这里我先讲清原理,再给具体建议。
一、为什么 5kΩ 也不准 —— 根本原因
手册「两组12位模数转换」的 ADC 静态特性表给出了 ADC 输入的等效模型:
| 符号 |
描述 |
典型值 |
| R_{AIN} |
通道等效电阻 |
∞ |
| R_{ESD} |
采样保持电容前串接的抗静电电阻 |
700 Ω |
| C_{ADC} |
内部采样保持电容 |
16.5 pF |
关键就在这里:R_{AIN} 是 ∞,但 C_{ADC} 只有 16.5pF,前面串了 700Ω 的 R_{ESD}。ADC 采样不是"直接读电压",而是每次采样时把内部 16.5pF 电容和外部信号源连一下,靠充电达到平衡。外部串联电阻越大,充电时间常数越大,如果采样窗口不够长,电容充不到外部电压,转换结果就偏小——这正是楼主看到的"偏小"。
手册在 ADC_CONTR 寄存器处专门写了这条(原文):
2、适当加长对外部信号的采样时间,就是对ADC内部采样保持电容的充电或放电时间,时间够,内部才能和外部电势相等。
所以**"电阻小就更准"的本质是时间常数小、充得快**,不是 ADC 输入阻抗的问题。
二、采样时间怎么配(这是解决问题的第一步)
手册 ADC1 时序控制寄存器 ADCTIM 的 SMPDUTY[4:0] 决定采样时间,单位是 ADC 时钟数,且原文明确要求:
注意:SMPDUTY一定不能设置小于01010B
| SMPDUTY[4:0] |
ADC时钟数 |
| 01010 |
11(默认值) |
| 11111 |
32(最大) |
要采大内阻信号,把 SMPDUTY 设到最大 11111B(32 个 ADC 时钟),这是最容易见效的一步。同时 ADC 时钟不要设太快(ADC 时钟由 ADCCFG 分频,具体分频位请以你所用型号的 ADCCFG 寄存器定义为准)。
三、电阻取值的经验算法(结合手册参数推算)
充电到 1/2 LSB 精度(12 位、VREF=5V,1 LSB ≈ 1.22mV,半 LSB ≈ 0.61mV),需要约 8.5 个时间常数(\ln(5V/0.61mV) \approx 9,取 9 个 τ 更保险)。
时间常数 \tau = (R_{ext} + R_{ESD}) \times C_{ADC} = (R_{ext}+700\Omega) \times 16.5pF
采样窗口 T_{samp} = SMPDUTY \times T_{ADC}
举例(仅用于说明量级,实际请按你的 ADCCFG 分频算):若 ADC 时钟取 1MHz(T_{ADC}=1\mu s),SMPDUTY=32,则 T_{samp} = 32\mu s。
则要求 $9\tau \le 32\mu s → \tau \le 3.56\mu s → R_{ext} \le \dfrac{3.56\mu s}{16.5pF} - 700 \approx 215k\Omega$。
也就是说理论上 215kΩ 以内都能满足 12 位精度。那为什么楼主 5kΩ 都不准?——因为楼主的 ADC 时钟/SMPDUTY 大概率是默认配置,采样窗口远小于上面假设。ADCCFG 若分频到 8MHz 甚至更高,T_{samp} 只有几微秒,5kΩ 都来不及充满。这是需要先检查的第一件事。
⚠️ 以上 τ 计算是我基于手册给出的 R_{ESD}=700\Omega、C_{ADC}=16.5pF 参数做的推导,手册原文并未直接给出"外部电阻上限 215kΩ"这个数字,仅为工程推算,供你参考。实际请以实测为准。
四、工程上真正推荐的做法
方案 A:加采样电容(最推荐,成本 1 分钱)
在 ADC 引脚对地加 0.1μF(100nF) 电容,串联电阻取 1kΩ ~ 10kΩ。
原理:外部电容作为"电荷池",ADC 采样时 16.5pF 内部电容直接和 100nF 外部电容并联均压,100nF 是 16.5pF 的 6000 倍,电压几乎不掉,瞬间充满,对外部串联电阻的敏感度大幅降低。这才是解决"高内阻信号源采不准"的行业通用做法。
同时 100nF 对 DC-DC 的开关噪声是一阶低通,截止频率 f = \dfrac{1}{2\pi R C},R=10k、C=100nF 时约 159Hz,每秒采 1 次的锂电池电压完全不受影响,而开关噪声被压掉。一举两得,正好解决楼主担心的"DC升压模块电感噪声"。
方案 B:分压电阻的取值
测超过 VREF 的电压必须分压。分压网络要给两个数:
- 总阻值:既要满足上面的充电时间(加 100nF 后基本不成问题),又要控制功耗。锂电池系统,总阻值取 100kΩ ~ 1MΩ 均可;若取 2×100kΩ,4.2V 下电流 21μA,功耗 88μW,可接受。
- 在分压中点对地加 100nF 电容(注意:电容接在 ADC 输入脚,即分压中点与地之间),这样分压电阻的高阻不会影响采样精度。
关于"倒灌"问题:楼主最初直连锂电正极导致 MCU 断电时倒灌,串联电阻只能限流不能阻断。正确做法是分压 + 串联电阻 + 100nF,或者用 I/O 控制一个 PMOS 开关来选通采样回路(只在采样瞬间导通),这样平时完全断开,零漏电、零倒灌。
五、给你一份具体建议参数
| 项目 |
建议值 |
理由 |
| 分压上阻 |
200kΩ |
4.2V 下电流 ~21μA |
| 分压下阻 |
200kΩ(中点输出) |
分压比 1/2,4.2V→2.1V,< 5V VREF |
| 分压中点对地电容 |
100nF |
电荷池 + 抗 DC-DC 噪声 |
| ADC 前串联电阻 |
1kΩ(可选) |
与 100nF 组成低通,同时保护 I/O |
| 采样时间 SMPDUTY |
11111B(32 个 ADC 时钟) |
手册允许的最大值 |
| ADC 时钟 |
尽量慢,取 1~2MHz 量级 |
拉长采样窗口 |
| I/O 模式 |
高阻输入(PxM0/PxM1) |
手册明确要求 |
注意手册原文的强制要求:
被选择为ADC输入通道的I/O口,必须设置PxM0/PxM1寄存器将I/O口模式设置为高阻输入模式。
以及上电时序:
给MCU的内部ADC模块电源打开后,需等待约1ms,等MCU内部的ADC电源稳定后再让ADC工作。
这两条不要漏。
六、还需要你确认的信息
- 你用的是哪颗芯片? 上面参数取自 STC32G144K246 手册,不同型号的 ADC 可能有差异(比如 STC8H 有些型号 ADC 是 10 位、C_{ADC} 参数不同),需要按你实际型号核对。
- ADC 时钟和 SMPDUTY 现在设的是多少? 这直接决定 5kΩ 是否够用。
- 分压比:你要测的最高电压是多少?VREF 用的是 VCC 还是内部 1.19V 基准(手册「ADC模数转换」章节提到内部 1.19V 参考信号源,可反推 VCC,也可做高精度基准)?
- 是否需要彻底断电防倒灌(用 I/O 控 PMOS)?
请补充这几点,我可以帮你把参数和寄存器配置一次定下来。
小结:ADC 输入端加了 5kΩ 反而不准,问题不在电阻本身,而在于手册给出的 C_{ADC}=16.5pF 采样保持电容需要足够的充电时间;手册原文明确要求"SMPDUTY 一定不能设置小于 01010B",并且"适当加长采样时间"。正确做法是:SMPDUTY 设到最大 + 分压中点对地加 100nF 电容 + 分压电阻取 100k~1MΩ 级别,这样既解决了精度,又同时抑制了 DC-DC 的开关噪声。纯靠减小串联电阻来"凑准"不是好办法,会白白浪费功耗。
🔍 搜索 "ADC采样电路 电阻取值"
⏱️ 查找用时 9.8s | 总回答用时 14.2s
🔍 搜索 "ADC采样电路 电阻取值 STC单片机"
📌 相关论坛讨论
- 用8H8K64U,精确采样OP 07C放大后,没有问题,请教,互感器放大后,为什么不行?
- ai8051u控制adc采集数据 通讯方法为i2c协议与官方usb通讯
- 请教关于交流电流检测算法如何优化
⏱️ 查找用时 6.6s | 总回答用时 20.6s