打印
[技术问答]

N76E003 adc波动

[复制链接]
4697|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yunxiang521|  楼主 | 2020-4-23 15:09 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ADC采集电压,时间长总会出现波动。
/*
程序功能:读取UID中带隙电压值;通过ADC,测量实际的带隙电压;得到比例系数COE;
本程序需要放在ADC正常测量前。
*/
void READ_BANDGAP()
{
                unsigned int i;
                set_IAPEN;
                IAPCN = READ_UID;
                IAPAL = 0x0d;
    IAPAH = 0x00;
    set_IAPGO;
                BandgapLow = IAPFD;
                BandgapMark = BandgapLow&0xF0;
                       
                if (BandgapMark==0x80)
                {
                                BandgapLow = BandgapLow&0x0F;
                                IAPAL = 0x0C;
                                IAPAH = 0x00;
                                set_IAPGO;
                                BandgapHigh = IAPFD;
                                Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
                                Bandgap_Voltage_Temp = Bandgap_Value*3/4;
                                Bandgap_Voltage = Bandgap_Voltage_Temp - 33;                        //the actually banggap voltage value is similar this value.
                }
                if (BandgapMark==0x00)
                {
                                BandgapLow = BandgapLow&0x0F;
                                IAPAL = 0x0C;
                                IAPAH = 0x00;
                                set_IAPGO;
                                BandgapHigh = IAPFD;
                                Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
                                Bandgap_Voltage= Bandgap_Value*3/4;
                }
                if (BandgapMark==0x90)
                {
                                IAPAL = 0x0E;
                                IAPAH = 0x00;
                                set_IAPGO;
                                BandgapHigh = IAPFD;
                                IAPAL = 0x0F;
                                IAPAH = 0x00;
                                set_IAPGO;
                                BandgapLow = IAPFD;
                                BandgapLow = BandgapLow&0x0F;
                                Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
                                Bandgap_Voltage= Bandgap_Value*3/4;
                }
                clr_IAPEN;
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------               
                                Enable_ADC_BandGap;        //使能ADC带隙电压                                                                                       
                                CKDIV = 0x02;                                // IMPORTANT!! Modify system clock to 4MHz ,then add the ADC sampling clock base to add the sampling timing.
                                for(i=0;i<5;i++)                //采样5次,不要前面三次
                                {                                                                                                                                                                       
                                                clr_ADCF;
                                                set_ADCS;                                                                                                                               
                                                while(ADCF == 0);
                                                ADCdataH[i] = ADCRH;
                                                ADCdataL[i] = ADCRL;
                                }               
                                CKDIV = 0x00;
//--------均值滤波--------------------------------------------
                                for(i=2;i<5;i++)                                                                                                        // use the last 3 times data to make average
                                {
                                        ADCsumH = ADCsumH + ADCdataH[i];
                                        ADCsumL = ADCsumL + ADCdataL[i];
                                }                               
                                ADCavgH = ADCsumH/3;
                                ADCavgL = ADCsumL/3;
                                bgvalue = (ADCavgH<<4) + ADCavgL;
                                Coe=(Bandgap_Voltage/bgvalue);
                                ADCsumH = 0;
                                ADCsumL = 0;       
}


//void ADC_ISR (void) interrupt 11
//{
//        if(ADCF)
//        {
//                clr_ADCF;//清除ADC转化完成标志,进行下一次转换
//                set_ADCS;//当单次转换完成后,ADCS会硬件置0,需要重新使能
//                RC_value= (ADCRH<<4) + ADCRL;//得到ADC转换值
//                ADC_Voltage=RC_value*Coe/1000;
//                //printf ("\n Value = 0x%bx",ADC_Voltage);
//                printf ("\n Value = %6.2f",ADC_Voltage);
//                s=ADC_Voltage*1024/5;
//                //printf ("  Value = %f",s);
//                sprintf(aa,"%6.2f",s);
//                printf (" Value = %e",RC_value);
//                //printf (" Value = %e",Coe);
//                Timer0_Delay1ms(500);
//        }// Check the P3.0 toggle at falling edge of PWM
//}

void main (void)
{
        UINT16 ss;
        InitialUART0_Timer1(115200);
  Set_All_GPIO_Quasi_Mode;  
        READ_BANDGAP();
        Enable_ADC_AIN0;//配置使能P1.7,作为AIN0。
        //P04_FALLINGEDGE_TRIG_ADC;// 使用P04下降沿触发中断,使                            用外部触发时,可以不使能ADCS。
  //set_EADC;//使能ADC中断
        //EA = 1;
        set_ADCS;//使能ADCS,启动ADC测量
        Init_I2C();
        while(1){
                if(ADCF)
        {
                clr_ADCF;//清除ADC转化完成标志,进行下一次转换
                set_ADCS;//当单次转换完成后,ADCS会硬件置0,需要重新使能
                RC_value= (ADCRH<<4) + ADCRL;//得到ADC转换值
                ss=RC_value;
                ADC_Voltage=RC_value*Coe/1000;
                //printf ("\n Value = 0x%bx",ADC_Voltage);
                printf ("\n Value = %6.2f",ADC_Voltage);
                s=ADC_Voltage*1024/5;
                //printf ("  Value = %f",s);
                sprintf(aa,"%6.2f",s);
                printf (" Value = %e",RC_value);
                //printf (" Value = %e",Coe);
                Timer0_Delay1ms(500);
        }
        };
}

不稳定,上面是代码,大牛帮看看问题在那

使用特权

评论回复
评论
zzm19900 2020-4-26 17:35 回复TA
不觉得累加求均值有问题吗 
沙发
jasontu| | 2020-4-23 16:19 | 只看该作者
檢查過外部電源及adc進入信號嗎?

使用特权

评论回复
板凳
yunxiang521|  楼主 | 2020-4-23 16:35 | 只看该作者
检查过,外部正常

使用特权

评论回复
地板
yunxiang521|  楼主 | 2020-4-23 16:38 | 只看该作者
用万用表,示波器都长时间测过。上面的代码,我用电脑的USB HUB供电,如果我在USB上再插一个设备,电压就会有变动。正常来说不应该变动才动。外部电压是正常的。

使用特权

评论回复
5
xuanhuanzi| | 2020-4-23 20:56 | 只看该作者
如果插个另外设备有影响,那就是电源问题,HUB供电不足。

使用特权

评论回复
6
pigluffy| | 2020-4-25 10:52 | 只看该作者
**NT018 发表于 2020-4-25 09:50
STC8G1K08-36I-SOP8, RMB0.65,
1T 8051, 8K FLASH, 1.2K SRAM, 1.9V - 5.5V, 低功耗,支持仿真
6个I/O, ISP ...

業績很缺喔?

使用特权

评论回复
7
huangcunxiake| | 2020-4-26 11:25 | 只看该作者
找到问题没

使用特权

评论回复
8
pigluffy| | 2020-4-26 14:38 | 只看该作者
可能是雜訊,使用低通濾波器應該就能解決了

使用特权

评论回复
9
huangcunxiake| | 2020-4-26 19:50 | 只看该作者
加个电容略博看看。

使用特权

评论回复
10
pigluffy| | 2020-4-26 20:28 | 只看该作者
pigluffy 发表于 2020-4-26 14:38
可能是雜訊,使用低通濾波器應該就能解決了

用程式的方式實現

使用特权

评论回复
11
Lbsonggz| | 2020-4-27 22:24 | 只看该作者
看AVR的技术资料,1)启动ADC转换后,要延时5-10ms,等待电源稳定;2)第一次ADC转换结果要丢弃,后面的简单使用3-5次的均值滤波就比较精确了

使用特权

评论回复
12
643757107| | 2020-4-27 23:39 | 只看该作者
楼上方法试试看

使用特权

评论回复
13
yunxiang521|  楼主 | 2020-4-29 10:47 | 只看该作者
不是HUB的问题,接了电容一样,具体问题还是没找出来。

使用特权

评论回复
14
yunxiang521|  楼主 | 2020-4-29 10:58 | 只看该作者
谢谢楼上几位的方法,我会都试试

使用特权

评论回复
15
HuangHongLun| | 2020-4-29 17:10 | 只看该作者
上一次转换完成后再进行下一次的判断,这样比较稳定点。

使用特权

评论回复
16
MagicSquare834| | 2020-7-30 09:51 | 只看该作者
那个adc的参数说明中说了低4位是不准的,有误差,12位的adc能用的其实只有高8位

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

100

帖子

0

粉丝