打印
[技术问答]

003的ADC稳定吗?

[复制链接]
2017|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
skys2000|  楼主 | 2018-6-1 09:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
ADC, TI, BLE, AI, AN
用003做了个温度采集的,用的是P0.4(AIN5)ADC丢弃了前2个包,取后3个,测VDD老是跳。
已配置 模拟输入了。
代码如下:
void main (void)
{
          //unsigned char i;
                double bgvalue;
    double digitalValue,voltageValue,Rt;
                unsigned int i;
    double temp;
    char xdata info[50],info2[50];
  
    Set_All_GPIO_Quasi_Mode;                                        // Define in Function_define.h
       


       
                InitialUART0_Timer1(115200);
    OLED_Init(); //OLED初始化
                READ_BANDGAP();
  
                Enable_ADC_BandGap;                                                                                               

                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++)                                                                                                        // All following ADC detect timing is 200uS run under 4MHz.
    {
                        clr_ADCF;
                        set_ADCS;                                                                                                                               
      while(ADCF == 0);
                        ADCdataH[i] = ADCRH;
                        ADCdataL[i] = ADCRL;
                }               
                CKDIV = 0x00;                                                                                                                        // After ADC sampling, modify system clock back to 16MHz to run next code.
   
    clr_ADCEN;
               
                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;
                VDD_Voltage = (0x1000/bgvalue)*Bandgap_Voltage/1000;
                        printf ("\n BG ROMMAP = %f",Bandgap_Voltage);
                        printf ("\n VDD voltage = %f", VDD_Voltage);
   
       
   
    P04_Input_Mode;
    Enable_ADC_AIN5;  // Enable AIN0 P0.4 as ADC input, Find in "Function_define.h" - "ADC INIT"
                                                   
    while(1){
      
      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++)                                                                                                        // All following ADC detect timing is 200uS run under 4MHz.
    {
                        clr_ADCF;
                        set_ADCS;                                                                                                                               
      while(ADCF == 0);
                        ADCdataH[i] = ADCRH;
                        ADCdataL[i] = ADCRL;
                }               
                CKDIV = 0x00;                                                                                                                        // After ADC sampling, modify system clock back to 16MHz to run next code.
   
   
    ADCsumH=0;
    ADCsumL=0;
                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;
    printf ("\nbgvalue = %f",bgvalue);
    printf ("\n BG ROMMAP = %f",Bandgap_Voltage);
                printf ("\n VDD voltage = %f", VDD_Voltage);
    Res_Voltage=4095/bgvalue*Bandgap_Voltage/1000;

    sprintf (&info,"Res_V= %f",Res_Voltage);

  //获得端口处的电压值  
  digitalValue=bgvalue;  
  voltageValue=(digitalValue/4095)*VDD_Voltage;  
  printf("Current voltage value=%3f",voltageValue);  
  
  voltagePower=VDD_Voltage;
   
  //通过分压比获得热敏电阻的阻值  
  Rt=((voltagePower-voltageValue)*Rs)/voltageValue;  
  printf("Current registor value=%3f",Rt);  
  
  
  //换算得到温度值  
  temp=(((T1*BZ)/(BZ+T1*log(Rt/R1)))-273.15);//
  printf("Current temperature value=%3f",temp);  
  sprintf(&info2,"tempv=%3f",temp);  

    OLED_P8x16Str(0,0,&info);
    OLED_P8x16Str(0,2,&info2);
    //Res_Voltage*100000;
/*
                for(i=0;i<105;i++)                                                                                                        // use the last 3 times data to make average
    {
                        if ((Temp_Voltage<dTemp[i])&&(Temp_Voltage>dTemp[i+1]))
        temp=i-20;
                }       
   
   
                        //printf ("\nRes_Voltage  = %10f",Res_Voltage);
      //printf ("\nTemp_Voltage = %3f",Temp_Voltage);
    sprintf (&info,"Temp = %3f",temp);
*/   
    //OLED_P8x16Str(0,2,&info);
                Timer3_Delay100ms(10);
                //OLED_CLS();
}  

温度采集每次都变动很大,小的时候0.05,大的时候0.5-0.6度。
同一个电阻和3435温度电阻在arduino 里很稳定。
沙发
gaoyang9992006| | 2018-6-1 09:26 | 只看该作者
测出来的结果跟温度计显示的差别大吗

使用特权

评论回复
板凳
gaoyang9992006| | 2018-6-1 09:26 | 只看该作者
如果有轻微的跳动,你可以使用滤波。

使用特权

评论回复
地板
woshicainiao| | 2018-6-1 09:52 | 只看该作者
N76E003的AD是12位的  你可以采集16组数据   然后从小到大排序   去掉最大值 最小值  剩下的求平均 ; 有好多种 AD采样数据滤波算法 你可以百度下

使用特权

评论回复
5
tianxj01| | 2018-6-1 10:00 | 只看该作者
003的ADC本身稳定性没有问题,由于采用的是Vcc作为ADC基准,因此,关键就变成芯片供电的稳定了,对ADC稳定性有特别要求的,建议把单独的稳压器,就近给单片机直接供电,并在稳压器输出端并联足够的旁路电容。以满足Vcc稳定的基本要求。

使用特权

评论回复
6
skys2000|  楼主 | 2018-6-1 10:29 | 只看该作者
tianxj01 发表于 2018-6-1 10:00
003的ADC本身稳定性没有问题,由于采用的是Vcc作为ADC基准,因此,关键就变成芯片供电的稳定了,对ADC稳定 ...

有的芯片可以选择ADC以VDD为基准还是以带隙基准为参考,这样就方便多了,否则外围太复杂了。毕竟这是1块多的芯片啊

使用特权

评论回复
7
skys2000|  楼主 | 2018-6-1 12:16 | 只看该作者
改成中值滤波 还是没用,看样子是硬件电路毛病了

                READ_BANDGAP();
  
                Enable_ADC_BandGap;                                                                                               

                CKDIV = 0x02;                                                                                                                        // IMPORTANT!! Modify system clock to 4MHz ,then add the ADC sampling clock base to add the sampling timing.
                for(i=0;i<Fn+3;i++)                                                                                                        // All following ADC detect timing is 200uS run under 4MHz.
    {
                        clr_ADCF;
                        set_ADCS;                                                                                                                               
      while(ADCF == 0);
      if (i>2)
      {
        ADCdataH[i-3] = ADCRH;
        ADCdataL[i-3] = ADCRL;
      }
                }               
                CKDIV = 0x00;                                                                                                                        // After ADC sampling, modify system clock back to 16MHz to run next code.
   
    clr_ADCEN;
               

    ADCavgH = middleValueFilter(ADCdataH);
                ADCavgL = middleValueFilter(ADCdataL);
   
   
                bgvalue = (ADCavgH<<4) + ADCavgL;
                VDD_Voltage = (0x1000/bgvalue)*Bandgap_Voltage/1000;
                        printf ("\n BG ROMMAP = %f",Bandgap_Voltage);
                        printf ("\n VDD voltage = %f", VDD_Voltage);
   
       
   
    P04_Input_Mode;
    Enable_ADC_AIN5;  // Enable AIN0 P0.4 as ADC input, Find in "Function_define.h" - "ADC INIT"
                                                   
    while(1){
      
      CKDIV = 0x02;                                                                                                                        // IMPORTANT!! Modify system clock to 4MHz ,then add the ADC sampling clock base to add the sampling timing.
   
                for(i=0;i<Fn+3;i++)                                                                                                        // All following ADC detect timing is 200uS run under 4MHz.
    {
                        clr_ADCF;
                        set_ADCS;                                                                                                                               
      while(ADCF == 0);
      if (i>2)
      {
        ADCdataH[i-3] = ADCRH;
        ADCdataL[i-3] = ADCRL;
      }
                }               
                CKDIV = 0x00;                                                                                                                        // After ADC sampling, modify system clock back to 16MHz to run next code.
   
    clr_ADCEN;
               

    ADCavgH = middleValueFilter(ADCdataH);
                ADCavgL = middleValueFilter(ADCdataL);
   
                bgvalue = (ADCavgH<<4) + ADCavgL;
    printf ("\nbgvalue = %f",bgvalue);
    printf ("\n BG ROMMAP = %f",Bandgap_Voltage);
                printf ("\n VDD voltage = %f", VDD_Voltage);
    Res_Voltage=4095/bgvalue*Bandgap_Voltage/1000;

    sprintf (&info,"Res_V= %f",Res_Voltage);

使用特权

评论回复
8
燕南飞| | 2018-6-1 14:33 | 只看该作者
用过赛元的7003,内部有2.4V基准作为参考电压,VDD的波动不影响内部2.4V,可以参考一下。

使用特权

评论回复
9
tianxj01| | 2018-6-1 16:13 | 只看该作者
skys2000 发表于 2018-6-1 10:29
有的芯片可以选择ADC以VDD为基准还是以带隙基准为参考,这样就方便多了,否则外围太复杂了。毕竟这是1块 ...

其实,在用STM8时候,我就在奇怪,为什么不用内部的带隙基准呢?
到新唐003了,其内部也有带隙基准,居然和STM8一样,只能作为专门的一路来反向测试电源,而不能把AD基准切换到该带隙基准?怎么想的?好不理解。

使用特权

评论回复
10
dongnanxibei| | 2018-6-2 17:09 | 只看该作者
哈哈,还是参考官方的例子的用法比较好。

使用特权

评论回复
11
小灵通2018| | 2018-6-3 20:57 | 只看该作者
看看电路吧,电路肯定是有问题的。因为你这个测量对象缓慢,加个电容试试看。

使用特权

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

本版积分规则

11

主题

23

帖子

0

粉丝