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值。 //取一份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;
}
}
|