⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ad_old.h

📁 客车车身控制模块 分为仪表部分 前控左 前控右 尾控和中控程序模块
💻 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 + -