地址:https://www.eefocus.com/luo_xinli/blog/14-08/305172_d5794.html
昨天见到一位朋友的AD采集代码,这段代码在他们公司产品中已经使用的。当然是正确的。我们来分析一下他的实现方法。 - 选择采集端口,采集端口电压,保存在 temp_l 、 Min_Value、 Max_Value中
- 采集端口电压7次,每次采集的值与 Min_Value、 Max_Value比较。如果小于 Min_Value将其值赋给 Min_Value,如果大于 Max_Value将其值赋给 Max_Value。并且将其值累加到numtemp 值中。
- numtemp 减去 Min_Value、 Max_Value,结果除于5.该结果就是本次采集的电压值。
这段代码的中心目的就是,采集7个值,去掉最大和最小的值,然后求平均值即可。过程很简单,流程图就不给出了。代码如下: /********************************************************
函数名: read_ad_inputs
功能 : 采集电压 充电或者是电池的电压
参数 : 无
返回值: 无
**********************************************************/
UINT read_ad_inputs(BYTE PORT)
{
char i = 0;
unsigned long numtemp = 0;
UINT Max_Value = 0;
UINT Min_Value = 0;
UINT temp = 0,ams = 0,temp_l = 0;
init_adc(); //重新初始化AD
switch(PORT)
{
// case Charge_ADV: //采集充电电压
// AMX0P = 0x0D; //正输入极为P25
// break;
case BATT_ADV: //电池电压
AMX0P = 0x0E; //P26为AD正输入端
break;
case TEMPE:
REF0CN |= 0x04; //内部温度传感器工作
AMX0P = 0x1E; //正输入端选择内部温度传感器
default:
break;
}
Delay_ms(2); //等待稳定
AD0INT = 0; //清除转换完成标志
AD0BUSY = 1; //initiate conversion
while (AD0INT == 0); //等待转换完成
temp = ADC0H; //高字节
ams = ADC0L; //低字节
temp = temp<<8;
temp_l = temp+ams;
Min_Value = temp_l; //取一次参考值
Max_Value = temp_l;
for(i = 0; i < 7; i++)
{
AD0INT = 0; //清除转换完成标志
AD0BUSY = 1; //initiate conversion
while (AD0INT == 0); //等待转换完成
temp= ADC0H; //高字节
ams = ADC0L; //低字节
temp = temp<<8;
temp_l = temp+ams;
if(temp_l >= Max_Value) //取最大值
{
Max_Value = temp_l;
}
if(temp_l <= Min_Value) //取最小值
{
Min_Value = temp_l;
} //累加
numtemp += temp_l;
}
numtemp -= Max_Value; //减去最大和最小两个值
numtemp -= Min_Value;
if(numtemp > 0xFFFF) //超出为错误,否则求平均数并返回值
{
temp_l = 0xFF;
}
else
{
temp_l = numtemp/5;
}
return temp_l;
}
|