[应用方案] ADC检测准确的几种方法

[复制链接]
 楼主| vivilyly 发表于 2022-12-10 22:37 | 显示全部楼层 |阅读模式

1.硬件分析

上臂电阻58K,下臂电阻10K   分压后就是V=24*10/(10+58)=3.07V

一般芯片,判断高于 0.7VDD为高电平 ,低于0.3VDD为低电平。

2.软件分析

2.1 采集AD时进行滤波

(1)先采集20个值,丢弃前2个,去掉最大值和最小值,最后除以16取平均值。

(2)每隔一段时间取一份平均值,总共10份。最后除以10可以得AD值。

  1. //取一份AD值
  2. unsigned int POWER_Get_Adc_Data12_Average()
  3. {
  4.   unsigned  int  temp_value  = 0;
  5.   unsigned char  channel=0;
  6.   unsigned long int tmpbuff = 0;
  7.   unsigned  int ADCMAX = 0;
  8.   unsigned  int ADCMIN = 0xffff;
  9.    for (channel = 0; channel < 20; channel++)
  10.    {
  11.                    ADCON        =        0x86;                   //通道选择:多通道时不能用|=,只能用|
  12.                 ADCON        |=        0x10;                  //启动ADC检测       
  13.                 while((ADCON&0x10));          //等待ADC检测结束

  14.                   temp_value = ADDH;
  15.                   temp_value = (temp_value<<4)|(ADDL&0x0F);
  16.                 if (channel < 2)
  17.             continue; //丢弃前两次采样的
  18.                
  19.         if (temp_value > ADCMAX)
  20.             ADCMAX = temp_value; //最大
  21.         if (temp_value < ADCMIN)
  22.             ADCMIN = temp_value; //最小
  23.                
  24.         tmpbuff += temp_value;
  25.         }
  26.                 tmpbuff -= ADCMAX;           //去掉一个最大
  27.             tmpbuff -= ADCMIN;           //去掉一个最小
  28.             temp_value = (tmpbuff >> 4); //除以16,取平均值
  29.                   return temp_value;
  30. }

  31. //每隔一段时间取一份AD值,再平均
  32. //ADC_CNT 表示时间计数的变量
  33. //POWER_ALL_value 表示AD总值的变量
  34. void POWER_ADC_Electric_PRO(void)
  35. {
  36.         unsigned int  ad_value;
  37.         ad_value = POWER_Get_Adc_Data12_Average();
  38.         ADC_CNT++;
  39.         POWER_ALL_value+=ad_value;
  40.         if(ADC_CNT>=10)
  41.         {
  42.                 ADC_CNT=0;               
  43.                 POWER_AGE_VALUE=POWER_ALL_value/10;
  44.                 POWER_ALL_value=0;
  45.         }               
  46. }


2.2 采取差值计算

先取一个A值,如果后面采集的AD值,波动的范围没有超过设定值,就默认在A值的范围内。

比如A值为3.53V,波动设定值为±0.01,如果后面采集的B值为3.525V 或者3.535V,就默认为A值;

程序如下:

  1.         //B_VALUE_temp1,B_VALUE_temp2  表示暂存AD值的变量
  2.           //POWER_AGE_VALUE   表示记录实时AD值的变量
  3.           // ADC_DIF          表示波动设定值   
  4.           //结果用B_VALUE_temp1取比较AD值
  5.      
  6.             if(B_VALUE_temp1<=POWER_AGE_VALUE)
  7.                                 {
  8.                                         B_VALUE_temp2=B_VALUE_temp1;
  9.                                         B_VALUE_temp2+=ADC_DIF;                          //范围值
  10.                                         if(B_VALUE_temp2<POWER_AGE_VALUE)          //更新值
  11.                                         {
  12.                                                 B_VALUE_temp1=POWER_AGE_VALUE;
  13.                                         }
  14.                                 }
  15.                                 else
  16.                                 {
  17.                                         B_VALUE_temp2=POWER_AGE_VALUE;
  18.                                         B_VALUE_temp2+=ADC_DIF;
  19.                                         if(B_VALUE_temp2<B_VALUE_temp1)          //更新值
  20.                                         {
  21.                                                 B_VALUE_temp1=POWER_AGE_VALUE;
  22.                                         }
  23.                                 }

  

2.3 AD值定时比较

先取一个A值,然后开始计时。如果AD值比较稳定,就在计时结束,确认为A值;如果AD值反复跳变,就清除计时,不能确认为A值。

  1. //AD值在某一段电压范围内,就用DISCHARGE_AD_NUM表示某档位
  2. //c_ad_wait_old,c_ad_wait_end 用来表示暂存档位值
  3. //c_ad_wait_time 表示时间计数


  4. void POWER_ADC_Discharge_RUN_PRO_10(void)
  5. {
  6.                  
  7.                 if(POWER_AGE_VALUE >= DIS_ADC_VALUE_F0)         
  8.             {
  9.                            DISCHARGE_AD_NUM=1;          
  10.             }
  11.             if(POWER_AGE_VALUE >= DIS_ADC_VALUE_F1)
  12.             {           
  13.                                 DISCHARGE_AD_NUM=2;
  14.             }
  15.             if(POWER_AGE_VALUE >= DIS_ADC_VALUE_F2)
  16.             {           
  17.                                 DISCHARGE_AD_NUM=3;
  18.             }
  19.                 if((POWER_AGE_VALUE >= DIS_ADC_VALUE_F3))
  20.             {
  21.                                 DISCHARGE_AD_NUM=4;               
  22.             }

  23.         if(DISCHARGE_AD_NUM==c_ad_wait_old)
  24.          {
  25.            ++c_ad_wait_time;
  26.            if(c_ad_wait_time>=20)
  27.            {
  28.                             c_ad_wait_time=0;
  29.                           c_ad_wait_end=c_ad_wait_old;
  30.                        
  31.            }
  32.          }
  33.          else
  34.          {
  35.            c_ad_wait_old=DISCHARGE_AD_NUM;
  36.            c_ad_wait_time=0;
  37.          }
  38.           
  39. }



单片小菜 发表于 2022-12-27 10:21 | 显示全部楼层
学习了,不错的方法
sesefadou 发表于 2023-1-5 12:27 | 显示全部楼层
这个ADC的精度跟很多的因素有关系的。
linfelix 发表于 2023-1-5 13:16 | 显示全部楼层
ADC的性能非常高。              
uytyu 发表于 2023-1-5 13:36 | 显示全部楼层
这个最好使用外部的ADC模块              
loutin 发表于 2023-1-5 14:04 | 显示全部楼层
选择一个稳定的参考电压芯片吧。              
七毛钱 发表于 2023-1-5 15:19 来自手机 | 显示全部楼层
学习了,不错的方法
wwppd 发表于 2023-1-5 15:49 | 显示全部楼层
不同的ADC之间存在干扰吗              
phoenixwhite 发表于 2023-1-6 13:24 | 显示全部楼层
检测准确对芯片的要求比较高。              
primojones 发表于 2023-1-6 16:53 | 显示全部楼层
可以做一个滤波的算法的。              
phoenixwhite 发表于 2023-1-6 18:11 | 显示全部楼层
这个是什么芯片的代码?              
timfordlare 发表于 2023-1-6 18:51 | 显示全部楼层
我一般都是通过滤波算法降低信号的影响。
chenjun89 发表于 2023-1-11 19:34 来自手机 | 显示全部楼层
要做校准,和滤波处理。
mnynt121 发表于 2023-2-7 21:59 | 显示全部楼层
ADC检测精准如何判断?              
ccook11 发表于 2023-2-7 22:14 | 显示全部楼层
这个采样稳定性怎么样?              
hilahope 发表于 2023-2-8 12:49 | 显示全部楼层
这个分压电阻可靠性如何?              
yeates333 发表于 2023-3-4 22:42 | 显示全部楼层
ADC之间是否存在干扰?              
tifmill 发表于 2023-3-10 10:46 | 显示全部楼层
可以通常通过滤波算法来减少信号的影响。
hearstnorman323 发表于 2023-3-10 11:51 | 显示全部楼层
ADC之间是否存在干扰?              
alvpeg 发表于 2023-3-10 14:11 | 显示全部楼层
该ADC的精度与许多因素有关。              
您需要登录后才可以回帖 登录 | 注册

本版积分规则

109

主题

1988

帖子

1

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