[技术问答] N76E003 adc波动

[复制链接]
5527|16
 楼主| yunxiang521 发表于 2020-4-23 15:09 | 显示全部楼层 |阅读模式
ADC采集电压,时间长总会出现波动。
  1. /*
  2. 程序功能:读取UID中带隙电压值;通过ADC,测量实际的带隙电压;得到比例系数COE;
  3. 本程序需要放在ADC正常测量前。
  4. */
  5. void READ_BANDGAP()
  6. {
  7.                 unsigned int i;
  8.                 set_IAPEN;
  9.                 IAPCN = READ_UID;
  10.                 IAPAL = 0x0d;
  11.     IAPAH = 0x00;
  12.     set_IAPGO;
  13.                 BandgapLow = IAPFD;
  14.                 BandgapMark = BandgapLow&0xF0;
  15.                        
  16.                 if (BandgapMark==0x80)
  17.                 {
  18.                                 BandgapLow = BandgapLow&0x0F;
  19.                                 IAPAL = 0x0C;
  20.                                 IAPAH = 0x00;
  21.                                 set_IAPGO;
  22.                                 BandgapHigh = IAPFD;
  23.                                 Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
  24.                                 Bandgap_Voltage_Temp = Bandgap_Value*3/4;
  25.                                 Bandgap_Voltage = Bandgap_Voltage_Temp - 33;                        //the actually banggap voltage value is similar this value.
  26.                 }
  27.                 if (BandgapMark==0x00)
  28.                 {
  29.                                 BandgapLow = BandgapLow&0x0F;
  30.                                 IAPAL = 0x0C;
  31.                                 IAPAH = 0x00;
  32.                                 set_IAPGO;
  33.                                 BandgapHigh = IAPFD;
  34.                                 Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
  35.                                 Bandgap_Voltage= Bandgap_Value*3/4;
  36.                 }
  37.                 if (BandgapMark==0x90)
  38.                 {
  39.                                 IAPAL = 0x0E;
  40.                                 IAPAH = 0x00;
  41.                                 set_IAPGO;
  42.                                 BandgapHigh = IAPFD;
  43.                                 IAPAL = 0x0F;
  44.                                 IAPAH = 0x00;
  45.                                 set_IAPGO;
  46.                                 BandgapLow = IAPFD;
  47.                                 BandgapLow = BandgapLow&0x0F;
  48.                                 Bandgap_Value = (BandgapHigh<<4)+BandgapLow;
  49.                                 Bandgap_Voltage= Bandgap_Value*3/4;
  50.                 }
  51.                 clr_IAPEN;
  52. //----------------------------------------------------------------------------
  53. //----------------------------------------------------------------------------
  54. //----------------------------------------------------------------------------               
  55.                                 Enable_ADC_BandGap;        //使能ADC带隙电压                                                                                       
  56.                                 CKDIV = 0x02;                                // IMPORTANT!! Modify system clock to 4MHz ,then add the ADC sampling clock base to add the sampling timing.
  57.                                 for(i=0;i<5;i++)                //采样5次,不要前面三次
  58.                                 {                                                                                                                                                                       
  59.                                                 clr_ADCF;
  60.                                                 set_ADCS;                                                                                                                               
  61.                                                 while(ADCF == 0);
  62.                                                 ADCdataH[i] = ADCRH;
  63.                                                 ADCdataL[i] = ADCRL;
  64.                                 }               
  65.                                 CKDIV = 0x00;
  66. //--------均值滤波--------------------------------------------
  67.                                 for(i=2;i<5;i++)                                                                                                        // use the last 3 times data to make average
  68.                                 {
  69.                                         ADCsumH = ADCsumH + ADCdataH[i];
  70.                                         ADCsumL = ADCsumL + ADCdataL[i];
  71.                                 }                               
  72.                                 ADCavgH = ADCsumH/3;
  73.                                 ADCavgL = ADCsumL/3;
  74.                                 bgvalue = (ADCavgH<<4) + ADCavgL;
  75.                                 Coe=(Bandgap_Voltage/bgvalue);
  76.                                 ADCsumH = 0;
  77.                                 ADCsumL = 0;       
  78. }


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

  97. void main (void)
  98. {
  99.         UINT16 ss;
  100.         InitialUART0_Timer1(115200);
  101.   Set_All_GPIO_Quasi_Mode;  
  102.         READ_BANDGAP();
  103.         Enable_ADC_AIN0;//配置使能P1.7,作为AIN0。
  104.         //P04_FALLINGEDGE_TRIG_ADC;// 使用P04下降沿触发中断,使                            用外部触发时,可以不使能ADCS。
  105.   //set_EADC;//使能ADC中断
  106.         //EA = 1;
  107.         set_ADCS;//使能ADCS,启动ADC测量
  108.         Init_I2C();
  109.         while(1){
  110.                 if(ADCF)
  111.         {
  112.                 clr_ADCF;//清除ADC转化完成标志,进行下一次转换
  113.                 set_ADCS;//当单次转换完成后,ADCS会硬件置0,需要重新使能
  114.                 RC_value= (ADCRH<<4) + ADCRL;//得到ADC转换值
  115.                 ss=RC_value;
  116.                 ADC_Voltage=RC_value*Coe/1000;
  117.                 //printf ("\n Value = 0x%bx",ADC_Voltage);
  118.                 printf ("\n Value = %6.2f",ADC_Voltage);
  119.                 s=ADC_Voltage*1024/5;
  120.                 //printf ("  Value = %f",s);
  121.                 sprintf(aa,"%6.2f",s);
  122.                 printf (" Value = %e",RC_value);
  123.                 //printf (" Value = %e",Coe);
  124.                 Timer0_Delay1ms(500);
  125.         }
  126.         };
  127. }

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

评论

不觉得累加求均值有问题吗  发表于 2020-4-26 17:35
jasontu 发表于 2020-4-23 16:19 | 显示全部楼层
檢查過外部電源及adc進入信號嗎?
 楼主| yunxiang521 发表于 2020-4-23 16:35 | 显示全部楼层
检查过,外部正常
 楼主| yunxiang521 发表于 2020-4-23 16:38 | 显示全部楼层
用万用表,示波器都长时间测过。上面的代码,我用电脑的USB HUB供电,如果我在USB上再插一个设备,电压就会有变动。正常来说不应该变动才动。外部电压是正常的。
xuanhuanzi 发表于 2020-4-23 20:56 | 显示全部楼层
如果插个另外设备有影响,那就是电源问题,HUB供电不足。
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 ...

業績很缺喔?
huangcunxiake 发表于 2020-4-26 11:25 | 显示全部楼层
找到问题没
pigluffy 发表于 2020-4-26 14:38 | 显示全部楼层
可能是雜訊,使用低通濾波器應該就能解決了
huangcunxiake 发表于 2020-4-26 19:50 | 显示全部楼层
加个电容略博看看。
pigluffy 发表于 2020-4-26 20:28 | 显示全部楼层
pigluffy 发表于 2020-4-26 14:38
可能是雜訊,使用低通濾波器應該就能解決了

用程式的方式實現
Lbsonggz 发表于 2020-4-27 22:24 | 显示全部楼层
看AVR的技术资料,1)启动ADC转换后,要延时5-10ms,等待电源稳定;2)第一次ADC转换结果要丢弃,后面的简单使用3-5次的均值滤波就比较精确了
643757107 发表于 2020-4-27 23:39 | 显示全部楼层
楼上方法试试看
 楼主| yunxiang521 发表于 2020-4-29 10:47 | 显示全部楼层
不是HUB的问题,接了电容一样,具体问题还是没找出来。
 楼主| yunxiang521 发表于 2020-4-29 10:58 | 显示全部楼层
谢谢楼上几位的方法,我会都试试
HuangHongLun 发表于 2020-4-29 17:10 | 显示全部楼层
上一次转换完成后再进行下一次的判断,这样比较稳定点。
MagicSquare834 发表于 2020-7-30 09:51 | 显示全部楼层
那个adc的参数说明中说了低4位是不准的,有误差,12位的adc能用的其实只有高8位
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

100

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部