昨天见到一位朋友的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;
}