linlinmiao 发表于 2025-7-22 11:11:44

求助大神,32G12K128 ADC读电压有误差 | 很准了

#define       VREFH_ADDR   CHIPID7
#define       VREFL_ADDR   CHIPID8

    int xdata VCCres;
    int xdata vcc;

unsigned char xdata volt_tens = 0;         // 电压千位数
unsigned char xdata volt_units = 0;          // 电压百位数
unsigned char xdata volt_units2 = 0;          // 电压十位数
unsigned char xdata volt_units3 = 0;          // 电压个位数

void ADCInit()
{
      
ADCTIM = 0x3f;               //设置ADC内部时序
ADCCFG = 0x2f;                //设置ADC时钟为系统时钟/2/16

}


int ADCRead()
{
    int VCCres;

    ADC_START = 1;                        //启动AD转换
    _nop_();
    _nop_();
    while (!ADC_FLAG);                            //查询ADC完成标志
      ADC_FLAG = 0;                           //清完成标志
    VCCres = (ADC_RES << 8) | ADC_RESL;            //读取ADC结果
    return VCCres;
}

                //                ————————————————读电源VCC res和电压————————————————


BGV=(VREFH_ADDR<<8)+VREFL_ADDR;

   ADC_CONTR = 0x00;
                        ADC_CONTR = 0x8f;       //选择通道15(内部基准)
                            _nop_();
    _nop_();
ADCRead();
ADCRead();
                  VCCres = 0;
    for (i=0; i<8; i++)
    {
      VCCres += ADCRead();                     //读取8次数据
    }
    VCCres >>= 3;                                  //取平均值

    vcc = (int)(4096L * BGV / VCCres);



      volt_tens = vcc / 1000;          // 获取千位数 (2756/1000=2)

      volt_units = (vcc % 1000) / 100; // 获取百位数 (2756%1000=700, 700/100=7)

               
               
      volt_units2 = (vcc % 100) / 10; // 获取十位数 (2756%100=50, 50/10=5)

               
      volt_units3 = (vcc % 10) / 1; // 获取个位数 (2756%10=6, 6/1=6)




得出来的数据用来FOR循环闪灯用,最后靠闪灯读数,发现有误差
4.2v   读出来4395
4.3v   读出来4500
3.4v    读3555
3.2    读3348
3.9   读4072

5.1   读5341


之前用的STC8G1K08 TSSOP20,读出来很准,换成STC32G12K128就不准了,硬件没改动

而且发现用其他引脚读GND电压,应该是0V,读出来0.168V,大佬们有空帮看看代码有没有问题,太感谢了!!

DebugLab 发表于 2025-7-22 14:00:34

32G12K128有独立VREF,注意VREF的连接




linlinmiao 发表于 2025-7-22 14:26:48

DebugLab 发表于 2025-7-22 14:00
32G12K128有独立VREF,注意VREF的连接

VREF直接接到VCC上面了,这样会影响精度么

神农鼎 发表于 2025-7-22 14:32:39







DebugLab 发表于 2025-7-22 15:46:21

linlinmiao 发表于 2025-7-22 14:26
VREF直接接到VCC上面了,这样会影响精度么

高精度应用还是建议外接基准的(但这样无法直接得到VCC电压,还需要另外占用一个ADC通道,外加至少两个电阻)
VREF接VCC,计算VCC和外部输入的电压程序,供参考:






梁工 发表于 2025-7-22 22:21:54

AVREF连接了吗?

vb2002 发表于 2025-7-22 23:05:51

没有这么大的误差把,
1%倒是可能有

王昱顺 发表于 2025-7-23 07:10:48

感觉可能是通过BGV计算电压实际值的时候出了点问题,看起来像是因为没有强制转换成更高精度数据类型,造成计算的时候出现了一些误差。
可以先尝试一下直接输出adcread读出来的数值,看看接地的时候是否为0,这个一般是不会出问题的

梁工 发表于 2025-7-23 09:51:39



用户请先别修改程序, 直接下载"01-读取15通道ADC计算AVREF电压-串口1(P3.1)返回结果->Objects"里的"ADC.hex"测试.

下载时选择主频11.0592MHZ. 测试时, 电脑的串口助手设置115200,8,n,1.

本程序演示查询方式读取15通道ADC并计算AVREF的电压值,通过串口1(P3.1)发送给上位机,波特率115200,8,n,1.


很准确的:




linlinmiao 发表于 2025-7-23 20:29:55

梁工 发表于 2025-7-23 09:51
用户请先别修改程序, 直接下载"01-读取15通道ADC计算AVREF电压-串口1(P3.1)返回结果->Objects"里的"ADC.h ...

哇,用这个程序读出来的电压又变得很准了,奇怪了,得仔细检查代码才行
页: [1] 2
查看完整版本: 求助大神,32G12K128 ADC读电压有误差 | 很准了