📄 main.c
字号:
//真空度: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 + -