ADC检测准确的几种方法

1.硬件分析

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

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

2.软件分析

AD读取越慢越稳定,这个经验在哪家公司的芯片都适用.

AD时钟周期或者转换速率要选择比较大的

2.1 采集AD时进行滤波

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

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


//取一份AD值
unsigned int POWER_Get_Adc_Data12_Average()
{
  unsigned  int  temp_value  = 0;
  unsigned char  channel=0;
  unsigned long int tmpbuff = 0;
  unsigned  int ADCMAX = 0;
  unsigned  int ADCMIN = 0xffff;
   for (channel = 0; channel < 20; channel++)
   {
   		ADCON	=	0x86;		   //通道选择:多通道时不能用|=,只能用|
		ADCON	|=	0x10;		  //启动ADC检测	
		while((ADCON&0x10));	  //等待ADC检测结束

  		temp_value = ADDH;
  		temp_value = (temp_value<<4)|(ADDL&0x0F);
		if (channel < 2)
            continue; //丢弃前两次采样的
		
        if (temp_value > ADCMAX)
            ADCMAX = temp_value; //最大
        if (temp_value < ADCMIN)
            ADCMIN = temp_value; //最小
		
        tmpbuff += temp_value;
	}
		tmpbuff -= ADCMAX;           //去掉一个最大
    	tmpbuff -= ADCMIN;           //去掉一个最小
    	temp_value = (tmpbuff >> 4); //除以16,取平均值
  		return temp_value;
}

//每隔一段时间取一份AD值,再平均
//ADC_CNT 表示时间计数的变量
//POWER_ALL_value 表示AD总值的变量
void POWER_ADC_Electric_PRO(void)
{
	unsigned int  ad_value;
	ad_value = POWER_Get_Adc_Data12_Average();
	ADC_CNT++;
	POWER_ALL_value+=ad_value;
	if(ADC_CNT>=10)
	{
		ADC_CNT=0;		
		POWER_AGE_VALUE=POWER_ALL_value/10;
		POWER_ALL_value=0;
	}		
}

2.2 采取差值计算

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

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

程序如下:

          //B_VALUE_temp1,B_VALUE_temp2  表示暂存AD值的变量
          //POWER_AGE_VALUE   表示记录实时AD值的变量
          // ADC_DIF          表示波动设定值   
          //结果用B_VALUE_temp1取比较AD值
     
            if(B_VALUE_temp1<=POWER_AGE_VALUE)
				{
					B_VALUE_temp2=B_VALUE_temp1;
					B_VALUE_temp2+=ADC_DIF;			  //范围值
					if(B_VALUE_temp2<POWER_AGE_VALUE)	  //更新值
					{
						B_VALUE_temp1=POWER_AGE_VALUE;
					}
				}
				else
				{
					B_VALUE_temp2=POWER_AGE_VALUE;
					B_VALUE_temp2+=ADC_DIF;
					if(B_VALUE_temp2<B_VALUE_temp1)	  //更新值
					{
						B_VALUE_temp1=POWER_AGE_VALUE;
					}
				}

2.3 AD值定时比较

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

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


void POWER_ADC_Discharge_RUN_PRO_10(void)
{
		 
		if(POWER_AGE_VALUE >= DIS_ADC_VALUE_F0)	 
	    {
			   DISCHARGE_AD_NUM=1;	  
	    }
	    if(POWER_AGE_VALUE >= DIS_ADC_VALUE_F1) 
	    {    	
				DISCHARGE_AD_NUM=2;
	    }
	    if(POWER_AGE_VALUE >= DIS_ADC_VALUE_F2) 
	    {    	
				DISCHARGE_AD_NUM=3;
	    }
		if((POWER_AGE_VALUE >= DIS_ADC_VALUE_F3)) 
	    {
				DISCHARGE_AD_NUM=4;		
	    }

	if(DISCHARGE_AD_NUM==c_ad_wait_old)
	 {
	   ++c_ad_wait_time;
	   if(c_ad_wait_time>=20)
	   {
	   	 	c_ad_wait_time=0;
		  	c_ad_wait_end=c_ad_wait_old;
			
	   } 
	 }
	 else
	 {
	   c_ad_wait_old=DISCHARGE_AD_NUM;
	   c_ad_wait_time=0;
	 }
	  
 }

  • 1
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ADC(Analog-to-Digital Converter)是一种电子设备,用于将模拟信号转换为数字信号。它通常用于测量电压和对其他模拟量进行数据转换。 如果ADC检测到的电压不等于0和4095,则可能存在以下几种情况: 1. 故障:ADC可能存在故障或不准确的校准,导致测量结果不在预期范围内。这可能是因为ADC本身的问题,或者由于外部电路的干扰或损坏。 2. 非线性响应:ADC的输出电压与输入电压之间的关系可能是非线性的。这意味着输入电压发生变化时,ADC的输出不是按照线性比例进行转换。这可能导致测量结果不等于预期的0和4095。 3. 输入电压超出范围:ADC通常只能测量在一定范围内的电压。如果输入电压超出了ADC的工作范围,那么测量结果就有可能不等于0和4095。 为了解决这个问题,可以采取以下步骤: 1. 校准ADC:检查ADC是否需要进行校准。如果是,则按照设备的规格说明进行校准。这将确保ADC的输出准确对应于输入电压。 2. 检查电路:检查与ADC相关的电路,确保其正常工作,并排除任何可能的损坏或干扰源。 3. 确认输入范围:查看ADC的规格说明,确认其输入电压范围。确保输入电压不超过规定的范围。 4. 进行线性校准:如果ADC的输出与输入电压之间存在非线性响应,可以尝试进行线性校准。这可以通过校准曲线或查找表来实现,以便将ADC的输出与预期的0和4095对应起来。 总之,如果ADC检测电压不等于0和4095,我们应该检查其校准、电路、输入范围和可能的非线性响应,以确保测量结果准确和可靠。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值