Files
TempControl/User.c
2025-10-21 21:25:35 +08:00

466 lines
16 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 "temperature.H"
#include <string.h>
//RAM重启保存标志
ubyte RestartDataFlg1 _at_ 0xF5E7;
ubyte RestartDataFlg2 _at_ 0xF600;
//KGF保存数据
uword RestartDataKGF _at_ 0xF5E5;
//can信息
UnInfCan UnInfCan_1 _at_ 0xF5E8;
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输出
//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; //控制器唤醒标志
//-----------------------------------------------------------------------
//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;
}
//输出PWM 20181227
/*
ubyte *pStt, 状态机变量
bit Cmd, 状态机输入1根据PwmH的值来决定输出0输出0
bit Out, 状态机输出
ubyte *pCnt, 定时计数器
ubyte *pPwmH 状态机参数PWM的高电平时间
*/
bit funcPwmOut(ubyte *pStt,bit Cmd,ubyte *pCnt,ubyte *pPwmH)
{
ubyte PwmL = 0;
bit Out = 0;
//------------------------------------------------------------------------------------------------
if((*pPwmH) > dfPwmH)(*pPwmH) = dfPwmH; //限制最大值
PwmL = dfPwmH - (*pPwmH);//计算PWM低电平
if((1 == Cmd) )
{
if(0 == (*pPwmH)) //高电平为0表示PWM无效由Cmd来控制Cmd为1输出1Cmd为0输出0
{
Out = 1;
(*pStt) = 0;
}
else
{
switch((*pStt))
{
case 0:
(*pCnt) = 0;
(*pStt) = 1;
Out = 1;
break;
case 1:
if((*pCnt) >= (*pPwmH))
{
(*pCnt) = 0;
(*pStt) = 2;
Out = 0;
}
else
{
(*pCnt)++;
(*pStt) = 1;
Out = 1;
}
break;
case 2:
if((*pCnt) >= PwmL)
{
(*pCnt) = 0;
(*pStt) = 1;
Out = 1;
}
else
{
(*pCnt)++;
(*pStt) = 2;
Out = 0;
}
break;
//-----------------------------------------------------
default:;
}//switch
}//else
}//if
else
{
Out = 0;
(*pStt) = 0;
}
return Out;
}
//根据接收的CAN缓冲区数据驱动相应指示灯。
void LedDr(void)
{
static ubyte RgSTT[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static ubyte CntTime[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
ubyte i = 0;
//------------------------------------------------------------------------------------------------
// dfOut_01 = funcPwmOut(&RgSTT[0 ],dfCmd_01,&CntTime[0 ],&PwmH[0 ]);
// dfOut_02 = funcPwmOut(&RgSTT[1 ],dfCmd_02,&CntTime[1 ],&PwmH[1 ]);
// dfOut_03 = funcPwmOut(&RgSTT[2 ],dfCmd_03,&CntTime[2 ],&PwmH[2 ]);
// dfOut_04 = funcPwmOut(&RgSTT[3 ],dfCmd_04,&CntTime[3 ],&PwmH[3 ]);
// dfOut_05 = funcPwmOut(&RgSTT[4 ],dfCmd_05,&CntTime[4 ],&PwmH[4 ]);
// dfOut_06 = funcPwmOut(&RgSTT[5 ],dfCmd_06,&CntTime[5 ],&PwmH[5 ]);
// dfOut_07 = funcPwmOut(&RgSTT[6 ],dfCmd_07,&CntTime[6 ],&PwmH[6 ]);
// dfOut_08 = funcPwmOut(&RgSTT[7 ],dfCmd_08,&CntTime[7 ],&PwmH[7 ]);
// dfOut_09 = funcPwmOut(&RgSTT[8 ],dfCmd_09,&CntTime[8 ],&PwmH[8 ]);
// dfOut_10 = funcPwmOut(&RgSTT[9 ],dfCmd_10,&CntTime[9 ],&PwmH[9 ]);
// dfOut_11 = funcPwmOut(&RgSTT[10],dfCmd_11,&CntTime[10],&PwmH[10]);
// dfOut_12 = funcPwmOut(&RgSTT[11],dfCmd_12,&CntTime[11],&PwmH[11]);
// dfOut_13 = funcPwmOut(&RgSTT[12],dfCmd_13,&CntTime[12],&PwmH[12]);
// dfOut_14 = funcPwmOut(&RgSTT[13],dfCmd_14,&CntTime[13],&PwmH[13]);
// dfOut_15 = funcPwmOut(&RgSTT[14],dfCmd_15,&CntTime[14],&PwmH[14]);
// dfOut_16 = funcPwmOut(&RgSTT[15],dfCmd_16,&CntTime[15],&PwmH[15]);
i = dfOut_02; //20210906保存IO口状态 解决KGF重启指示灯闪烁问题
RestartDataKGF = dfOut_01;
RestartDataKGF = RestartDataKGF + (i<<1);
i = dfOut_03;
RestartDataKGF = RestartDataKGF + (i<<2);
i = dfOut_04;
RestartDataKGF = RestartDataKGF + (i<<3);
i = dfOut_05;
RestartDataKGF = RestartDataKGF + (i<<4);
i = dfOut_06;
RestartDataKGF = RestartDataKGF + (i<<5);
i = dfOut_07;
RestartDataKGF = RestartDataKGF + (i<<6);
i = dfOut_08;
RestartDataKGF = RestartDataKGF + (i<<7);
i = dfOut_09;
RestartDataKGF = RestartDataKGF + (i<<8);
i = dfOut_10;
RestartDataKGF = RestartDataKGF + (i<<9);
i = dfOut_11;
RestartDataKGF = RestartDataKGF + (i<<10);
i = dfOut_12;
RestartDataKGF = RestartDataKGF + (i<<11);
i = dfOut_13;
RestartDataKGF = RestartDataKGF + (i<<12);
i = dfOut_14;
RestartDataKGF = RestartDataKGF + (i<<13);
i = dfOut_15;
RestartDataKGF = RestartDataKGF + (i<<14);
i = dfOut_16;
RestartDataKGF = RestartDataKGF + (i<<15);
}
void CanTransmit(void)
{
// ulong i;
//----------------- --------
CAN_waitTransmit(DF_SwTx);//发送前等待上一帧发送完毕,这样不会丢帧
// Password();
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)
{
//-----------------------------------
if(1 == SwOut09)UnInfCan_1.ArrData.Arr[0][3] |= 0x01;else UnInfCan_1.ArrData.Arr[0][3] &= (~0x01); //KGF1 //20200303修改为与接收到的数据一致反馈与接收到时数据为一致
if(1 == SwOut10)UnInfCan_1.ArrData.Arr[0][3] |= 0x02;else UnInfCan_1.ArrData.Arr[0][3] &= (~0x02); //KGF2
if(1 == SwOut04)UnInfCan_1.ArrData.Arr[0][3] |= 0x04;else UnInfCan_1.ArrData.Arr[0][3] &= (~0x04); //KGF3
if(1 == SwOut03)UnInfCan_1.ArrData.Arr[0][3] |= 0x08;else UnInfCan_1.ArrData.Arr[0][3] &= (~0x08); //KGF4
if(1 == SwOut06)UnInfCan_1.ArrData.Arr[0][3] |= 0x10;else UnInfCan_1.ArrData.Arr[0][3] &= (~0x10); //KGF5
if(1 == SwOut05)UnInfCan_1.ArrData.Arr[0][3] |= 0x20;else UnInfCan_1.ArrData.Arr[0][3] &= (~0x20); //KGF6
if(1 == SwOut15)UnInfCan_1.ArrData.Arr[0][3] |= 0x40;else UnInfCan_1.ArrData.Arr[0][3] &= (~0x40); //KGF7
if(1 == SwOut16)UnInfCan_1.ArrData.Arr[0][3] |= 0x80;else UnInfCan_1.ArrData.Arr[0][3] &= (~0x80); //KGF8
if(1 == SwOut13)UnInfCan_1.ArrData.Arr[0][2] |= 0x01;else UnInfCan_1.ArrData.Arr[0][2] &= (~0x01); //KGF9
if(1 == SwOut14)UnInfCan_1.ArrData.Arr[0][2] |= 0x02;else UnInfCan_1.ArrData.Arr[0][2] &= (~0x02); //KGF10
if(1 == SwOut08)UnInfCan_1.ArrData.Arr[0][2] |= 0x04;else UnInfCan_1.ArrData.Arr[0][2] &= (~0x04); //KGF11
if(1 == SwOut07)UnInfCan_1.ArrData.Arr[0][2] |= 0x08;else UnInfCan_1.ArrData.Arr[0][2] &= (~0x08); //KGF12
if(1 == SwOut02)UnInfCan_1.ArrData.Arr[0][2] |= 0x10;else UnInfCan_1.ArrData.Arr[0][2] &= (~0x10); //KGF13
if(1 == SwOut01)UnInfCan_1.ArrData.Arr[0][2] |= 0x20;else UnInfCan_1.ArrData.Arr[0][2] &= (~0x20); //KGF14
if(1 == SwOut11)UnInfCan_1.ArrData.Arr[0][2] |= 0x40;else UnInfCan_1.ArrData.Arr[0][2] &= (~0x40); //KGF15
if(1 == SwOut12)UnInfCan_1.ArrData.Arr[0][2] |= 0x80;else UnInfCan_1.ArrData.Arr[0][2] &= (~0x80); //KGF16
if(1 == SwIn01 )UnInfCan_1.ArrData.Arr[0][1] &= (~0x01);else UnInfCan_1.ArrData.Arr[0][1] |= 0x01; //Dia01 20200225修改为0数据变为1,1数据变为0这样大CPU方便处理
if(1 == SwIn02 )UnInfCan_1.ArrData.Arr[0][1] &= (~0x02);else UnInfCan_1.ArrData.Arr[0][1] |= 0x02; //Dia02
if(1 == SwIn03 )UnInfCan_1.ArrData.Arr[0][1] &= (~0x04);else UnInfCan_1.ArrData.Arr[0][1] |= 0x04; //Dia03
if(1 == SwIn04 )UnInfCan_1.ArrData.Arr[0][1] &= (~0x08);else UnInfCan_1.ArrData.Arr[0][1] |= 0x08; //Dia04
if(1 == SwIn05 )UnInfCan_1.ArrData.Arr[0][1] &= (~0x10);else UnInfCan_1.ArrData.Arr[0][1] |= 0x10; //Dia05
if(1 == SwIn06 )UnInfCan_1.ArrData.Arr[0][1] &= (~0x20);else UnInfCan_1.ArrData.Arr[0][1] |= 0x20; //Dia06
if(1 == SwIn07 )UnInfCan_1.ArrData.Arr[0][1] &= (~0x40);else UnInfCan_1.ArrData.Arr[0][1] |= 0x40; //Dia07
if(1 == SwIn08 )UnInfCan_1.ArrData.Arr[0][1] &= (~0x80);else UnInfCan_1.ArrData.Arr[0][1] |= 0x80; //Dia08
UnInfCan_1.ArrData.Arr[0][0] = 0;
UnInfCan_1.ArrData.Arr[0][7] = 0;
UnInfCan_1.ArrData.Arr[0][6] = RomNum;
UnInfCan_1.ArrData.Arr[0][5] = (ubyte)(UnSwSample_1.bit_data.temperature[0]);
UnInfCan_1.ArrData.Arr[0][4] = (ubyte)(UnSwSample_1.bit_data.temperature[0]>>8);
CanTransmit();
}
//------------------------------------------------------------------
// 三状态温度控制状态机
// 参数说明:
// current_state - 当前状态指针(需保持生命周期)
// current_temp - 当前温度值(建议通过中断更新[6](@ref)
//------------------------------------------------------------------
void tempStateMachine(SystemState *current_state, float current_temp)
{
switch (*current_state)
{
// 初始检测状态网页5初始化逻辑强化
case STATE_INIT_CHECK:
if(current_temp < INIT_THRESHOLD)
{
*current_state = STATE_INIT_HEATING;
HERTER_CMD(1);
PC_CMD(0);
}
else
{
// 非低温环境直接进入冷却状态
*current_state = STATE_COOLING;
HERTER_CMD(0);
PC_CMD(1);
}
break;
case STATE_INIT_HEATING://20250330初始加热状态只有当温度大于设定才会此状态未加热到设定温度会关闭计算机后面的状态不会。
if(current_temp > (HEATING_STOP + TEMP_HYSTERESIS))
{
*current_state = STATE_COOLING;
HERTER_CMD(0);
PC_CMD(1);
}
else
{
// 非低温环境直接进入冷却状态
*current_state = STATE_INIT_HEATING;
HERTER_CMD(1);
PC_CMD(0);
}
break;
// 加热状态网页3加热阶段优化
case STATE_HEATING:
if(current_temp > (HEATING_STOP + TEMP_HYSTERESIS))
{
*current_state = STATE_COOLING;
HERTER_CMD(0);
PC_CMD(1);
}
else
{
HERTER_CMD(1);
PC_CMD(1);
}
break;
// 冷却状态网页6状态切换改进
case STATE_COOLING:
if(current_temp < (COOLING_RESTART - TEMP_HYSTERESIS))
{
*current_state = STATE_HEATING;
HERTER_CMD(1);
PC_CMD(1);
}
else
{
HERTER_CMD(0);
PC_CMD(1);
}
break;
default:
// 异常处理网页1安全规范
*current_state = STATE_INIT_CHECK;
break;
}
}
//CAN发送接收
void CanRXTX(void)
{
stCAN_SWObj StrCanRx = {0};
uword tmp = 0;
ubyte i = 0,j = 0;
static SystemState temp_state = STATE_INIT_CHECK;
float current_temp = 0.0f;
//------------------------------------
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);
//CAN发送周期 50-5000ms
tmp = (uword)UnInfCan_1.ArrData.ArrRX[0][6];
tmp = (tmp << 8);
tmp |= ((uword)UnInfCan_1.ArrData.ArrRX[0][7]);
if(tmp >= 50)RgCanPerid = tmp;
if(tmp >= 5000)RgCanPerid = 5000;
// UnInfCan_1.ArrData.Arr[0][3] = UnInfCan_1.ArrData.ArrRX[0][0];
// UnInfCan_1.ArrData.Arr[0][2] = UnInfCan_1.ArrData.ArrRX[0][1];
// UnInfCan_1.ArrData.Arr[0][1] = UnInfCan_1.ArrData.ArrRX[0][2]; 20200225注释不更新诊断数据
// UnInfCan_1.ArrData.Arr[0][0] = UnInfCan_1.ArrData.ArrRX[0][3];
// UnInfCan_1.ArrData.Arr[0][7] = UnInfCan_1.ArrData.ArrRX[0][4];
// UnInfCan_1.ArrData.Arr[0][6] = UnInfCan_1.ArrData.ArrRX[0][5];
// UnInfCan_1.ArrData.Arr[0][5] = (ubyte)(RgCanPerid>>8);
// UnInfCan_1.ArrData.Arr[0][4] = (ubyte)(RgCanPerid);
// CanTransmit(); 20200730不发送干扰数据运行
}
if(CAN_ubNewData(DF_SwRxPwm))
{
CAN_vGetMsgObj(DF_SwRxPwm, &StrCanRx);
UnInfCan_1.ArrData.ArrRX[1][2] = StrCanRx.ulDATAL.ubDB[0];
UnInfCan_1.ArrData.ArrRX[1][3] = StrCanRx.ulDATAL.ubDB[1];
UnInfCan_1.ArrData.ArrRX[1][0] = StrCanRx.ulDATAL.ubDB[2];
UnInfCan_1.ArrData.ArrRX[1][1] = StrCanRx.ulDATAL.ubDB[3];
UnInfCan_1.ArrData.ArrRX[1][6] = StrCanRx.ulDATAH.ubDB[0];
UnInfCan_1.ArrData.ArrRX[1][7] = StrCanRx.ulDATAH.ubDB[1];
UnInfCan_1.ArrData.ArrRX[1][4] = StrCanRx.ulDATAH.ubDB[2];
UnInfCan_1.ArrData.ArrRX[1][5] = StrCanRx.ulDATAH.ubDB[3];
CAN_vReleaseObj(DF_SwRxPwm);
//接收的数据保存到PWM数据结构中20181227
PwmH[0 ] = (ubyte)UnInfCan_1.BitData.Pwm_01;
PwmH[1 ] = (ubyte)UnInfCan_1.BitData.Pwm_02;
PwmH[2 ] = (ubyte)UnInfCan_1.BitData.Pwm_03;
PwmH[3 ] = (ubyte)UnInfCan_1.BitData.Pwm_04;
PwmH[4 ] = (ubyte)UnInfCan_1.BitData.Pwm_05;
PwmH[5 ] = (ubyte)UnInfCan_1.BitData.Pwm_06;
PwmH[6 ] = (ubyte)UnInfCan_1.BitData.Pwm_07;
PwmH[7 ] = (ubyte)UnInfCan_1.BitData.Pwm_08;
PwmH[8 ] = (ubyte)UnInfCan_1.BitData.Pwm_09;
PwmH[9 ] = (ubyte)UnInfCan_1.BitData.Pwm_10;
PwmH[10] = (ubyte)UnInfCan_1.BitData.Pwm_11;
PwmH[11] = (ubyte)UnInfCan_1.BitData.Pwm_12;
PwmH[12] = (ubyte)UnInfCan_1.BitData.Pwm_13;
PwmH[13] = (ubyte)UnInfCan_1.BitData.Pwm_14;
PwmH[14] = (ubyte)UnInfCan_1.BitData.Pwm_15;
PwmH[15] = (ubyte)UnInfCan_1.BitData.Pwm_16;
}
//接收一帧,调用一次点灯程序。
LedDr();
//100ms发送一帧
if(!FlgCan_1)
{
FlgCan_1 = 1;
GetTemp();//1s采集一次温度
current_temp = (float)((int)UnSwSample_1.bit_data.temperature[0]);
current_temp = current_temp/10.0f;//
tempStateMachine(&temp_state, current_temp);
CanTX();
}
}