找回密码
 立即注册
查看: 691|回复: 19

ADC采样值不正常

[复制链接]

2

主题

7

回帖

2023

积分

金牌会员

积分
2023
发表于 2026-8-22 10:05:48 | 显示全部楼层 |阅读模式
一批主控STC8H8K64U-45I-LQFP32的板子,
ADC10端口采集电池电压,
多数正常(电压降低,采集值降低),
少数采集值异常(电压降低,采集值升高)。
无标题1.png
无标题2.png
无标题3.png
回复

使用道具 举报 送花

9

主题

772

回帖

5311

积分

论坛元老

积分
5311
发表于 2026-8-22 10:23:39 | 显示全部楼层
分压电阻阻抗太高,跟滤波电容形成的RC滞后过大,如果电池电压变化过快,采样也快的话,可能引起错误值,建议减少电容容量,加个跟随器做缓冲,用软件滤波来抗干扰.
回复

使用道具 举报 送花

2

主题

7

回帖

2023

积分

金牌会员

积分
2023
 楼主| 发表于 2026-8-22 10:40:40 | 显示全部楼层
网*** 发表于 2026-8-22 10:23
分压电阻阻抗太高,跟滤波电容形成的RC滞后过大,如果电池电压变化过快,采样也快的话,可能引起错误值,建议减 ...

大电阻是为了省电。现在的问题是稳定电压的采样值异常(示波器能检测adc端口电压值变化),而且是批次差异。我只是想知道芯片内部是怎么处理的,什么情况能导致这种状态变化。
回复

使用道具 举报 送花

已绑定手机

11

主题

484

回帖

1362

积分

金牌会员

积分
1362
发表于 2026-8-22 10:54:03 | 显示全部楼层

软件稍微修改一下。
/*-------------------------------------------------------
  初始化ADC
--------------------------------------------------------*/
void ADCInit()
{        //ADC 控制器  电源  启动  完成  --  15通道模拟输入选择位
        //ADC_CONTR    B7    B6    B5   B4   B3   B2   B1   B0
        P_SW2 |= 0x80;                  //打开扩展存储器
        ADCTIM = 0x3f;                  //设置 ADC 内部时序
        P_SW2 &= 0x7f;                  //关闭扩展存储器
        ADCCFG = 0x2f;                  //设置ADC结果右对齐,速度为1/32系统时钟
        ADC_RES=0;                      //清除ADC_RES存储器以前的结果
        ADC_RESL=0;                     //清除ADC_RESL存储器以前的结果
        ADC_CONTR=0x80;                 //ADC 开启电源
        delayms(1);                     //上电延时1ms
}
/*----------------------------
        读取ADC结果
----------------------------*/
int ADCRead()
{
        ADC_CONTR|=0x4a;                //启动转换ADC10通道1100 1010
        _nop_();_nop_();                //小延时
        while (!(ADC_CONTR & 0x20));    //等待ADC转换完成标志置位
        ADC_CONTR &=~0x20;                  //清完成标志
        return ADC_RES<<8|ADC_RESL;     //返回十位ADC结果
}

回复

使用道具 举报 送花

已绑定手机

7

主题

445

回帖

6692

积分

论坛元老

积分
6692
发表于 2026-8-22 10:57:00 | 显示全部楼层
"采样值异常(示波器能检测adc端口电压值变化)"意思是示波器已经能看出电压异常了?
示波器探头接口输入阻抗不小,会影响电压,这个要注意.
具体电压是多少?ADC值多少?建议从0~15V测一组实际电压与ADC值,列个表看看数据,看能否找出规律.
回复

使用道具 举报 送花

9

主题

772

回帖

5311

积分

论坛元老

积分
5311
发表于 2026-8-22 10:58:21 | 显示全部楼层
ggq*** 发表于 2026-8-22 10:40
大电阻是为了省电。现在的问题是稳定电压的采样值异常(示波器能检测adc端口电压值变化),而且是批次差 ...

单片机ADC管脚即使是高阻状态,内阻也有限,而且一致性很差,外部分压电阻阻值过大的话,内阻影响相不可忽视,电阻过大温漂也大,量产一致性肯定受影响.
回复

使用道具 举报 送花

已绑定手机

11

主题

484

回帖

1362

积分

金牌会员

积分
1362
发表于 2026-8-22 11:02:03 | 显示全部楼层
ggq*** 发表于 2026-8-22 10:40
大电阻是为了省电。现在的问题是稳定电压的采样值异常(示波器能检测adc端口电压值变化),而且是批次差 ...

如果为了省电,可以用一个空闲IO置高电平经过小一点的分压电阻采样,采样结束这个IO置低电平。测量结果可能有差值,补偿一下即可。测电池电压不必密集采样。
回复

使用道具 举报 送花

已绑定手机

872

主题

1万

回帖

2万

积分

管理员

积分
25432
发表于 2026-8-22 11:16:32 | 显示全部楼层
截图202608221116299604.jpg
回复

使用道具 举报 送花

已绑定手机

872

主题

1万

回帖

2万

积分

管理员

积分
25432
发表于 2026-8-22 11:16:57 | 显示全部楼层

我已经获取了 STC8H 手册中关于 ADC 的详细资料。现在结合论坛帖子内容和用户提供的图片(原理图+代码),来综合分析这个问题。

让我先分析一下用户代码中的几个关键问题,然后结合论坛讨论和手册内容给出完整解答。

让我再确认一下论坛帖子的关键信息,以及结合手册中 ADC 的电气特性来做深入分析。

我已经获得了足够的信息来回答。让我整理一下这个 ADC 采样值异常的问题分析。


STC8H8K64U ADC 采样值异常问题分析

我结合了你提供的原理图、代码以及**论坛帖子(thread-25361)**的讨论,从 STC8H 手册的电气特性和寄存器规范出发,为你做一次深入分析。

一、你提供的代码中存在的关键问题

问题 1:ADC 时钟频率设置过高(最可能的原因)

ADCCFG = 0x2f; //设置 ADC 时钟为系统时钟/2/16/16

你注释写的是"系统时钟/2/16/16",即 SPEED = 0x0F(1111B),F_ADC = SYSclk/2/16。

手册明确说明:STC8H 系列 ADC 最高速度为 12 位 800K、10 位 500K。如果你的系统时钟是 40MHz(外部 40MHz 晶振):

  • F_ADC = 40MHz / 2 / 16 = 1.25MHz

这个频率已经超过了 12 位 ADC 的 800K 上限,属于超频使用,会造成采样值不稳定、批次一致性差。手册的 ADC 静态特性表中,采样保持电容为 ​C_{ADC}=16.5pF,前端还串接抗静电电阻 ​R_{ESD}=700\Omega,采样时间不足时内部电容根本来不及充满电。

问题 2:I/O 口模式未设置为高阻输入

手册明确要求:

被选择为 ADC 输入通道的 I/O 口,必须设置 PxM0/PxM1 寄存器将 I/O 口模式设置为高阻输入模式。

你图片中 ADC 引脚是 P0.0P0.3 (ADC8ADC11),但代码中没有看到 P0M0/P0M1 的设置。如果这些引脚不是高阻输入,内部上拉/准双向结构会引入额外电流,与外部 1MΩ 大电阻分压网络相互作用,导致采样值偏差——这正是帖子里"批次差异"的根源之一。

二、论坛讨论的核心矛盾点

楼主(ggq***)描述的现象非常关键:

多数正常(电压降低,采集值降低),少数异常(电压降低,采集值升高)。

这在 ADC 上是**反向(反逻辑)**的异常,不是简单的精度误差。结合手册和论坛回复,我梳理出几个方向:

方向 A:外部 RC 完全无法给内部采样电容充电(论坛回复1/5/6 的核心)

你的分压电阻是 R19、R21 = 1MΩ,滤波电容 C14 = 100nF。

  • 手册给出采样保持电容 ​C_{ADC}=16.5pF,前端串 ​R_{ESD}=700\Omega。
  • 外部 1MΩ 电平到 ADC 采样电容之间的等效电路,时间常数极大。
  • 手册在 ADC_CONTR 中特别强调:

    适当加长对外部信号的采样时间,就是对 ADC 内部采样保持电容的充电或放电时间,时间够,内部才能和外部电势相等。

而你的 ADCTIM = 0x3f(SMPDUTY 已经设到最大 31 个时钟),配合 ADCCFG=0x2f 的超快 ADC 时钟 1.25MHz,采样窗口极短,1MΩ 高阻源根本无法在这么短时间内把 16.5pF 采样电容充到外部电平。若外部 100nF 电容也未被充分充电/放电,就会出现采样值不随电压正确变化甚至反向的怪现象。

方向 B:ADC 引脚内部漏电或等效电阻不一致(论坛回复5)

单片机 ADC 管脚即使是高阻状态,内阻也有限,而且一致性很差,外部分压电阻阻值过大的话,内阻影响不可忽视,电阻过大温漂也大,量产一致性肯定受影响。

手册给出的通道等效电阻是 ​R_{AIN}=\infty(理想值),但那是芯片内部理想情况。外部 1MΩ 级电阻网络,对微弱的批次性内部差异非常敏感。

三、为什么会出现"电压降低采集值升高"的反向现象

这个反向现象用电路层面最好解释:如果 ADC 引脚输入存在漏电流或驱动不足,且外部没有足够强的驱动(1MΩ 分压 + 无运放缓冲),那么:

  • 当电池电压升高时,通过 1MΩ 给 100nF 充电→ 采样时 ADC 内部电容拉低的电荷量相对固定;
  • 当外部源阻抗阻抗太低(1MΩ 太高)时,ADC 采样瞬间会把采样电容上原有的电荷放掉,而来不及从外部补充,导致采样到的值更多反映的是内部电容残留电荷而非外部真实电压,不同批次芯片的残留电荷与漏电方向不同,就可能出现反向。

帖子回复1也提到:"分压电阻阻抗太高,跟滤波电容形成的 RC 滞后过大"——这确实是首要嫌疑。

四、解决方案建议

根据手册规范 + 论坛讨论,建议从以下方面排查改进:

1. 降低 ADC 工作时钟频率(手册规范性要求)

// 系统40MHz下,建议把ADC时钟降到800K以内
ADCCFG = 0x2f;  // 建议改为值更大的SPEED,如 0x8f 或更大分频

实际上 0x8f 的 SPEED=0x0F 仍是 1.25MHz,应改为更低分频。同时确保 ADCTIM 中 SMPDUTY 足够大.

2. 必须将 ADC 引脚设为高阻输入

P0M1 |= 0x0F;  // P0.0~P0.3 设为高阻输入(推挽之外的输入方式)
P0M0 &= ~0x0F;

3. 降低外部源阻抗(论坛回复1/6 的核心)

由于你用大电阻是为了省电,可参考回复6 的省电技巧:用一个空闲 I/O 在采样时短暂输出高电平,经过较小的分压电阻(如几 kΩ~几十 kΩ)给采样电容提供足够驱动,采样结束后该 I/O 置低电平断电,既省电又保证采样准确。或者按回复1加一个运放电压跟随器做缓冲。

4. 加长采样时间 / 减少采样电容充电不足

手册强调通道选择后需等待、采样时间要足够。可适当增大 ADCTIM 采样占空比,并在 ADC 上电后 delay(1ms) 再使用(手册明确指出 ADC 模块上电后需等待约 1ms)。

5. 测量标定(回复4 的建议)

对一批板子实测 0~15V 对应的 ADC 值,列成表,判断是否能把"反向异常板"通过软件重标定修正。


信息来源:STC8H 系列手册第「21 ADC模数转换,内部1.19V参考信号源」章节(ADC_CONTR、ADCTIM、ADCCFG 寄存器及 ADC 静态特性表)、STC 论坛帖子 《ADC采样值不正常》。


需要我把完整的、符合手册规范的 ADC 初始化 + 采样代码按你的 40MHz 系统时钟写一份给你吗?我可以确保寄存器值和采样时序都是对的。


🔍 搜索 "https://www.stcaimcu.com/thread-25361-1-1.html"

⏱️ 查找用时 5.8s | 总回答用时 22.5s

回复

使用道具 举报 送花

2

主题

7

回帖

2023

积分

金牌会员

积分
2023
 楼主| 发表于 2026-8-22 12:06:11 | 显示全部楼层
无标题4.png
外部输入电压4-6v,分压后检测范围1.19v-1.26v,采样值正常1600-2200左右,异常值1456-1406.
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-11-8 01:13 , Processed in 0.077050 second(s), 87 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表