Files
acquisition_module/User.c

408 lines
12 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 inittime = {00,1,1,0,0,0,0,0};// 默认设置 2000年1月1日 周日0000
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定时器 890-=
//-----------------------------------------------------------------------
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_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(&currenttime);//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)); // 屏蔽控制位
// 读取周地址0x06BM8563周值为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_output2.bit_data.KGF04 = 0x01;//KGF20接的主控
un_inf_can_kgf_output1.bit_data.KGF01 = 0x01; // E3
un_inf_can_kgf_output1.bit_data.KGF02 = 0x01; // 导航仪
un_inf_can_kgf_output1.bit_data.KGF03 = 0 ; // 导航仪
un_inf_can_kgf_output1.bit_data.KGF05 = 0x01; // 交换机、路由器
un_inf_can_kgf_output1.bit_data.KGF06 = 0x01; // 交换机、路由器
un_inf_can_kgf_output1.bit_data.KGF07 = 0x01; // 计算机
un_inf_can_kgf_output1.bit_data.KGF08 = 0x01; // 计算机
un_inf_can_kgf_output1.bit_data.KGF09 = 0x01; // 上装
un_inf_can_kgf_output1.bit_data.KGF11 = 0x01; // 上装
un_inf_can_kgf_output1.bit_data.KGF12 = 0x01; // 待定
un_inf_can_kgf_output1.bit_data.KGF15 = 0x01; // 网络摄像头
un_inf_can_kgf_output1.bit_data.KGF16 = 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 = 0;
UnSwSample_1.bit_data.High_voltage_switch = 1;
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;
}
}