Files
acquisition_module/User.c
liumin 0c90d88c20 更新 User.c
注释多余计算机的KGF通道
2025-07-05 10:08:25 +08:00

540 lines
15 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 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] = sleepstate;
CanTransmit();
}
//休眠处理函数
//------------------------------------------------------------------
void SystemStateMachine(SystemState *RgSTT)
{
ubyte i = 0;
//----------------------------------------------
switch (*RgSTT)
{
//-------------------------------------------
case STATE_INIT:
if(NORMAL == flg_wake_ecu)//控制器唤醒
{
if(STOP_PIN == ON) //急停开关唤醒
{
*RgSTT = STATE_ON; // 引脚为ON进入工作状态
wake_time_10min.bit_data.day = 0;
wake_time_10min.bit_data.hour = 0;
wake_time_10min.bit_data.week = 0;
wake_time_10min.bit_data.minute = 10;
bm8563ClearAlarmFlag(); //先清0
bm8563SetAlarm(&wake_time_10min);//设置10分钟
}
else
{
*RgSTT = STATE_OFF; // RTC唤醒直接进入休眠准备
}
}
else
{
*RgSTT = STATE_INIT;
}
break;
//-------------------------------------------
case STATE_ON:
if(bm8563CheckAlarmFlag() || ( (STOP_PIN == OFF) && (POWER_STANDBY == powerstate) ) || (WAKE_UP_PIN == OFF) )//10分钟到了或者按下急停且休眠或者关闭总开关
{
// 处理定时唤醒
bm8563ClearAlarmFlag();
bm8563SetAlarm(&sleeptime);
KGF_PIN = 0; //KGF休眠
CAN_PIN = 1; //can芯片休眠
BATTERY_PIN = 0;//电池休眠
*RgSTT = STATE_ON; // 保持状态(唤醒后由中断处理)
PS_vSetPowerDown();//休眠
}
else if( (POWER_WORKING == powerstate) || (POWER_EMERGENCY == powerstate) )//等于工作状态
{
*RgSTT = STATE_ON2; // 进入STATE_ON2
}
else
{
*RgSTT = STATE_ON; // 保持
}
// 保持ON状态无需额外操作
break;
//-------------------------------------------
case STATE_ON2:
if(POWER_STANDBY == powerstate)//下低压电就进入ON定时判断
{
*RgSTT = STATE_ON; //
wake_time_10min.bit_data.day = 0;
wake_time_10min.bit_data.hour = 0;
wake_time_10min.bit_data.week = 0;
wake_time_10min.bit_data.minute = 10;
bm8563ClearAlarmFlag(); //先清0
bm8563SetAlarm(&wake_time_10min);//设置10分钟
}
else if(WAKE_UP_PIN == OFF)//总开关关闭直接休眠
{
bm8563ClearAlarmFlag();
bm8563SetAlarm(&sleeptime);
KGF_PIN = 0; //KGF休眠
CAN_PIN = 1; //can芯片休眠
BATTERY_PIN = 0;//电池休眠
*RgSTT = STATE_ON2; // 保持状态(唤醒后由中断处理)
PS_vSetPowerDown();//休眠
}
else
{
*RgSTT = STATE_ON2; // 保持
}
break;
//-------------------------------------------
case STATE_OFF:
// 并设置下次唤醒
bm8563ClearAlarmFlag();
bm8563SetAlarm(&waketime);
memcpy(&waketimelast,&waketime,sizeof(UnTimeOutput));
*RgSTT = STATE_OFF2; // 进入休眠监控
break;
//-------------------------------------------
case STATE_OFF2:
if (STOP_PIN == ON) //退出休眠条件
{
*RgSTT = STATE_ON; // 引脚为ON进入工作状态
wake_time_10min.bit_data.day = 0;
wake_time_10min.bit_data.hour = 0;
wake_time_10min.bit_data.week = 0;
wake_time_10min.bit_data.minute = 10;
bm8563ClearAlarmFlag(); //先清0
bm8563SetAlarm(&wake_time_10min);//设置10分钟
}
else if(POWER_WORKING == powerstate)//等于工作状态
{
*RgSTT = STATE_ON2; // 保持状态
}
else if(0 != memcmp(&waketimelast,&waketime,sizeof(UnTimeOutput)))//比较值是否一样,不一样的话立马更新
{
memcpy(&waketimelast,&waketime,sizeof(UnTimeOutput));
bm8563SetAlarm(&waketime);
*RgSTT = STATE_OFF2; // 保持状态(唤醒后由中断处理)
}
else if(bm8563CheckAlarmFlag()) //唤醒时间到
{
// 处理定时唤醒
bm8563ClearAlarmFlag();
bm8563SetAlarm(&sleeptime);
KGF_PIN = 0; //KGF休眠
CAN_PIN = 1; //can芯片休眠
BATTERY_PIN = 0;//电池休眠
*RgSTT = STATE_OFF2; // 保持状态(唤醒后由中断处理)
PS_vSetPowerDown();//休眠
}
else
{
*RgSTT = STATE_OFF2; // 外部唤醒
}
break;
default:break;
}
// switch (*RgSTT)
// {
// //-------------------------------------------
// case STATE_INIT:
// if(1 == flgwakeecu)//控制器唤醒
// {
// if (WAKE_UP_PIN == ON) {
// *RgSTT = STATE_ON; // 引脚为ON进入工作状态
// } else {
// *RgSTT = STATE_OFF; // 引脚为OFF直接进入休眠准备
// }
// }
// else
// {
// *RgSTT = STATE_INIT;
// }
// break;
// //-------------------------------------------
// case STATE_ON:
// if( (WAKE_UP_PIN == OFF) || ( (STOP_PIN == OFF) && (POWER_STANDBY == powerstate) ) )//休眠条件:总开关断开或者急停开关按下且处于下电模式
// {
// // 并设置下次唤醒
// bm8563SetAlarm(&sleeptime);
// *RgSTT = STATE_OFF; // 引脚为OFF直接进入休眠准备
// KGF_PIN = 0; //KGF休眠
// CAN_PIN = 1; //can芯片休眠
// PS_vSetPowerDown();//休眠
// }
// else
// {
// *RgSTT = STATE_ON; // 引脚为ON进入工作状态
// }
// // 保持ON状态无需额外操作
// break;
// //-------------------------------------------
// case STATE_OFF:
// if (WAKE_UP_PIN == ON) {
// *RgSTT = STATE_ON; // 外部唤醒
// } else {
// // 并设置下次唤醒
// bm8563SetAlarm(&waketime);
//
// memcpy(&waketimelast,&waketime,sizeof(UnTimeOutput));
//
// *RgSTT = STATE_OFF2; // 进入休眠监控
// }
// break;
// //-------------------------------------------
// case STATE_OFF2:
// if (WAKE_UP_PIN == ON) //退出休眠条件
// {
// *RgSTT = STATE_ON; // 外部唤醒
// }
// else if(0 != memcmp(&waketimelast,&waketime,sizeof(UnTimeOutput)))//比较值是否一样,不一样的话立马更新
// {
// memcpy(&waketimelast,&waketime,sizeof(UnTimeOutput));
// bm8563SetAlarm(&waketime);
// *RgSTT = STATE_OFF2; // 保持状态(唤醒后由中断处理)
// }
// else if (bm8563CheckAlarmFlag())
// {
// // 处理定时唤醒
// bm8563ClearAlarmFlag();
//
// bm8563SetAlarm(&sleeptime);
// KGF_PIN = 0; //KGF休眠
// CAN_PIN = 1; //can芯片休眠
// *RgSTT = STATE_OFF2; // 保持状态(唤醒后由中断处理)
// PS_vSetPowerDown();//休眠
// }
// else
// {
// *RgSTT = STATE_OFF2; // 外部唤醒
// }
// break;
// default:break;
// }
}
//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) ;//唤醒时间
// 分钟 → 小时
HoursTemp = TimeTemp / 60;
sleeptime.bit_data.minute = TimeTemp % 60;
// 小时 → 天
DaysTemp = HoursTemp / 24;
sleeptime.bit_data.hour = HoursTemp % 24;
if(DaysTemp >= 31)//月超过范围
{
sleeptime.bit_data.day = 31;
}
else
{
sleeptime.bit_data.day = DaysTemp;
}
//设定唤醒时间
TimeTemp = UnInfCan_1.ArrData.ArrRX[0][2] + ((ulong)UnInfCan_1.ArrData.ArrRX[0][3] << 8);//唤醒时间
// 分钟 → 小时
HoursTemp = TimeTemp / 60;
waketime.bit_data.minute = TimeTemp % 60;
// 小时 → 天
DaysTemp = HoursTemp / 24;
waketime.bit_data.hour = HoursTemp % 24;
if(DaysTemp >= 31)//月超过范围
{
waketime.bit_data.day = 31;
}
else
{
waketime.bit_data.day = DaysTemp;
}
}
UnSwSample_1.arr[2] = waketime.bit_data.minute;
UnSwSample_1.arr[1] = sleeptime.bit_data.minute;
//休眠处理
SystemStateMachine(&sleepstate);
//1000ms发送一帧
if(!FlgCan_1)
{
FlgCan_1 = 1;
bm8563GetTime(&currenttime);//1s更新一次时钟
// CanTX();
UnSwSample_1.bit_data.temperature[1] = 0;
UnSwSample_1.bit_data.temperature[0] = 0;
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_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);
}
}
if( (0x40 == can_error_cnt) || (0x80 == can_error_cnt) )//20250625判断是否出现总线错误
{
can_error_flg = can_error_cnt;
CAN_vInit();
can_error_cnt = 0;
}
}