#include "MAIN.H" #include "RTC.H" #include "temperature.H" #include //can信息 UnInfCan UnInfCan_1 = {0}; UnSwOut UnSwOut_1 = {0}; //CAN发送周期 uword CntCan_1 = 0; bit FlgCan_1 = 0; //第一次采集到有效数据指示 bit FlgOneTime = 0; uword RgCanPerid = 1000; UnTimeOutput sleeptime = {0}; UnTimeOutput waketime = {0}; UnTimeOutput currenttime = {0}; UnTimeOutput inittime = {00,1,1,0,0,0,0,0};// 默认设置 2000年,1月1日 周日,0:0:00 UnTimeOutput un_time_output1 = {0};//接收设定时间 UnInfCanKGFOutput un_inf_can_kgf_output2 = {0};//kgf输出 UnInfCanKGFOutput un_inf_can_kgf_output1 = {0};//kgf输出 UnInfCanKGFOutput un_inf_can_kgf_output3 = {0};//kgf或结果 UnInfCanKGFOutput un_inf_can_kgf_output4 = {0};//kgf或结果 UnSampleKgfCommand un_sample_kgf_command = {0};//kgf转发 UnTimeOutput waketimelast = {0}; UnTimeOutput wake_time_10min = {0}; SystemState sleepstate = STATE_INIT; //PWM 20181227 ubyte PwmH[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; ubyte powerstate = 0;//电源状态 ubyte vcu_can_cnt = 0; // 帧累加器 ubyte vcu_can_last = 0; // 帧累加器过去值 bool flg_wake_ecu = 0; //控制器唤醒标志 bool flg_KGF = 0;//KGF唤醒标志 ubyte can_error_cnt = 0; ubyte can_error_flg = 0; //----------------------------------------------------------------------- //RTC定时器 //----------------------------------------------------------------------- void RTCProcess(void) { //************************************************************************ //////CAN发送周期 if(FlgCan_1){CntCan_1++;if(CntCan_1 >= RgCanPerid){FlgCan_1=0; CntCan_1=0;}}else{CntCan_1=0;} //************************************************************************ } //can错误处理 void CanErrorProcess(void) { ubyte ubNSRL; ubyte ubNSRH; ubyte ubResetLEC = 0x3F; //------------------------------------------- EA = 0; CAN_pushAMRegs(); // push the CAN Access Mediator Registers SFR_PAGE(_su0, SST0); // switch to page 0 CAN_vWriteCANAddress(CAN_NSR0); CAN_vReadEN(); ubNSRL = CAN_DATA0; ubNSRH = CAN_DATA1; if (ubNSRL & 0x20) // if ALERT { CAN_vInit(); } if (ubNSRL & 0x07) // if LEC { ubResetLEC = 0x38; } //// Reset LEC, TXOK, RXOK, ALERT, EWRN, BOFF, LLE, LOE (if set) CAN_vWriteCANAddress(CAN_NSR0); // Addressing CAN_NSR0 CAN_DATA0 = ~(ubNSRL & ubResetLEC); // load CAN_NSR0 status register[7-0] CAN_DATA1 = ~(ubNSRH); // load CAN_NSR0 status register[15-8] CAN_vWriteEN(D0_VALID+D1_VALID); // Data0 and Data1 are Valid for SFR_PAGE(_su0, RST0); // restore the old SCU page CAN_popAMRegs(); // restore the CAN Access Mediator Registers EA = 1; } void CanTransmit(void) { //----------------- -------- // 装载数据 if(1 == flg_KGF)//等待KGF唤醒后再发送数据 { CAN_waitTransmit(DF_SwTx);//发送前等待上一帧发送完毕,这样不会丢帧 CAN_vLoadData(DF_SwTx, (ulong *)(&UnInfCan_1.ArrData.Arr[0][0])); CAN_vTransmit(DF_SwTx); } } void canSendTo(ubyte index,ubyte *buf) { ubyte CanTransmitbuf[8] = {0,0,0,0,0,0,0,0}; //----------------- -------- CanTransmitbuf[2] = buf[0]; CanTransmitbuf[3] = buf[1]; CanTransmitbuf[0] = buf[2]; CanTransmitbuf[1] = buf[3]; CanTransmitbuf[6] = buf[4]; CanTransmitbuf[7] = buf[5]; CanTransmitbuf[4] = buf[6]; CanTransmitbuf[5] = buf[7]; CAN_waitTransmit(index);//发送前等待上一帧发送完毕,这样不会丢帧 CAN_vLoadData(index, (ulong *)CanTransmitbuf);// 装载数据 CAN_vTransmit(index); } //CAN发送一帧 void CanTX(void) { //----------------------------------- UnInfCan_1.ArrData.Arr[0][3] = currenttime.bit_data.year; UnInfCan_1.ArrData.Arr[0][2] = currenttime.bit_data.month; UnInfCan_1.ArrData.Arr[0][1] = currenttime.bit_data.day; UnInfCan_1.ArrData.Arr[0][0] = currenttime.bit_data.hour; UnInfCan_1.ArrData.Arr[0][7] = currenttime.bit_data.week; UnInfCan_1.ArrData.Arr[0][6] = currenttime.bit_data.minute; UnInfCan_1.ArrData.Arr[0][5] = currenttime.bit_data.second; UnInfCan_1.ArrData.Arr[0][4] = waketime.bit_data.day; CanTransmit(); } //休眠处理函数 //------------------------------------------------------------------ void SystemStateMachine(SystemState *RgSTT) { //---------------------------------------------- switch (*RgSTT) { //------------------------------------------- case STATE_INIT: if(NORMAL == flg_wake_ecu)//控制器唤醒 { bm8563SetAlarm(&waketime); //设置唤醒时间 memcpy(&waketimelast,&waketime,sizeof(UnTimeOutput)); *RgSTT = STATE_ON; } else { *RgSTT = STATE_INIT; } break; case STATE_ON: if(bm8563CheckAlarmFlag())//唤醒时间到以及高压开关关闭 { bm8563SetTime(&inittime);//20250802 初始化时间 解决因为时间不对导致无法休眠问题 bm8563SetAlarm(&sleeptime);//设置休眠时间 KGF_PIN = 0; //KGF休眠 CAN_PIN = 1; //can芯片休眠 BATTERY_PIN = 0;//电池休眠 *RgSTT = STATE_INIT; // 初始化状态 PS_vSetPowerDown();//休眠 } else if(0 != memcmp(&waketimelast,&waketime,sizeof(UnTimeOutput)))//比较值是否一样,不一样的话立马更新 { memcpy(&waketimelast,&waketime,sizeof(UnTimeOutput)); bm8563SetAlarm(&waketime); *RgSTT = STATE_ON; // 保持状态(唤醒后由中断处理) } else if( (POWER_WORKING == powerstate) || (POWER_EMERGENCY == powerstate) )//等于工作状态 { *RgSTT = STATE_ON2; // 进入STATE_ON2 } else { *RgSTT = STATE_ON; // 保持 } break; case STATE_ON2: if( POWER_STANDBY == powerstate )//总开关关闭或者进入standy { bm8563SetTime(&inittime);//20250802 初始化时间 解决因为时间不对导致无法休眠问题 bm8563SetAlarm(&sleeptime); KGF_PIN = 0; //KGF休眠 CAN_PIN = 1; //can芯片休眠 BATTERY_PIN = 0;//电池休眠 *RgSTT = STATE_INIT; // 保持状态(唤醒后由中断处理) PS_vSetPowerDown();//休眠 } else { *RgSTT = STATE_ON2; // 保持 } break; default:; } } //CAN发送接收 void CanRXTX(void) { stCAN_SWObj StrCanRx = {0}; uword tmp = 0; ubyte i = 0,j = 0; uword TimeTemp = 0; uword HoursTemp = 0; uword DaysTemp = 0; //------------------------------------ if(CAN_ubNewData(DF_RXTIME)) { CAN_vGetMsgObj(DF_RXTIME, &StrCanRx); un_time_output1.arr[3] = StrCanRx.ulDATAL.ubDB[0]; un_time_output1.arr[2] = StrCanRx.ulDATAL.ubDB[1]; un_time_output1.arr[1] = StrCanRx.ulDATAL.ubDB[2]; un_time_output1.arr[0] = StrCanRx.ulDATAL.ubDB[3]; un_time_output1.arr[7] = StrCanRx.ulDATAH.ubDB[0]; un_time_output1.arr[6] = StrCanRx.ulDATAH.ubDB[1]; un_time_output1.arr[5] = StrCanRx.ulDATAH.ubDB[2]; un_time_output1.arr[4] = StrCanRx.ulDATAH.ubDB[3]; CAN_vReleaseObj(DF_RXTIME); bm8563SetTime(&un_time_output1); } if(CAN_ubNewData(DF_SwRxKGF2))//等待KGF唤醒 { CAN_vGetMsgObj(DF_SwRxKGF2, &StrCanRx); CAN_vReleaseObj(DF_SwRxKGF2); flg_KGF = 1; } if(CAN_ubNewData(DF_SwZFKGF1))//接受E3的转发控制 { CAN_vGetMsgObj(DF_SwZFKGF1, &StrCanRx); un_sample_kgf_command.arr[2] = StrCanRx.ulDATAL.ubDB[0]; un_sample_kgf_command.arr[3] = StrCanRx.ulDATAL.ubDB[1]; un_sample_kgf_command.arr[0] = StrCanRx.ulDATAL.ubDB[2]; un_sample_kgf_command.arr[1] = StrCanRx.ulDATAL.ubDB[3]; un_sample_kgf_command.arr[6] = StrCanRx.ulDATAH.ubDB[0]; un_sample_kgf_command.arr[7] = StrCanRx.ulDATAH.ubDB[1]; un_sample_kgf_command.arr[4] = StrCanRx.ulDATAH.ubDB[2]; un_sample_kgf_command.arr[5] = StrCanRx.ulDATAH.ubDB[3]; CAN_vReleaseObj(DF_SwZFKGF1); } //---------------------------------------------------------- if(CAN_ubNewData(DF_SwRx)) { CAN_vGetMsgObj(DF_SwRx, &StrCanRx); UnInfCan_1.ArrData.ArrRX[0][3] = StrCanRx.ulDATAL.ubDB[0]; UnInfCan_1.ArrData.ArrRX[0][2] = StrCanRx.ulDATAL.ubDB[1]; UnInfCan_1.ArrData.ArrRX[0][1] = StrCanRx.ulDATAL.ubDB[2]; UnInfCan_1.ArrData.ArrRX[0][0] = StrCanRx.ulDATAL.ubDB[3]; UnInfCan_1.ArrData.ArrRX[0][7] = StrCanRx.ulDATAH.ubDB[0]; UnInfCan_1.ArrData.ArrRX[0][6] = StrCanRx.ulDATAH.ubDB[1]; UnInfCan_1.ArrData.ArrRX[0][5] = StrCanRx.ulDATAH.ubDB[2]; UnInfCan_1.ArrData.ArrRX[0][4] = StrCanRx.ulDATAH.ubDB[3]; CAN_vReleaseObj(DF_SwRx); vcu_can_cnt ++;//节点在线检测累加 powerstate = UnInfCan_1.ArrData.ArrRX[0][4];//整车电源状态 //设定休眠时间 TimeTemp = UnInfCan_1.ArrData.ArrRX[0][0] + ((ulong)UnInfCan_1.ArrData.ArrRX[0][1] << 8) ;//唤醒时间 if(TimeTemp >= MAX_TIME)//最大限制值,30天 { TimeTemp = MAX_TIME; } // 分钟 → 小时 HoursTemp = TimeTemp / 60; sleeptime.bit_data.minute = TimeTemp % 60; // 小时 → 天 DaysTemp = HoursTemp / 24; sleeptime.bit_data.hour = HoursTemp % 24; if(DaysTemp >= 30)//日超过范围 { sleeptime.bit_data.day = 30; } else { sleeptime.bit_data.day = DaysTemp; } //设定唤醒时间 TimeTemp = UnInfCan_1.ArrData.ArrRX[0][2] + ((ulong)UnInfCan_1.ArrData.ArrRX[0][3] << 8);//唤醒时间 if(TimeTemp > MAX_TIME)//最大限制值,30天 { TimeTemp = MAX_TIME; } // 分钟 → 小时 HoursTemp = TimeTemp / 60; waketime.bit_data.minute = TimeTemp % 60; // 小时 → 天 DaysTemp = HoursTemp / 24; waketime.bit_data.hour = HoursTemp % 24; if(DaysTemp >= 30)//日超过范围 { waketime.bit_data.day = 30; } else { waketime.bit_data.day = DaysTemp; } } //休眠处理 SystemStateMachine(&sleepstate); // //1000ms发送一帧 if(!FlgCan_1) { FlgCan_1 = 1; bm8563GetTime(¤ttime);//1s更新一次时钟 // 读取分钟(地址0x03) UnSwSample_1.arr[4] = (BM8563_ReadReg(BM8563_ALARM_MIN)); // 读取小时(地址0x04) UnSwSample_1.arr[2] = (BM8563_ReadReg(BM8563_ALARM_HOUR)); // 24小时制需屏蔽Bit6-7 // 读取日(地址0x05) UnSwSample_1.arr[1] = (BM8563_ReadReg(BM8563_ALARM_DAY)); // 屏蔽控制位 // 读取日(地址0x05) UnSwSample_1.arr[5] = (BM8563_ReadReg(BM8563_ALARM_DAY)); // 屏蔽控制位 // 读取周(地址0x06,BM8563周值为0x01-0x07,无需BCD转换) UnSwSample_1.arr[3] = BM8563_ReadReg(BM8563_ALARM_WEEK); // 仅保留低3位 CanTX(); if(1 == flg_KGF)//等待KGF唤醒后再发送数据 { un_inf_can_kgf_output3.bit_data.KGF01 = un_sample_kgf_command.bit_data.KGF01_CH01_Reserve | un_inf_can_kgf_output1.bit_data.KGF01; un_inf_can_kgf_output3.bit_data.KGF02 = un_sample_kgf_command.bit_data.KGF01_CH02_Reserve | un_inf_can_kgf_output1.bit_data.KGF02; un_inf_can_kgf_output3.bit_data.KGF03 = un_sample_kgf_command.bit_data.KGF01_CH03_Reserve | un_inf_can_kgf_output1.bit_data.KGF03; un_inf_can_kgf_output3.bit_data.KGF04 = un_sample_kgf_command.bit_data.KGF01_PrechargeRelay | un_inf_can_kgf_output1.bit_data.KGF04; un_inf_can_kgf_output3.bit_data.KGF05 = un_sample_kgf_command.bit_data.KGF01_CH05_Reserve | un_inf_can_kgf_output1.bit_data.KGF05; un_inf_can_kgf_output3.bit_data.KGF06 = un_sample_kgf_command.bit_data.KGF01_CH06_Reserve | un_inf_can_kgf_output1.bit_data.KGF06; un_inf_can_kgf_output3.bit_data.KGF07 = un_sample_kgf_command.bit_data.KGF01_HighVoltageRelayA | un_inf_can_kgf_output1.bit_data.KGF07; un_inf_can_kgf_output3.bit_data.KGF08 = un_sample_kgf_command.bit_data.KGF01_HighVoltageRelayB | un_inf_can_kgf_output1.bit_data.KGF08; un_inf_can_kgf_output3.bit_data.KGF09 = un_sample_kgf_command.bit_data.KGF01_CH09_Reserve | un_inf_can_kgf_output1.bit_data.KGF09; un_inf_can_kgf_output3.bit_data.KGF10 = un_sample_kgf_command.bit_data.KGF01_CH10_Reserve | un_inf_can_kgf_output1.bit_data.KGF10; un_inf_can_kgf_output3.bit_data.KGF11 = un_sample_kgf_command.bit_data.KGF01_LowVoltageRelayA | un_inf_can_kgf_output1.bit_data.KGF11; un_inf_can_kgf_output3.bit_data.KGF12 = un_sample_kgf_command.bit_data.KGF01_LowVoltageRelayB | un_inf_can_kgf_output1.bit_data.KGF12; un_inf_can_kgf_output3.bit_data.KGF13 = un_sample_kgf_command.bit_data.KGF01_LowVoltageCharge | un_inf_can_kgf_output1.bit_data.KGF13; un_inf_can_kgf_output3.bit_data.KGF14 = un_sample_kgf_command.bit_data.KGF01_CH14_Reserve | un_inf_can_kgf_output1.bit_data.KGF14; un_inf_can_kgf_output3.bit_data.KGF15 = un_sample_kgf_command.bit_data.KGF01_CH15_Reserve | un_inf_can_kgf_output1.bit_data.KGF15; un_inf_can_kgf_output3.bit_data.KGF16 = un_sample_kgf_command.bit_data.KGF01_CH16_Reserve | un_inf_can_kgf_output1.bit_data.KGF16; un_inf_can_kgf_output4.bit_data.KGF01 = un_sample_kgf_command.bit_data.KGF02_ComputerPowerA | un_inf_can_kgf_output2.bit_data.KGF01; un_inf_can_kgf_output4.bit_data.KGF02 = un_sample_kgf_command.bit_data.KGF02_ComputerPowerB | un_inf_can_kgf_output2.bit_data.KGF02; un_inf_can_kgf_output4.bit_data.KGF03 = un_sample_kgf_command.bit_data.KGF02_RemotePower | un_inf_can_kgf_output2.bit_data.KGF03; un_inf_can_kgf_output4.bit_data.KGF04 = un_sample_kgf_command.bit_data.KGF02_VcuE3Power | un_inf_can_kgf_output2.bit_data.KGF04; un_inf_can_kgf_output4.bit_data.KGF05 = un_sample_kgf_command.bit_data.KGF02_NetworkSwitchPowerA | un_inf_can_kgf_output2.bit_data.KGF05; un_inf_can_kgf_output4.bit_data.KGF06 = un_sample_kgf_command.bit_data.KGF02_NetworkSwitchPowerB | un_inf_can_kgf_output2.bit_data.KGF06; un_inf_can_kgf_output4.bit_data.KGF07 = un_sample_kgf_command.bit_data.KGF02_LeftHeadlightA | un_inf_can_kgf_output2.bit_data.KGF07; un_inf_can_kgf_output4.bit_data.KGF08 = un_sample_kgf_command.bit_data.KGF02_LeftHeadlightB | un_inf_can_kgf_output2.bit_data.KGF08; un_inf_can_kgf_output4.bit_data.KGF09 = un_sample_kgf_command.bit_data.KGF02_RightHeadlightA | un_inf_can_kgf_output2.bit_data.KGF09; un_inf_can_kgf_output4.bit_data.KGF10 = un_sample_kgf_command.bit_data.KGF02_RightHeadlightB | un_inf_can_kgf_output2.bit_data.KGF10; un_inf_can_kgf_output4.bit_data.KGF11 = un_sample_kgf_command.bit_data.KGF02_LeftTaillightA | un_inf_can_kgf_output2.bit_data.KGF11; un_inf_can_kgf_output4.bit_data.KGF12 = un_sample_kgf_command.bit_data.KGF02_LeftTaillightB | un_inf_can_kgf_output2.bit_data.KGF12; un_inf_can_kgf_output4.bit_data.KGF13 = un_sample_kgf_command.bit_data.KGF02_RightTaillightA | un_inf_can_kgf_output2.bit_data.KGF13; un_inf_can_kgf_output4.bit_data.KGF14 = un_sample_kgf_command.bit_data.KGF02_RightTaillightB | un_inf_can_kgf_output2.bit_data.KGF14; un_inf_can_kgf_output4.bit_data.KGF15 = un_sample_kgf_command.bit_data.KGF02_ComputerPowerC | un_inf_can_kgf_output2.bit_data.KGF15; un_inf_can_kgf_output4.bit_data.KGF16 = un_sample_kgf_command.bit_data.KGF02_ComputerPowerD | un_inf_can_kgf_output2.bit_data.KGF16; canSendTo(DF_SwTxKGF1,(ubyte *)&un_inf_can_kgf_output3.arr[0]); canSendTo(DF_SwTxKGF2,(ubyte *)&un_inf_can_kgf_output4.arr[0]); } if(vcu_can_cnt == vcu_can_last)//数据一样表示故障 { flg_wake_ecu = FAULT; } else { flg_wake_ecu = NORMAL; vcu_can_last = vcu_can_cnt;//数据更新 } GetTemp();//1s采集一次温度 UnSwSample_1.bit_data.emergency_stop_switch = STOP_PIN; UnSwSample_1.bit_data.High_voltage_switch = ~WAKE_UP_PIN; UnSwSample_1.bit_data.CH03 = flg_wake_ecu; if(1 == flg_KGF)//等待KGF唤醒后再发送数据 { canSendTo(DF_SwTxTemp,(ubyte *)&UnSwSample_1.arr[0]); //不需要发送 小车不需要采集 } } if( (0x40 == can_error_cnt) || (0x80 == can_error_cnt) )//20250625判断是否出现总线错误 { can_error_flg = can_error_cnt; CAN_vInit(); can_error_cnt = 0; } }