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; } }
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; } }
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; } }
举报
本版积分规则 发表回复 回帖并转播 回帖后跳转到最后一页
109
1988
1
扫码关注 21ic 官方微信
扫码关注嵌入式微处理器
扫码关注电源系统设计
扫码关注21ic项目外包
扫码浏览21ic手机版
本站介绍 | 申请友情链接 | 欢迎投稿 | 隐私声明 | 广告业务 | 网站地图 | 联系我们 | 诚聘英才
京公网安备 11010802024343号