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

📄 main.c

📁 以LPC2194为平台开发的整车ECU控制器程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************Copyright (c)**************************************************
**                              上 海 比 亚 迪 有 限 公 司
**                                     电动汽车研究所
**                                        电控一科
**
**	文   件  	名:	Main.C
**  作          者:丁会利
** 	日		期:	    2006年12月04日
**	描		述:  	主函数
********************************************************************************************************/
#define	_MAIN_GLOBAL_
#include "canapp.h"
#include "config.h"
#include "IncludeCan.H"
#include "Main.h"

void alarm(void);
void Logic(void);
uint16 filter6(uint16 y[6]);					//AD值计算
/******************************数据的定义**********************************/
uint32 IOstate0;
uint32 IOstate1;
uint8  dangwei;        							//定义档位用于主接触器判断
uint16 speedold;
uint16 speed;
//里程存储
uint32 odo1;									//存放正确里程
uint32 odo2;									//存放存储区1的里程
uint32 odo3;									//存放存储区2的里程
uint32 odo4;
uint32 odo5;
uint32 odo1_dlt;
uint8  flag_rec;
uint8 flag_speed;
//=============故障代码==============
uint8 ecu_no;//故障代码个数
uint8 ecu_ch;//新故障代码标识
//==================定时器中的值===============================================
uint16 counter;    								//发送里程、速度
uint16 counter1;   								// 告警数据
/*******************************真空压力传感器损坏后的计数**********************/
uint16 counter2;   								// 5秒计时,到5秒判为损坏
uint16 counter3;   								// 20m钟计时
uint16 counter5;	
uint8 counter7;//706用于计时
uint8  WDI_flag;//706复位标识
/*******************************************************************************/
/**************************水温传感器损坏后的计数*******************************/
uint16 counter4;   								// 5秒计时
/*******************************************************************************/
#define pulse_number    1008  //0.1公里的脉冲数
uint8  odo_buf[40];	
uint8  odo_buf1[40];	
uint8  odo_buf2[40];
uint16 l_odo_buf[40];
uint16 l_odo_buf1[40];
uint16 l_odo_buf2[40];
uint16 l_odo_buf3[40];
uint8  flag_odo;								//判断上电后读取的里程是否都为非法的
uint8 i;
uint32 timer1,timer2,error;						//脉冲周期计算
uint8 flag;
uint32 counter6;
uint8 flag_cutd;								//主接触器关断标识
uint8 flag_zhkb;								//真空压力传感器损坏标志
uint8 flag_zhkbkq;								//损坏后真空泵开启标志
uint8 flag_zhkbjsh;								//损坏后踩脚刹标识
uint8 flag_shw;									//水温传感器损坏标志
uint8 flag_moto;								//发动机启动后首先执行一次状态标志
uint8 flag_outtemp;
uint8 flag_outtemp1;
//真空泵电路MOS管判坏
uint8 MOS_flag;									//MOS损坏标志
uint8 counter8;									//MOS管损坏计时
//故障代码发送计数
uint8 counter10;
//故障代码发送函数:各模块发送标志
uint8 DTC_ecu_flag;
//车速传感器判断用数据
uint16 MG2_rad;//MG2转速
uint8 counter11;//用于车速传感器损坏计数
//uint8 chesu_flag;//车速传感器损坏标志位
//碰撞故障代码判断用数据
uint8 counter12;
uint8 pengzhuang_flag;
//水温传感器故障代码
uint8 shuiwen_flag;
//真空压力传感器故障代码
uint8 zhenkong_flag;
//冷却水压过低故障判别用数据
uint8 shuiya_flag;
uint8 shuiya_alarm_flag;//用于告警报文中的判断标识位,当连续出现5秒后为有告警
uint8 counter15;//水压过低告警计时
uint8 counter13;
uint8 counter16;
//CAN通讯故障计数
//uint8 counter17;
//uint8 CAN_flag;
uint8 flag_lengque;



/****************************************************************************
* 名称:RstWdt()
* 功能:看门狗喂狗操作。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void  RstWdt(void)
{  WDFEED = 0xAA;
   WDFEED = 0x55;
}

/****************************************************************************
* 名称:delay()
* 功能:短软件延时   0.5ms左右
* 入口参数:dly		延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void  delay(uint32  dly)
{  uint32  i;

   for(; dly>0; dly--) 
      for(i=0; i<6000; i++);
}

/****************************************************************************
* 名称:DelayNS()
* 功能:长软件延时  5ms左右
* 入口参数:dly		延时参数,值越大,延时越久
* 出口参数:无
****************************************************************************/
void  DelayNS(uint32  dly)
{  uint32  i;

   for(; dly>0; dly--) 
      for(i=0; i<50000; i++);
}

/******************************************************************************
**函数:void Init_T_D_Data(void)
**参数:  无
**返回值:无
**说明:对不同的模块的故障代码存储数组进行必要的指针类型转化,达到指针对应数组
**      的关系。
******************************************************************************/
void Init_T_D_Data(void)
{
  ecu_array =(pTrouble_prefix)ECU_Array;			//主控ECU数据转换
  pcanData=(pRCV_candata)rec_canData;
} 


/*****************************************************************************
**函数:uint8 Storage_Array(Trouble_type type,pTrouble_prefix Array,
**                             uint16 candata,uint8 n)
**参数:    Trouble_type      type:   故障的类型
**          pTrouble_prefix   Array:  参数数组的指针
**          uint16            candata:要存入的数据
**          uint8             n      :存入数组的位置
**返回值: :0 :存储成功
**         :1 :存储失败
**说明: 用于各个模块的数据存储,对接收到的不同的数据进行相应模块的存储
**       如果模块故障数组中存在其中一个故障代码,就不存储,不存在并达到
**       要求的故障代码就存储。 
******************************************************************************/
void Storage_Array(Trouble_type type,pTrouble_prefix Array,uint16 candata,uint8 n) //查询故障代码是否已经存在
{
  uint8 status=0;									//有新的故障码
  uint8 num;
  switch(type)
  {
    case M_ECU:
      if(n<=0x09||n==0x29||n==0x30)
      {
	      for(num=1;num<=ecu_no;num++)
	      {
	        if(candata==(*(ecu_array+num)).Word) {status=1; break;}   //故障代码已存在
	        else status=0;
	      }
	      if(status==0)
	      { 
	          ecu_array->Bits.trouble_counter++;        //故障代码个数+1
	          ecu_no++;
	          (*(ecu_array+ecu_no)).Word=candata;
	          ecu_ch=1;                                 //新故障代码标识
	      } 
      } 
      break;
     default :break;
  }
}

/*****************************************************************************
**函数:uint8 Delete_Array(Trouble_type type,pTrouble_prefix Array,
**                             uint16 candata,uint8 n)
**参数:    Trouble_type      type:   故障的类型
**          pTrouble_prefix   Array:  参数数组的指针
**          uint16            candata:要删除的数据
**          uint8             n      :数组的位置
**说明: 用于各个模块的数据清除
******************************************************************************/
void Delete_Array(Trouble_type type,pTrouble_prefix Array,uint16 candata,uint8 n) //查询故障代码是否已经存在
{
  uint8 status=0;									//有新的故障码
  uint8 num;
  switch(type)
  {
    case M_ECU:
      if(n<=0x09||n==0x29||n==0x30)
      {
	      for(num=1;num<=ecu_no;num++)
	      {
	        if(candata==(*(ecu_array+num)).Word)  //故障代码已存在
	        {
	        	ecu_array->Bits.trouble_counter--;        //故障代码个数-1
	          	for(;num<ecu_no;num++)
	          	{
	          		(*(ecu_array+num)).Word=(*(ecu_array+num+1)).Word;
	          	}
	          	(*(ecu_array+ecu_no)).Word=0;
	          	ecu_no--;
	          	ecu_ch=1; 
	          	break;
	        }
	        else status=0; 
	      }
      } 
      break;
     default :break;
  }
}

/*****************************************************************************
**函数:RCV_TD(void)
**参数:无
**返回值:无
**说明:用于接收到的把所有的故障代码按照不同的类型进行存储到相应的数组中,或者对
	    故障清除进行操作。
*****************************************************************************/
void RCV_TD(void)
{
     uint16 candata;
     uint8 n; 
     
     /**************************故障代码接收********************************/
     if(DTC_flag==1&&DTC_num!=0)   //接收故障代码
     {
       for(i=0;i<DTC_num;i++)
       {
         candata=DTC_array[i];
         candata=(DTC_type[i]<<8)|candata;
         n=DTC_array[i];
         switch(DTC_type[i])
         {
           //主控ECU模块
           case 0x93:
             Storage_Array(M_ECU,ecu_array,candata,n);
             break;
           default: break;
         }
       } 
     }
     /********************************************************************************/
     
     /******************************故障代码清除********************************/
     else if(DTC_flag==0&&DTC_num!=0)   //清除故障代码
     {
     	 candata=DTC_array[0];
         candata=(DTC_type[0]<<8)|candata;
         n=DTC_array[0];
         
         switch(DTC_type[0])
         {
           //主控ECU模块
           case 0x93:
             Delete_Array(M_ECU,ecu_array,candata,n);
             break;
           default: break;
         }
     }
     /********************************************************************************/
}

/**********************************2006.11.3添加里程校验*******************************/
/****************************************************************************
* 名称:xiaoyan(uint8 *buf3)
* 功能:用来对里程数据进行写校验
* 入口参数:addr:代表要进行校验的数组的首地址
* 出口参数:无
****************************************************************************/
void xiaoyan(uint8 *buf3)
{
	uint16 add1;
	uint8  add;								//前3位的ADD
	uint8  XOR;
	if(buf3[0]+buf3[1]>0xFF)
	{
		add1=buf3[0]+buf3[1]-0xFE;
	}
	else add1=buf3[0]+buf3[1];
	if(add1+buf3[2]>0xFF)
	{
		add1=add1+buf3[2]-0xFE;
	}
	else add1=add1+buf3[2];
	add=add1;								//前3个数字的和,为第4个数字
	buf3[3]=add;
	
	XOR=buf3[0]^buf3[1];
	XOR=XOR^buf3[2];
	XOR=XOR^buf3[3];
	buf3[4]=XOR;	
	
}

/****************************************************************************
* 名称:de_xiaoyan(uint8 *buf3)
* 功能:用来对里程数据进行解校验
* 入口参数:addr:代表要进行校验的数组的首地址
* 出口参数:无
****************************************************************************/
uint8 de_xiaoyan(uint8 *buf3)
{
	uint8 XOR;
	//计算XOR
	XOR=buf3[0]^buf3[1];
	XOR=XOR^buf3[2];
	XOR=XOR^buf3[3];
	if(XOR==buf3[4])
	{
		return (1);
	} 
	else 
	{
		return(0);
	}
}

/*******************************2006.12.25添加******************************/
//2007.3.16调通
/****************************************************************************
* 名称:void write_eeprom(uint16 Addr,uint16 Data)
* 功能:IO口模拟SPI写数据
* 入口参数:
* 出口参数:
****************************************************************************/
void write_eeprom(uint16 Addr,uint16 Data)
{
  uint16 AADDR;
  uint32 DDATA;
  uint8 m;
  uint16 ewen=0x1300;
  uint16 ewds=0x1000;
  AADDR = Addr & 0x03ff;
  AADDR = AADDR|0x1400;			//高13位格式
  DDATA = AADDR;
  DDATA = (DDATA<<16)|Data; 	//转换为29为格式
  DDATA = DDATA<<3;				//左移3位,将高位0清除
  //写允许命令
  IO1SET = CS;
  for(m=0;m<=12;m++)
  {
     if((ewen & 0x1000)==0x1000)
         IO0SET = MOSI0;
     else IO0CLR = MOSI0; 
     IO0CLR = SCK0;
     IO0SET = SCK0;
     ewen = ewen << 1;
   }
  IO1CLR = CS;
  //数据写入
  IO1SET = CS;    
  for(m=0;m<=28;m++)
  {
     if((DDATA & 0x80000000)==0x80000000)
         IO0SET = MOSI0;
     else IO0CLR = MOSI0; 
     IO0CLR = SCK0;
     IO0SET = SCK0;
     DDATA = DDATA << 1;
   }  
  IO1CLR = CS;
  //写禁止命令
  IO1SET = CS;
  for(m=0;m<=12;m++)
  {
     if((ewds & 0x1000)==0x1000)
         IO0SET = MOSI0;
     else IO0CLR = MOSI0; 
     IO0CLR = SCK0;
     IO0SET = SCK0;
     ewds = ewds << 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -