找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 765|回复: 12
收起左侧

ADC采集精度为什么只有0.2V

[复制链接]
ID:705846 发表于 2025-12-9 13:51 | 显示全部楼层 |阅读模式
STC15W408AS
利用bandgap作为参考电压,10位采集,什么原因导致测量的电压总是精度为0.2V,有没有哪位大佬处理过类似问题。

//初始化ADC
void AdInit()
{        
        P1ASF = 0x03;                                                                                                //00000011允许P1.0,P1.1执行ADC
        ADC_RES = 0;        ADC_RESL = 0;                                        //清除ADC结果寄存器
        CLK_DIV = 0x20;                                                                                 //00100000、ADRJ 为 1,
                                                                                                                                                        //ADC_RES 存放高两位结果,
                                                                                                                                                        //ADC_RESL 存放低 8 位结果
        ADC_CONTR = 0x88|0x01;                                                        //0x88是ADC_POWER|ADC_SPEEDLL|ADC_START的结果
        delay_ms(20);                                                                                                //等待ADC稳定
        EADC = 1;                                                                                                 //允许AD转换中断
}


//获取芯片出厂bandgap的ADC值(ADCbg)
void GetADCbg()
{
        P1ASF        =        0x00;
        ADC_RES = 0;        ADC_RESL = 0;
        CLK_DIV = 0x20;
        ADC_CONTR = 0x88;                                                                                //ADC_POWER|ADC_SPEEDLL|ADC_START的结果
        delay_us(2);                                       
        ADC_CONTR = 0x88|0x00;                                                                                //启动ADCbg第九通道的转换
        delay_us(5);
        while(!(ADC_CONTR & ADC_FLAG));                        //等待转换完成
        ADC_CONTR &= ~ADC_FLAG;                                                        //关闭ADC
        ADCbg = (ADC_RES*256+ADC_RESL);
}



//获取芯片出厂bandgap的电压值(bandgap)
void bdgp()
{
        uchar idata *iptr;                                //定义RAM内存区指针
        iptr = ID_ADDR_RAM;
        bandgap=*iptr++;
        bandgap<<=8;
        bandgap+=*iptr;                                                //从内存区读取BandGap电压值(单位毫伏
}


void adc_isr()interrupt 5 using 1
{
        static char VoCount,CrCount,m,ch;
        static uint VoResult,CrResult;
        ADC_CONTR &= !0x10; //CLOSE ADC ADC_FLAG复位
                if(ch==0){        
                                OPPCur = (float)bandgap*(ADC_RES*256+ADC_RESL)/ADCbg*cur_sampling/100; //
                                if(m==32){
                                        if(CrCount < ADC_TIMES){
                                                CrResult +=        (ADC_RES*256+ADC_RESL);
                                                CrCount++;
                                        }else{
                                                CFt = (float)bandgap*(CrResult/ADC_TIMES)/ADCbg*cur_sampling/100;
                                                CrCount = 0;
                                                CrResult = 0;
                                        }
                                }
                }
               
                if(ch==1){
                                OPPVol = ((float)bandgap*(ADC_RES*256+ADC_RESL)/ADCbg/vol_sampling)/100; //123V
                                if(m==32){
                                        if(VoCount < ADC_TIMES){
                                                VoResult +=        (ADC_RES*256+ADC_RESL);
                                                VoCount++;
                                        }else{
                                                VFt = ((float)bandgap*(VoResult/ADC_TIMES)/ADCbg/vol_sampling)/100+voloffset;
                                                VoCount = 0;
                                                VoResult = 0;
                                        }
                                }
                }
               
        if((m%33)==32) ch++;
        m++;
        if(m>32) m = 0;
        if(ch>1)ch=0;
        ADC_CONTR = 0x88|ch;
        _nop_();_nop_();_nop_();_nop_();        //等待四个机器周期
}


回复

使用道具 举报

ID:705846 发表于 2025-12-9 13:59 | 显示全部楼层
用万用表测量输出电压步进是0.1,但ADC采集数码管确是0.2的步进
回复

使用道具 举报

ID:1034262 发表于 2025-12-9 21:04 | 显示全部楼层
没有量程,只说精度,没有意义。
比如量程100V,误差0.2V,那精度就是0.2%。量程10V,误差0.2V,那精度就是2%!
回复

使用道具 举报

ID:1128898 发表于 2025-12-10 05:58 | 显示全部楼层
用万用表测量输出电压? are you suer?
回复

使用道具 举报

ID:705846 发表于 2025-12-10 09:41 | 显示全部楼层
也就是ADC 0.1的变化测不出来,每次变化都是0.2V ,而实际电压只变化了0.1V
回复

使用道具 举报

ID:283207 发表于 2025-12-10 14:26 | 显示全部楼层
量程的问题,10位AD分辨率高是1024,极限来说:如果测100V就是0.1V精度,测200V就是0.2V步进。还有就是“用万用表测量输出电压步进是0.1”,这句没明白?AD转换器,你测的是什么?输入电压?
回复

使用道具 举报

ID:1164475 发表于 2025-12-10 15:33 | 显示全部楼层
hyzqq 发表于 2025-12-10 14:26
量程的问题,10位AD分辨率高是1024,极限来说:如果测100V就是0.1V精度,测200V就是0.2V步进。还有就是“用 ...

我认为他想表达的意思是0.1V,万用表能分辨的出来,而他的ADC 需要0.2V的压差才能分辨的出来
回复

使用道具 举报

ID:705846 发表于 2025-12-10 15:58 | 显示全部楼层
hyzqq 发表于 2025-12-10 14:26
量程的问题,10位AD分辨率高是1024,极限来说:如果测100V就是0.1V精度,测200V就是0.2V步进。还有就是“用 ...

我测试的13-48V的电压。 ADC也是从输出电压采样,万用表测的输出电压,比如万用表测输出电压是15.0,15,2,15,3,15.4V,ADC采集数码管只能显示15.0.15.2,15.4
回复

使用道具 举报

ID:283207 发表于 2025-12-12 09:57 | 显示全部楼层
samxon 发表于 2025-12-10 15:58
我测试的13-48V的电压。 ADC也是从输出电压采样,万帽聿獾氖涑龅缪梗热缤蛴帽聿馐涑龅缪故�15.0,15,2, ...

是的,请看我上面的回答。要提高分辨率,就要减小量程。也就是说在量程最大电压值时,要把AD输入的电压分压后输入单片机端口,该电压值,调到和基准一致。假设输入100V时你用万用表测IO输入的电压值应是1.2V左右(内部基准一致性不好,有偏差),此时你测的分辨率就是100/1023约0.1V(理想状态)。如想测量分辨率是0.01V,那就把10V(超过10V就超量程了)输入时,IO端口的分压值调到基准值即可。
回复

使用道具 举报

ID:283207 发表于 2025-12-12 10:02 | 显示全部楼层
newton1207 发表于 2025-12-10 15:33
我认为他想表达的意思是0.1V,万用表能分辨的出来,而他的ADC 需要0.2V的压差才能分辨的出来

确实。那这就是量程的问题了。
回复

使用道具 举报

ID:705846 发表于 2025-12-13 09:29 | 显示全部楼层
hyzqq 发表于 2025-12-12 09:57
是的,请看我上面的回答。要提高分辨率,就要减小量程。也就是说在量程最大电压值时,要把AD输入的电压分 ...

谢谢各位大佬解答。我的理解是10位ADC,参考电压5V,分辨率就是0.00488V。 如果电压是1-100V,就是每次ADC采集变动必须小于分辨率电压才能步进0.1V。经过实际验证测试,问题解决。再次感谢。
回复

使用道具 举报

ID:624769 发表于 2025-12-13 16:12 | 显示全部楼层
samxon 发表于 2025-12-13 09:29
谢谢各位大佬解答。我的理解是10位ADC,参考电压5V,分辨率就是0.00488V。 如果电压是1-100V,就是每次ADC ...

你的理解并不对, 分辨率不仅仅由参考电压决定的,还取决于你的分压电阻。
假定,你的分压电阻是10K 和 990K(1:100), 那么,分辨率就得 0.488V 了。
你想要分辨率小于 0.1,那么分压电阻一般需要选择 20k 和 383K(1:20.15) 这个比例才可以。
回复

使用道具 举报

ID:469589 发表于 2026-1-2 08:58 | 显示全部楼层
理解有问题,我看觉果是对的。
回复

使用道具 举报

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

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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