📄 ad_old.h
字号:
#define prewarm_ad_en PTE_PTE2
#define water_ad_en PTE_PTE3
#define sump_ad_en PTE_PTE4
unsigned char tab_fuel[3] = {0x16,0x4d,0x9d};
unsigned char tab_sump[4] = {0x18,0x57,0x79,0x92}; //机油压力刻度采样值
unsigned char tab_water[5] = {0xe3,0x9f,0x7d,0x57,0x3a}; //水温刻度采样值
unsigned char tab_warm[3]= {0xe2,0x7d,0x39}; //预热温度采样值
unsigned char sump_temp[4],water_temp[4],warm_temp[4]; //机油压力、水温、预热温度缓存
unsigned char sump_count=0,water_count=0,warm_count=0; //机油压力、水温、预热温度计数器
sys_data_type _AD_FLAGS; //AD标志
#define sump_flag _AD_FLAGS.Bit.BIT0 //机油压力标志
#define water_flag _AD_FLAGS.Bit.BIT1 //水温标志
#define warm_flag _AD_FLAGS.Bit.BIT2 //预热温度标志
#define ad_flag _AD_FLAGS.Bit.BIT3 //AD滤波标志
#define sampling_flag _AD_FLAGS.Bit.BIT4 //AD采样标志
//******************************************************************************
//函数: void ad_init(void);
//描述: 初始化AD转换器作为单一转换
//参数: none
//返回值: none
//*******************************************************************************
void Init_AD(void)
{
prewarm_ad_en=1;
water_ad_en=1;
sump_ad_en=1;
ADSCR=0x1f;
//ADCH0=1
//ADCH1=1
//ADCH2=1
//ADCH3=1
//ADCH4=1 此时AD电源关闭,AD通道选择
//ADCO=0 单次转换
//AIEN=0 禁止中断
//COCO=0 1转换结束,0忙
ADCLK=0x40;
//0~1为NC
//MODE0=0
//MODE1=0 转换结果为无符号8位
//ADICLK=0 0晶振、1总线
//ADIV0=0
//ADIV1=1
//ADIV2=0 //1Mhz
}
//*******************************************************************************
//函数: unsigned char ad_filter(unsigned char ad_tab[],unsigned char ad_count)
//参数: unsigned char ad_tab[](需处理的数组),unsigned char ad_count(数组长度)
//返回值: 平均值
//说明: 虑除1/4最大值、1/4最小值,取剩余1/2数据平均值
//*******************************************************************************
unsigned char ad_filter(unsigned char ad_tab[],unsigned char ad_count)
{
unsigned char filter_count;
unsigned char filter_break;
unsigned char filter_temp;
unsigned int filter_sum=0;
filter_break=ad_count+1; //循环次数计数器赋值
ad_count--; //数组指针-1
ad_flag=1; //置位排序交换标志
while(ad_flag) //有数据交换,需继续排序
{
ad_flag=0; //清除排序交换标志
filter_break--; //循环计数器-1
if(filter_break==0) //循环计数器为0,排序错误
{
ad_flag=0; //标志清0,表示返回值异常
return 0; //返回0
}
for(filter_count=0;filter_count<ad_count;filter_count++)//排序,由大到小
{
if(ad_tab[filter_count]<ad_tab[filter_count+1]) //前一个数小于后一个数,需交换数据
{
ad_flag=1; //置位交换标志
filter_temp=ad_tab[filter_count]; //数据交换
ad_tab[filter_count]=ad_tab[filter_count+1];
ad_tab[filter_count+1]=filter_temp;
}
}
}
ad_count++; //恢复数组指针
ad_count=(unsigned char)(ad_count/4); //定位求平均区域下限
filter_count=(unsigned char)(ad_count*3); //定位求平均区域上限
while(filter_count>ad_count) //求和
{
filter_count--;
filter_sum+=ad_tab[filter_count];
}
ad_count=(unsigned char)(ad_count*2); //求和区域长度
filter_sum=filter_sum/ad_count; //求平均
ad_flag=1; //返回值正常标志
return (unsigned char)filter_sum; //返回值
}
//*******************************************************************************
//函数: unsigned char ad_single(unsigned char ch);
//参数: unsigned char ch---选择A/D 通道;
//返回值: A/D 转换值
//说明: channel为AD通道取值0-7
//*******************************************************************************
unsigned char ad_single(unsigned char channel)
{
unsigned char ad_count=0;
unsigned char ad[8];
switch(channel)
{
case 3: sump_ad_en=0;
break;
case 5: water_ad_en=0;
break;
case 6: prewarm_ad_en=0;
break;
default:break;
}
ADSCR=0x20+channel; //写ADSCR启动连续AD转换
while(ad_count<8) //8次采样
{
if(ADSCR_COCO==1)
{
ad[ad_count]=ADRL; //取AD寄存器,8位AD量
ad_count++;
}
}
ADSCR=0x1f; //写ADSCR关闭AD转换
switch(channel)
{
case 3: sump_ad_en=1;
break;
case 5: water_ad_en=1;
break;
case 6: prewarm_ad_en=1;
break;
default:break;
}
return ad_filter(ad,8); //返回结果
}
//*******************************************************************************
//函数: void ad_warm_u(void);
//返回值: A/D 转换值对应的CAN报文值(预热温度)
//*******************************************************************************
void ad_warm(void)
{
unsigned char i=0;
unsigned char _warm;
unsigned int temp;
_warm=ad_single(4); //AD采样,AD通道6
if(ad_flag) //返回值正常
{
ad_flag=0; //清除数据异常标志
if(_warm>0xe1) _warm = 40; //<40℃?
else if(_warm<0x3a) _warm = 120; //>120℃?
else
{
while(tab_warm[i]>_warm) i++; //取得上限刻度
_warm = tab_warm[i-1]-_warm;
temp = _warm*40;
_warm = tab_warm[i-1]-tab_warm[i]; //取得下限刻度
temp/=_warm;
temp+=40*i;
_warm=temp%0x100; //最终结果CAN报文值
}
warm_temp[warm_count]=_warm; //暂存
warm_count++; //预热温度计数器+1
if(warm_count==4) //滤波
{
warm_count=0; //预热温度计数器清0
_warm=ad_filter(warm_temp,16); //滤波
if(ad_flag) CAN_CMD6.Byte=_warm; //数据正常编写CAN报文
ad_flag=0; //清除数据异常标志
}
}
}
//*******************************************************************************
//函数: void ad_water(void);
//返回值: A/D 转换值对应的CAN报文值(水温)
//*******************************************************************************
void ad_water(void)
{
unsigned char i = 0;
unsigned char _water;
unsigned int temp;
_water=ad_single(5); //AD采样,AD通道5
if(ad_flag) //返回值正常
{
ad_flag=0; //清除数据异常标志
if(_water>0xe3) _water = 40; //<40℃?
else if(_water<0x3b) _water = 120; //>120℃?
else
{
while(tab_water[i]>_water) i++; //取得上限刻度
_water = tab_water[i-1]-_water; //取得下限刻度
temp = _water*20;
_water = tab_water[i-1]-tab_water[i];
temp = temp/_water;
i--;
temp = temp+20*i+40;
_water = temp%0x100; //最终结果CAN报文值
}
water_temp[water_count]=_water; //暂存
water_count++; //水温计数器+1
if(water_count==4) //滤波
{
water_count=0; //水温计数器清0
_water=ad_filter(water_temp,4); //滤波
if(ad_flag) CAN_CMD5.Byte=_water; //数据正常编写CAN报文
ad_flag=0; //清除数据异常标志
}
}
}
//*******************************************************************************
//函数: void ad_sump(void);
//返回值: A/D 转换值对应的CAN报文值(机油压力)
//*******************************************************************************
void ad_sump(void)
{
unsigned char i = 0;
unsigned char _sump;
unsigned int temp;
_sump=ad_single(6); //AD采样,AD通道5
if(ad_flag)
{
if(_sump<0x2c) _sump = 0x00; //采样值<0x0d2c结果为0x00
else if(_sump>0x91) _sump = 0x26; //采样值>0x91结果为0x26
else
{
while(tab_sump[i]<_sump) i++; //取得上限刻度
_sump = _sump-tab_sump[i-1]; //取得下限刻度
temp = _sump*200;
_sump = tab_sump[i]-tab_sump[i-1];
temp = temp/_sump;
i--;
temp = (temp+200*i)/16;
_sump = temp%0x100; //最终结果CAN报文值
}
sump_temp[sump_count]=_sump; //暂存
sump_count++; //机油压力计数器+1
if(sump_count==4) //滤波
{
sump_count=0; //机油压力计数器清0
_sump=ad_filter(sump_temp,4); //滤波
if(ad_flag) CAN_CMD4.Byte=_sump; //数据正常编写CAN报文
ad_flag=0; //清除数据异常标志
}
}
}
//*******************************************************************************
//函数: void AD_sampling(void);
//说明: A/D 转换过程,每次循环只执行一路AD
//*******************************************************************************
void AD_sampling(void)
{
// if(sampling_flag)
{
// sampling_flag=0;
if(warm_flag) //预热温度
{
ad_warm();
warm_flag=0;
water_flag=1;
sump_flag=0;
}
else if(water_flag) //水温
{
ad_water();
warm_flag=0;
water_flag=1;
sump_flag=0;
}
else if(sump_flag) //机油压力
{
ad_sump();
warm_flag=0;
water_flag=1;
sump_flag=0;
}
else //重新开始检测
{
warm_flag=1;
water_flag=0;
sump_flag=0;
warm_count=0;
water_count=0;
sump_count=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -