399 lines
11 KiB
C
399 lines
11 KiB
C
#include "MAIN.H"
|
||
#include "RTC.H"
|
||
#include "temperature.H"
|
||
#include <string.h>
|
||
//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输出
|
||
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()) || (OFF == WAKE_UP_PIN) )//唤醒时间到以及高压开关关闭
|
||
{
|
||
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( (WAKE_UP_PIN == OFF) || (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_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(vcu_can_cnt == vcu_can_last)//数据一样表示故障
|
||
{
|
||
flg_wake_ecu = FAULT;
|
||
|
||
un_inf_can_kgf_output2.bit_data.KGF01 = 0x01;// 计算机
|
||
un_inf_can_kgf_output2.bit_data.KGF02 = 0x01;// 计算机
|
||
// un_inf_can_kgf_output2.bit_data.KGF15 = 0x01;// 计算机
|
||
// un_inf_can_kgf_output2.bit_data.KGF16 = 0x01;// 计算机
|
||
|
||
un_inf_can_kgf_output2.bit_data.KGF03 = 0x01;// 遥控器
|
||
|
||
un_inf_can_kgf_output2.bit_data.KGF05 = 0x01;// 网络交换机
|
||
un_inf_can_kgf_output2.bit_data.KGF06 = 0x01;// 网络交换机
|
||
un_inf_can_kgf_output1.bit_data.KGF09 = 0x01;// 交换机2
|
||
|
||
un_inf_can_kgf_output2.bit_data.KGF04 = 0x01;//KGF20接的主控
|
||
un_inf_can_kgf_output1.bit_data.KGF13 = 0x01;// 低压充电
|
||
|
||
|
||
if(1 == flg_KGF)//等待KGF唤醒后再发送数据
|
||
{
|
||
canSendTo(DF_SwTxKGF2,(ubyte *)&un_inf_can_kgf_output2.arr[0]);
|
||
canSendTo(DF_SwTxKGF1,(ubyte *)&un_inf_can_kgf_output1.arr[0]);
|
||
}
|
||
}
|
||
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;
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
|