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

📄 main.c

📁 以LPC2194为平台开发的整车ECU控制器程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	 //真空度:70-74
	 else if(ADC_data1<=533*k1/k2&&ADC_data1>403*k1/k2)
	 {
	 	vacuum_pressure=70+((533*k1/k2-ADC_data1)/26*k2/k1);
	 }
	 //真空度:75+
	 else if(ADC_data1<=403*k1/k2&&ADC_data1>100*k1/k2)
	 {
	 	vacuum_pressure=75+((403*k1/k2-ADC_data1)/12*k2/k1);
	 }
	 else if(ADC_data1<=100*k1/k2)  vacuum_pressure=0;//真空压力电压小于100认为损坏为0
	 
}

/****************************************************************************
* 名称:IRQ_Time0()
* 功能:定时器0中断服务程序,取反LEDCON控制口。
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq  IRQ_Time0(void)
{  
  counter++; //里程时间计数
  counter1++; 
  
  alarm();
  
  //内部喂狗
  RstWdt();	
  
  //逻辑判断                              							
  Logic();												
   
  //****************************706看门狗复位实现*******************************
  //706芯片脉冲个数计数
  counter7++;
  //交替给WDI高低脉冲
  if(counter7==6)
  {
  	  	WDI_flag=~WDI_flag;			
  	  	counter7=0;
  }
  //*****************************************************************************
   
  //**************************真空泵控制电路MOS管判损坏***************************
  if(MOS_flag==0)  
  {
	 	 //输出信号和控制信号不同则表明MOS管损坏
	 	 if(((IOstate0&o_Zhenkongbeng==0)&&(IOstate1&i_test))||((IOstate0&o_Zhenkongbeng)&&(IOstate1&i_test==0)))
	 	 counter8++; 
	 	 else counter8=0;
  }
  if(counter8>=50)										    //MOS管损坏,标志位置1,准备启用备用电路(连续5秒)
  {
	 	 MOS_flag=1;
	 	 counter8=0;
	 	 IO1SET=o_ready;									    //继电器跳转
	 	 DelayNS(1);
  }
  //******************************************************************************
  
  //******************************水压和碰撞告警检测******************************
  //水压过低告警检测
  if(shuiya_alarm_flag==0)
  {
  		if(IOstate0&i_ShuiYaKaiGuan)//无告警
  		{
  			counter15=0;
  		}
  		else counter15++;
  		if(counter15>=50)	
  		{
  			counter15=0;
  			shuiya_alarm_flag=1;
  		}
  }
  //******************************************************************************
 
  //************************传感器检测(0.05秒一次)*******************************
  //水温传感器判损坏
  if((ADC_data0<100||ADC_data0>3000)&&(flag_shw==0))
  {
 	  	counter4++;
  }
  else 
  {
 	  	counter4=0;
  }
  if(counter4>=300)										    //连续20秒钟损坏则视为水温传感器已经损坏
  {
 	  	flag_shw=1;
 	  	counter4=0;	
 	  	shuiwen_flag=1;									    //可以考虑不清零
  }	
  //真空压力传感器判损坏
  if((ADC_data1<100*k1/k2||ADC_data1>3000*k1/k2)&&(flag_zhkb==0))
  {
		counter2++;											//真空泵损坏标志
  }
  else 
  {	
 	 	counter2=0;	 
  }
  if(counter2>=200)											//连续20秒损坏则视为真空压力传感器已经损坏
  {
 	  	flag_zhkb=1;
 	  	counter2=0;	
 	  	zhenkong_flag=1;										//可以考虑不清零
  }
  if((flag_zhkb==1)&&(flag_zhkbkq==0))						//真空压力传感器损坏后计时20秒开启真空泵,且第1次开启
  {
 	  	counter3++;
  }
  if((IOstate0&i_JiaoSha)&&(flag_zhkbjsh==1))				//刚踩过脚刹且脚刹已松开,此时要继续计时5秒开启
  {
 	  	counter5++;
  }   
  //车速传感器判损坏
  /*if(chesu_flag==0)
  {
	  if(speed==0&&MG2_rad>=305)				//电机转速和车速比为61:1,取5公里
	  {
	  		counter11++;
	  }
	  if(counter11>=200)//20秒钟车速和电机转速不等则认为传感器损坏
	  {
	  		chesu_flag=1;
	  		counter11=0;
	  }
  }*/
  //碰撞告警。连续0.3秒判为有告警
  if(pengzhuang_flag==0)
  {
	  if(infoalarm_2.Bits.pengzhuang==1)
	  {
	  		counter12++;
	  }
	  else counter12=0;
	  if(counter12>=3)
	  {
	  		pengzhuang_flag=1;
	  }
  }
  //冷却水压过低故障
  if(shuiya_flag==0)
  {
  	  if(infoalarm_1.Bits.water_press==2)
  	  {
  	  		counter13++;
  	  }
  	  if(counter13>=200)
  	  {
  	  		shuiya_flag=1;//传感器损坏
  	  		counter13=0;
  	  }
  }
  
  //*****************************************************************************
  
  //**********************************车速、里程计算*****************************
  if(counter==1)
  {
	   counter=0;
	   T1CCR = 0xA00;//开timer1用于捕获脉冲,0.1秒钟进一次中断,只有这时才有可能捕获到脉冲。
	   if(error!=0) 
	   {
	   		speed=110592/error; 			//计算脉冲数,ECU进行了100分频,所以为110592
	   }									//error为两次捕获之间的时间差,被110592除就是脉冲数了。
	   if(speed>=285)
	   {
	   		speed=speedold;					//车速计算处理,防止计算错误
	   }
       if(speed-speedold>20)                //车速增长过快的话不合理,软件让其长慢点。
       {									//根据资料,脉冲数乘以0.7即为车速。
    	    speed=speedold+(speed-speedold)/4;
       }
       if(speedold-speed>20)
       {
    	    speed=speedold-(speedold-speed)/4;
       }
	   
	   //车速为0判断
	   if(odo5==odo4)
	   {
	    	counter6++;
	   }
	   else counter6=0;
	   if(counter6>=8)
	   {
	    	speed=0;				//odo4只在timer1里面才会加一,若0.8秒之后还和odo5相等,则车速不对。
	   }
	    
	   odo1+=speed/5;			//脉冲数累加
	   odo1_dlt+=speed/5;
	   if(odo1_dlt>=(pulse_number*10)) //每0.1公里的脉冲数为1008,这里表示里程增加了1公里。
	   {
	     	odo1_dlt=odo1_dlt-pulse_number*10; //减少脉冲数丢失
	     	flag_rec=1;//通过置位该标志位来表示里程又加了一,可以存储了。
	   } 
	   if(speed<=7&&speed>0)  //车速在0-4之间时就要存储里程。
	   {
	   		
	   		flag_speed=1;  
	   }  
	   odo=odo1/pulse_number;
	   //odo=0;
	   odo_buf[0]=odo;odo_buf[1]=odo>>8;odo_buf[2]=odo>>16;
	   CANSendData_29bit(CAN1,65328,speed*7/10,odo);DelayNS(2);//发送车速、里程
	   speedold=speed;
	   odo5=odo4;
  }
                            								//判别告警报文数据
  if(counter1==3)  CANSendData_29bit(CAN1,65330,0,0);  DelayNS(2);//发送AD值 
  if(counter1==6)    CANSendData_29bit(CAN1,65490,0,0);  DelayNS(2);//状态报文发送
  if(counter1==10)      
  {																	//1秒发送1次
	   counter1=0;
	   CANSendData_29bit(CAN1,65522,0,0); 								//发送告警数据   
	   DelayNS(2);
  }
  
  //VIN发送
  if(vin_flag==1)
  {
  	counter16++;
  	if(counter16==1)    CANSendData_29bit(CAN1,65329,1,0);  DelayNS(2);
  	if(counter16==3)	CANSendData_29bit(CAN1,65329,2,0);  DelayNS(2);
  	if(counter16==5)	CANSendData_29bit(CAN1,65329,3,0);  DelayNS(2);
  	if(counter16==7)	CANSendData_29bit(CAN1,65329,1,0);  DelayNS(2);
  	if(counter16==9)	CANSendData_29bit(CAN1,65329,2,0);  DelayNS(2);
  	if(counter16==11)	CANSendData_29bit(CAN1,65329,3,0);  DelayNS(2);
  	if(counter16==13)	CANSendData_29bit(CAN1,65329,1,0);  DelayNS(2);
  	if(counter16==15)	CANSendData_29bit(CAN1,65329,2,0);  DelayNS(2);
  	if(counter16==17)	CANSendData_29bit(CAN1,65329,3,0);  DelayNS(2);
  	if(counter16==19)	CANSendData_29bit(CAN1,65329,1,0);  DelayNS(2);
  	if(counter16==21)	CANSendData_29bit(CAN1,65329,2,0);  DelayNS(2);
  	if(counter16==23)	
  	{
  		vin_flag=0;
  		counter16=0;
  		CANSendData_29bit(CAN1,65329,3,0);  DelayNS(2);
  	}
  }
  
  //版本号报文发送
  if(banben_flag==1)
  {
	  banben_flag=0;
	  CANSendData_29bit(CAN1,512,0x70702,0x70602);DelayNS(2);
  }
  
  //发送故障代码
  if(counter10!=0)
  {
  	if(DTC_ecu_flag==1)//主控模块
  	{
  		CANSendData_29bit(CAN1,768,0x11,(*(ecu_array+counter10)).Word);DelayNS(2);
  	}
  	counter10=counter10-1;
  }
  if(counter10==0)
  {
  	DTC_ecu_flag=0;
  }
  //****************************************************************************
  
  T0IR = 0x02;	    			            			// 清除中断标志
  VICVectAddr = 0x00;				        			// 通知VIC中断处理结束
}

/****************************************************************************
* 名称:IRQ_Time1()
* 功能:定时器1中断服务程序
* 入口参数:无
* 出口参数:无
****************************************************************************/
void __irq  IRQ_Time1(void)
{ 
      odo4++;
      if(flag==0) 
      {
      	  timer1=T1CR3;
      	  flag=1;	//置位,表示到过第一次脉冲沿了。
      }				//第1次上升沿到
      else if(flag==1) 
      {
      	timer2=T1CR3;
      	flag=0;
      	if(timer2>=timer1)
      	{
      		error=timer2-timer1;//至少要2次捕获才能算出error
      	}
      	else 
      	{
      		error=110592-timer1+timer2;
      	}
      	T1CCR = 0x00;
      } //第2次上升沿到,得到1次跳变周期
      T1IR = 0x80;	    			            		// 清除中断标志
      VICVectAddr = 0x00;				        		// 通知VIC中断处理结束
}

/****************************************************************************
* 名称:Time1Init()
* 功能:仅用于捕获。 
* 入口参数:无
* 出口参数:无
****************************************************************************/
void  Time1Init(void)
{ 
   T1PR = 99;			    							// 设置定时器0分频为100分频,得110592Hz
   T1MCR = 0x02 ;										// 匹配通道0匹配复位T1TC
   T1MR0 = 110592;	    		    					// 设置MR0比较值(1S定时值)
   T1CCR = 0xA00;   									// 上升沿捕获并产生中断
   T1TCR = 0x03;		   								// 启动并复位T1TC
   T1TCR = 0x01; 
}

/****************************************************************************
* 名称:Time0Init()
* 功能:仅用于周期中断。 
* 入口参数:无
* 出口参数:无
****************************************************************************/
void Time0Init(void)
{  
    T0PR = 99;			    							// 设置定时器0分频为100分频,得110592Hz
    T0MCR = 0x03<<3;										// 匹配通道0匹配中断并复位T0TC
    T0MR1 = 110592/10;	    							// 设置MR0比较值(100ms定时值)   
    T0TCR = 0x03;		   								// 启动并复位T0TC
    T0TCR = 0x01; 
}

/*****************************************************************************
*名称:VIC_Init()
*功能:初始化中断
*入口参数:无
*出口参数:无
*****************************************************************************/
void  VIC_Init(void)
{
    EXTMODE=0x0f;                      					// 边沿触发模式
                
    EXTPOLAR=0x00;                     					// 上升沿触发
    VICIntSelect = 0x00000000;		  					// 设置所有中断分配为IRQ中断
    
    VICVectCntl0 = 0x20|5;			   					// 分配定时器中断到向量中断1
    VICVectAddr0 = (int)IRQ_Time1;     					// 设置中断服务程序地址
    VICVectCntl1 = 0x20|4;			   					// 分配定时器中断到向量中断1
    VICVectAddr1 = (int)IRQ_Time0;     					// 设置中断服务程序地址
    VICIntEnable =  (1<<4)|
                    (1<<5);
}

/*****************************************************************************************************
函数原型:void ADC()
参数说明:无
返回值:  无
功能说明:对IO中的模拟量进行AD转换
******************************************************************************************************/
void ADC_Init(void)
{
   ADCR = (1 << 0)                     |				// SEL = 1 ,选择通道0
          ((Fpclk / 1000000 - 1) << 8) | 				// CLKDIV = Fpclk / 1000000 - 1 ,即转换时钟为1MHz
          (0 << 16)                    |				// BURST = 0 ,软件控制转换操作
          (0 << 17)                    | 				// CLKS = 0 ,使用11clock转换
          (1 << 21)                    | 				// PDN = 1 , 正常工作模式(非掉电转换模式)
          (0 << 22)                    | 				// TEST1:0 = 00 ,正常工作模式(非测试模式)
          (1 << 24)                    | 				// START = 1 ,直接启动ADC转换
          (0 << 27);									// EDGE = 0 (CAP/MAT引脚下降沿触发ADC转换)
   DelayNS(10);		
   ADC_data1 = ADDR;                              		//读取ADC结果,并清除DONE标志位,2路全部转换完毕  
 } 

/*****************************************************************************************************
函数原型:filter6(uint16 y[6])
参数说明:无
返回值:  无
功能说明:对模拟量进行精确,除去最大值和最小值其余平均得最厚值
******************************************************************************************************/
uint16 filter6(uint16 y[6])
{
   uint16 i,sum,max,min;
   uint32 sum_temp;
   sum_temp=y[0];max=y[0];min=y[0];
   for(i=1;i<6;i++)
   { sum_temp+=y[i];
     if(y[i]>=max) max=y[i];
     if(y[i]<=min) min=y[i];
   }
   sum=(sum_temp-max-min)>>2;
   return(sum);
}

⌨️ 快捷键说明

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