目前因为没有插枪拔枪检测电路,所以收到chm信号,我就开始了状态机操作,也就是这样来代替插枪,现在通信失败就会要求充电桩重新刷卡,这样子应该也没有问题。但是怎么实现可以不插拔枪也可以重复3次,看来是有必要的,如果充电桩厂家要求我这么做,我就要实现这个功能。
#include"charge_DC.h"
#include"basic_function.h"
#include"CAN.h"
#include"charge_basic.h"
void CAN_SendCharge(can_msg msg);
byte StartCharge(void); //充电启动,检测到充电信号后,判断连接是否正常
byte JugeParamerterCharge(void); //判断充电桩参数是否适合
byte ReadyCharge(void); //准备充电
void StopSwitchCharge(void); //关闭充电开关
word T_CalCharge(word V_data,word V_total,word RES_series_connect); //计算温度,参数:采集电压,总电压、串联电阻
byte JugeStopCharge(void); //中止充电判断
volatile word g_receive_charge[13]={0}; //接收自充电桩信息
/***************************************************************/
//g_receive_charge[]详细内容
//字节
//0,充电协议版本号低8位 如V1.2中的0X02
//1,充电协议版本号高16位 如V1.2中的0X0001
//2,充电桩编号低16位
//3,充电桩编号高16位
//4,充电桩最高输出电压
//5,充电桩最低输出电压
//6,充电桩最大输出电流
//7,充电桩最小输出电流
//8,电压输出值
//9,电流输出值
//10,累计充电时间
//11,充电允许/暂停 1/0
//12,输出能量
/********************************************************************/
volatile byte g_state_charging[4]={0}; //充电状态信息
/******************************************************************/
//g_state_charging[]详细信息
//字节
//0,充电状态:0,未连充电抢,1 已连上充电枪,2,充电准备,3,正在充电,7充电结束,未拔充电枪,8充电枪断开,9充电连接故障,但未断开 //第8位为1表示重新开始充电
//1,故障级别:0,1,2,3
//2,BMS中止充电原因 //充电中止类型
//0充电未中止,1,达到所需SOC,2达到总电压设置,3达到单体电压设置
//4充电机主动停止,5绝缘故障,6输出连接器过温,7BMS元件输出连接过温
//8充电连接故障,9电池组过温,10高压继电器故障,11监测点2电压故障
//12其他故障 13电流过大 14电压异常
//3,充电桩中止充电原因
static word g_send_charge[40]={0}; //充电相关发送数据,详细信息见SetDataCharge()函数
/****************************************************************************************************/
/****************************************************************************************************/
//充电基本模块//
/****************************************************************************************************/
/****************************************************************************************************/
static volatile byte g_charge_step=1; //0,不充电
//1, 检测到充电枪,但未收到充电握手信息
//2,充电握手启动阶段,收到充电机握手信息后
//3,充电握手阶段,收到0X00充电机辨识报文后
//4, 预留
//5, 充电参数配置,收到0XAA的充电机辨识报文后
//6, 收到时间同步信息
//7, 收到充电机最大输出能力参数
//8, 判断能否充电,发送充电准备未就绪报文,收到5和6后
//9,BMS判断能充电并发送完成充电准备报文
//10,预留
//11, 发送电池需求和总状态,接收到充电机完成充电准备后
//12,充电阶段:发送电池需求、总状态、蓄电池状态
//13,充电中止
//14, 充电结束
//20, 通讯中断
//21,通讯中断后,充电电流小于5A
//22,充电故障
static volatile byte g_timeover_charge_temp=0; //充电超时判断字节
//0位:接收0X00的CRM超时
//1位:接收0XAA的CRM超时
//2位:接收CML超时
//3位:接收CRO超时
//4位:接收CCS超时
//5位:接收CST超时
//6位:接收CSD超时
//7位:超时标志
static volatile byte g_timeover_charge=0; //超时标志 :0正常
//1,接收0X00的CRM超时
//2接收0XAA的CRM超时
//3接收充电机最大输出能力CML及时钟同步超时
//4接收充电就绪CRO超时
//5接收充电机状态超时
//6接收充电中止BST超时
//7接收充电数据统计报文超时
//20充电机判断通讯超时
//static volatile can_msg msg_charge;
static word g_count_10ms_charge=0;
static volatile byte g_finish_charge=0;
static volatile byte g_flag_stop_charge=0;
/**************************************************/
//直流充电枪检测
//返回:0无充电枪;1,有充电枪2有充电枪;其他,不定
/**************************************************/
void ReadCharge(void)
{
word data;
static byte s_count1=0;
static byte s_count2=0;
static byte s_count3=0;
data=ADCapture(CHANNEL_CC,12,4); //采集电压
if(data>2700) //无充电枪
{
if(s_count1<100)
{
s_count1++;
}
else
{
if(g_chg.state)
{
g_chg.state=8;
}
}
}
else
{
s_count1=0;
}
if(data>1300&&data<2700) //有充电枪
{
if(s_count2<100)
{
s_count2++;
}
else
{
if(g_chg.state==0)
{
g_chg.state=1;
}
}
}
else
{
s_count2=0;
}
if(data<1300)
{
if(s_count3<100)
{
s_count3++;
}
else
{
g_chg.state=9;
}
}
else
{
s_count3=0;
}
}
/********************************************************/
//判断充电桩参数是否适合
//返回值:0参数不合适,1,参数合适,
/********************************************************/
byte JugeParamerterCharge(void)
{
if(g_receive_charge[4]>g_send_charge[0]&&g_receive_charge[5]<g_send_charge[9]) //充电桩最高输出电压大于电池组最大允许充电电压,且最小输出电压小于当前总电压
{
return 1;
}
else
{
return 0;
}
}
/*************************************************/
//发送BHM报文
/*************************************************/
void SendBHM(void)
{
can_msg msg_send;
msg_send.CAN_ID=ID_BHM;
SetBasic(&msg_send,2);
SetU16(&msg_send.TAB[0], g_send_charge[0]);
CAN_SendCharge(msg_send);
}
/*************************************************/
//发送BRM报文
/*************************************************/
byte SendBRM(void)
{
byte temp;
byte data_send[7];
can_msg msg_send;
if(0==Set_TPCM_data(&msg_send,41,0X000200))
{
CAN_SendCharge(msg_send);
}
if(NO_package_send_charge_spots==1)
{
data_send[0]=(VER_BMS)&0XFF;
data_send[1]=(VER_BMS>>8)&0XFF;
data_send[2]=(VER_BMS>>16)&0XFF;
data_send[3]=g_send_charge[1]&0XFF;
SetU16(&data_send[4], g_send_charge[2]);
data_send[6]=g_send_charge[3]&0XFF;
}
else if(NO_package_send_charge_spots==2)
{
data_send[0]=(g_send_charge[3]>>8)&0XFF;
data_send[1]=0XFF;
data_send[2]=0XFF;
data_send[3]=0XFF;
data_send[4]=0XFF;
data_send[5]=0XFF;
data_send[6]=0XFF;
}
else if(NO_package_send_charge_spots==3)
{
data_send[0]=0XFF;
data_send[1]=0XFF;
data_send[2]=0XFF;
data_send[3]=0XFF;
data_send[4]=0XFF;
data_send[5]=0XFF;
data_send[6]=0XFF;
}
else if(NO_package_send_charge_spots==4)
{
data_send[0]=0XFF;
data_send[1]=0XFF;
data_send[2]=0XFF;
data_send[3]=0XFF;
data_send[4]=0XFF;
data_send[5]=0XFF;
data_send[6]=0XFF;
}else if(NO_package_send_charge_spots==5){
data_send[0]=0XFF;
data_send[1]=0XFF;
data_send[2]=0XFF;
data_send[3]=0XFF;
data_send[4]=0XFF;
data_send[5]=0XFF;
data_send[6]=0XFF;
}
else if(NO_package_send_charge_spots==6)
{
data_send[0]=0XFF;
data_send[1]=0XFF;
data_send[2]=0XFF;
data_send[3]=0XFF;
data_send[4]=0XFF;
data_send[5]=0XFF;
data_send[6]=0XFF;
}
temp=Set_TPDT_data(&msg_send,data_send);
if(temp==0)
{
CAN_SendCharge(msg_send);
}
else if(temp==2)
{
return 1;
}
return 0;
}
/*************************************************/
//发送BCP报文
/*************************************************/
byte SendBCP(void) //充电参数
{
byte temp;
byte data_send[7];
can_msg msg_send;
word data_temp=0;
if(0==Set_TPCM_data(&msg_send,13,0X000600))
{
CAN_SendCharge(msg_send);
}
if(NO_package_send_charge_spots==1)
{
SetU16(&data_send[0],(g_send_charge[4])/10) ;
SetU16(&data_send[2],g_send_charge[5]) ;
SetU16(&data_send[4],g_send_charge[6]) ;
data_send[6]=g_send_charge[0]&0XFF;
}
else if(NO_package_send_charge_spots==2)
{
data_send[0]=((g_send_charge[0])>>8)&0XFF;
data_send[1]=(g_send_charge[7]/10)&0XFF;
SetU16(&data_send[2],g_send_charge[8]);
SetU16(&data_send[4],g_send_charge[9]);
data_send[6]=0XFF;
}
temp=Set_TPDT_data(&msg_send,data_send);
if(temp==0)
{
CAN_SendCharge(msg_send);
}
else if(temp==2)
{
return 1;
}
return 0;
}
/*************************************************/
//发送BRO报文
/*************************************************/
void SendBRO(byte state) //充电准备
{
can_msg msg_send;
msg_send.CAN_ID=ID_BRO;
SetBasic(&msg_send,1);
msg_send.TAB[0]=state;
CAN_SendCharge(msg_send);
}
/*************************************************/
//发送BCL报文
/*************************************************/
void SendBCL(void) //充电需求
{
can_msg msg_send;
msg_send.CAN_ID=ID_BCL;
SetBasic(&msg_send,5);
SetU16(&msg_send.TAB[0],g_chg.V) ;
SetU16(&msg_send.TAB[2],g_chg.I) ;
msg_send.TAB[4]=g_chg.flag?1:2;
CAN_SendCharge(msg_send);
}
/*************************************************/
//发送BCS报文
/*************************************************/
byte SendBCS(void) //充电状态
{
word temp;
byte data_send[7];
can_msg msg_send;
if(0==Set_TPCM_data(&msg_send,9,0X001100))
{
CAN_SendCharge(msg_send);
}
if(NO_package_send_charge_spots==1)
{
SetU16(&data_send[0],g_send_charge[9]) ;
SetU16(&data_send[2],g_send_charge[21]) ;
temp=g_send_charge[13]/10;
temp|=0X2000;
SetU16(&data_send[4],temp) ;
data_send[6]=(g_send_charge[8]/10)&0XFF;
}
else if(NO_package_send_charge_spots==2)
{
g_send_charge[14]=(1000-g_send_charge[8])*18/100+10; //根据SOC估算剩余充电时间
SetU16(&data_send[0],g_send_charge[14]) ;
data_send[2]=0XFF;
data_send[3]=0XFF;
data_send[4]=0XFF;
data_send[5]=0XFF;
data_send[6]=0XFF;
}
temp=Set_TPDT_data(&msg_send,data_send);
if(temp==0)
{
CAN_SendCharge(msg_send);
}
else if(temp==2)
{
return 1;
}
return 0;
}
/*************************************************/
//发送BSM报文
/*************************************************/
void SendBSM(void) //发送蓄电池状态信息
{
can_msg msg_send;
byte i=0;
msg_send.CAN_ID=ID_BSM;
SetBasic(&msg_send,7);
msg_send.TAB[0]=g_send_charge[15]&0XFF;
msg_send.TAB[1]=(g_send_charge[16]/10)&0XFF;
msg_send.TAB[2]=g_send_charge[17]&0XFF;
msg_send.TAB[3]=(g_send_charge[18]/10)&0XFF;
msg_send.TAB[4]=g_send_charge[19]&0XFF;
SetU16(&msg_send.TAB[5],g_send_charge[20]) ;
CAN_SendCharge(msg_send);
}
/*************************************************/
//发送BST报文
/*************************************************/
void SendBST(void) //充电中止
{
can_msg msg_send;
byte i=0;
unsigned long temp;
msg_send.CAN_ID=ID_BST;
SetBasic(&msg_send,4);
temp=((unsigned long)0X01)<<((2*(g_state_charging[2]-1))&0X1F);
SetU32(&msg_send.TAB[0],temp) ;
CAN_SendCharge(msg_send);
}
/*************************************************/
//发送BEM报文
/*************************************************/
void SendBEM(byte data) //充电错误报文
{
can_msg msg_send;
byte i;
msg_send.CAN_ID=ID_BEM;
SetBasic(&msg_send,8);
for(i=0;i<3;i++)
{
msg_send.TAB[i]=0XF0;
}
msg_send.TAB[3]=0XFC;
for(i=4;i<8;i++)
{
msg_send.TAB[i]=0XFF;
}
switch(data)
{
case 1:
msg_send.TAB[0]|=0X01;
break;
case 2:
msg_send.TAB[0]|=0X04;
break;
case 3:
msg_send.TAB[1]|=0X01;
break;
case 4:
msg_send.TAB[1]|=0X04;
break;
case 5:
msg_send.TAB[2]|=0X01;
break;
case 6:
msg_send.TAB[2]|=0X04;
break;
case 7:
msg_send.TAB[3]|=0X01;
break;
}
}
/*****************************************************************************************/
//充电握手函数
/*****************************************************************************************/
void HandShakeCharge(word count_100ms)
{
static byte flag_TP=0;
if(g_charge_step==STEP_ON_CHARGE) //检测到物理连接正常
{
//if(count_100ms>600) //系统启动后60s未收到0X00的CRM
//{
// g_state_charging[1]=3; //故障级别
// g_state_charging[2]=12; //充电中止原因:其他
//}
}
if(g_charge_step==STEP_CHM_CHARGE) //发送充电握手启动报文
{
if(0==(g_timeover_charge_temp&0X80)) //非通讯超时重新进入此流程
{
if((g_count_10ms_charge%25)==7) //250ms
{
SendBHM(); //发送握手报文
}
}
if(count_100ms>600) //60s未收到0X00的CRM
{
g_state_charging[1]=3; //故障级别
g_state_charging[2]=12; //充电中止原因:其他
}
}
if(g_charge_step==STEP_CRM_CHARGE1) //发送充电握手辨识
{
if((g_count_10ms_charge%25)==7) //250ms
{
flag_TP=1; //在本函数后面用传输协议发送
}
if(count_100ms>50) //5s未收到0XAA的CRM
{
g_timeover_charge=2; //接收0XAA的CRM超时
}
}
if(flag_TP==1) //用传输协议发送充电握手辨识
{
if(SendBRM()) //发送完成
{
flag_TP=0;
}
}
return;
}
static volatile g_flag_relay_charge=0;
/******************************************************************/
//充电辨识阶段函数
void ConfigeCharge(word count_100ms)
{
static byte flag_TP=0;
static byte flag_charge_enbale=0;
static byte s_count=0;
if((g_charge_step>=STEP_CONFIGE_CHARGE1)&(g_charge_step<=STEP_CONFIGE_CHARGE3)) //发送充电参数
{
if((g_count_10ms_charge%50)==7) //500ms执行1次
{
flag_TP=2; //在本函数后面用传输协议发送
}
if(count_100ms>50) //5s未收到充电机时钟同步和最大输出能力
{
g_timeover_charge=3; //通讯超时
}
}
else if(g_charge_step==STEP_CONFIGE_CHARGE4) //发送充电准备未就绪报文
{
if((g_count_10ms_charge%25)==7) //250ms发送1次
{
SendBRO(0X00);
}
if(flag_charge_enbale==0) //判断充电桩输出是否匹配
{
if(1==JugeParamerterCharge()) //充电桩参数判断结果可以充电
{
flag_charge_enbale=1; //充电准备,准备就绪后进入参数配置下一阶段
}
else //充电桩参数判断结果不可以充电
{
g_state_charging[1]=3; //3级故障
g_state_charging[2]=12;
}
}
if(flag_charge_enbale==1) //充电准备
{
if(1==ReadyCharge()) //充电准备就绪
{
g_charge_step=STEP_CONFIGE_CHARGE5;
g_flag_relay_charge=0;
flag_charge_enbale=0;
s_count=0;
}
}
}
else if(g_charge_step==STEP_CONFIGE_CHARGE5) //发送充电准备就绪报文
{
if((g_count_10ms_charge%25)==7) //250ms发送1次
{
SendBRO(0XAA);
}
if(count_100ms>4800) //120s未收到0XAA充电机准备就绪命令
{
g_state_charging[1]=3; //3级故障
g_state_charging[2]=12;
s_count=0;
}
s_count++;
if(g_timeover_charge_temp&0X08)
{
if(s_count>2000) //5s未收到0XAA或0X00充电机准备就绪命令
{
g_timeover_charge_temp&=0XF7;
g_timeover_charge=4;
s_count=0;
}
}
else
{
g_timeover_charge_temp|=0X08;
s_count=0;
}
}
if(flag_TP==2) //用传输协议发送充电参数报文
{
if(SendBCP()) //发送完成或发送中止
{
flag_TP=0;
}
}
return ;
}
void Charging()
{
static byte flag_TP=0;
static word s_count=0;
static byte s_count_BST=0;
if(g_charge_step==STEP_CHARGE1||g_charge_step==STEP_CHARGE2) //发送充电需求
{
static byte s_flag=0;
g_chg.state=3;//进入充电阶段
if(g_flag_relay_charge<10)
{
g_flag_relay_charge++;
if(g_flag_relay_charge==10)
{
ContralRelayCHG(1);
}
}
if(JugeStopCharge())
{
g_charge_step=STEP_STOP_CHARGE; //停止充电
}
if((g_count_10ms_charge%5)==1) //50ms
{
SendBCL();
}
if((g_count_10ms_charge%25)==2) //250ms //发送充电总状态
{
flag_TP=3; //在本函数后面用传输协议发送
}
if(g_charge_step==STEP_CHARGE2) //发送蓄电池状态信息
{
if((g_count_10ms_charge%25)==4) //250ms
{
SendBSM();
}
}
if((g_count_10ms_charge%10)==9) //接收充电准备报文超时
{
s_count++;
if(g_timeover_charge_temp&0X10) //未收到充电准备报文
{
if(s_count>=10) //1s
{
g_timeover_charge_temp&=0XEF; //清标志位
s_count=0;
g_timeover_charge=5; //超时
}
}
else //收到充电准备报文
{
g_timeover_charge_temp|=0X10;
s_count=0;
}
}
if(flag_TP==3) //用传输协议发送充电总状态
{
if(SendBCS()) //发送完成
{
flag_TP=0;
}
}
}
if(STEP_STOP_CHARGE==g_charge_step) //充电中止
{
if(0==(g_flag_stop_charge&0X02)) //判断是否充电机停止充电
{
g_flag_stop_charge|=0X01; //BMS结束充电
}
SendBST(); //正常状态下结束充电
s_count++;
if(s_count>100)
{
g_charge_step=STEP_FINISH_CHARGE;
g_flag_stop_charge|=0X04; //充电中止阶段结束,不再处理充电桩发送的充电中止报文
s_count=0;
}
}
return;
}
void FinishCharge(word count_100ms) //充电结束
{
static byte flag_TP=0;
static byte flag_I=0;
static byte s_count_5A=0;
static byte s_flag_finish=0; //0:电流高于5A,1电流低于5A
if(g_charge_step==STEP_STOP_CHARGE||g_charge_step==STEP_FINISH_CHARGE)
{
if(g_count_10ms_charge%10==3)
{
if(0==s_flag_finish)
{
s_count_5A++;
if(g_send_charge[21]>I_5A_CHARGE) //电流小于5A
{
s_flag_finish=1;
s_count_5A=0;
}
if(s_count_5A>100) // 10s
{
g_state_charging[1]=2; //1级告警
g_state_charging[2]=13;
g_charge_step=STEP_FINISH_CHARGE2;
g_chg.state=4;
s_flag_finish=1;
s_count_5A=0;
}
}
if(s_flag_finish)
{
StopSwitchCharge();
}
}
if(STEP_FINISH_CHARGE==g_charge_step) //充电结束
{
if((g_count_10ms_charge%25)==1)
{
SendBSD();
if(s_flag_finish)
{
if((g_finish_charge&=0X01)) //收到CSD报文且电流小于5A
{
g_chg.state=4; //充电结束
StopSwitchCharge();
}
if(count_100ms>50) //5s未收到CSD
{
g_state_charging[1]=3; //3级告警
g_state_charging[2]=12;
g_chg.state=4; //充电结束
}
}
}
}
}
}
void ReceiveCharge(can_msg msg)
{
g_warn.flag&=0XFFF7; //与充电桩通讯正常
if(msg.CAN_ID==ID_TPCM) //传输协议相关命令
{
CAN_Receive_TPCM(&msg);
}
else if(msg.CAN_ID==ID_CHM) //握手报文
{
if(g_chg.state>=4) //充电结束后收到充电握手报文或辨识报文,重启充电流程
{
//g_chg.state|=0X80;
return;
}
/*if(0==(g_work_mode&0X01)&&g_err_charge==0) //收到握手信号,且无故障启动充电准备
{
g_work_mode|=0X80; //结束其它模式(放电)
work_mode_check=1;
}
else
{*/
g_charge_step=STEP_CHM_CHARGE;
g_receive_charge[0]=msg.TAB[0];
g_receive_charge[1]=msg.TAB[1]+(msg.TAB[2]<<8);
//}
}
else if(msg.CAN_ID==ID_CRM) //握手辨识报文
{
if(g_chg.state==4) //充电结束后收到充电握手报文或辨识报文,重启充电流程
{
g_chg.state|=0X80;
}
/*if(0==(g_work_mode&0X01)&&g_err_charge==0) //收到握手信号,且无故障启动充电准备
{
g_work_mode|=0X80; //结束其它模式(放电)
work_mode_check=1;
}
else
{*/
if(g_charge_step==STEP_ON_CHARGE||g_charge_step==STEP_CHM_CHARGE||g_charge_step==STEP_CRM_CHARGE1)
{
if(0X00==msg.TAB[0]) //未辨识
{
g_charge_step=STEP_CRM_CHARGE1;
g_timeover_charge_temp&=0XFE;
}
else if(0XAA==msg.TAB[0]) //已辨识
{
g_charge_step=STEP_CONFIGE_CHARGE1;
g_timeover_charge_temp&=0XFD;
}
}
g_receive_charge[2]=msg.TAB[0]+(msg.TAB[1]<<8);
g_receive_charge[3]=msg.TAB[2]+(msg.TAB[3]<<8);
//}
}
else if(msg.CAN_ID==ID_CTS) //时钟同步
{
if(g_charge_step==STEP_CONFIGE_CHARGE1||g_charge_step==STEP_CONFIGE_CHARGE2||g_charge_step==STEP_CONFIGE_CHARGE3)
{
if(g_charge_step==STEP_CONFIGE_CHARGE1)
{
g_charge_step=STEP_CONFIGE_CHARGE2;
}
}
}
else if(msg.CAN_ID==ID_CML) //充电机最大输出能力
{
if(g_charge_step==STEP_CONFIGE_CHARGE1||g_charge_step==STEP_CONFIGE_CHARGE2)
{
g_charge_step=STEP_CONFIGE_CHARGE4;
g_receive_charge[4]=(msg.TAB[1]<<8)+msg.TAB[0];
g_receive_charge[5]=(msg.TAB[3]<<8)+msg.TAB[2];
g_receive_charge[6]=(msg.TAB[5]<<8)+msg.TAB[4];
g_receive_charge[7]=(msg.TAB[7]<<8)+msg.TAB[6];
}
g_timeover_charge_temp&=0XFB;
}
else if(msg.CAN_ID==ID_CRO) //充电机准备就绪
{
if(0XAA==msg.TAB[0])
{
if(g_charge_step==STEP_CONFIGE_CHARGE5)
{
g_charge_step=STEP_CHARGE1;
}
}
g_timeover_charge_temp&=0XF7; //收到充电机准备未就绪报文
}
else if(msg.CAN_ID==ID_CCS) //充电机状态报文
{
if(g_charge_step==STEP_CHARGE1)
{
g_charge_step=STEP_CHARGE2;
}
g_timeover_charge_temp&=0XEF;
g_receive_charge[8]=(msg.TAB[1]<<8)+msg.TAB[0];
g_receive_charge[9]=(msg.TAB[3]<<8)+msg.TAB[2];
g_receive_charge[10]=(msg.TAB[5]<<8)+msg.TAB[4];
g_receive_charge[11]=msg.TAB[6]&0X0003;
}
else if(msg.CAN_ID==ID_CST)
{
if(g_flag_stop_charge&0X04) //进入发送充电统计数据报文阶段,不再处理充电中止报文
{
}
else if(g_flag_stop_charge&0X01) //BMS停止充电
{
g_charge_step=STEP_FINISH_CHARGE; //接收到充电桩反馈进入充电结束阶段
}
else //充电机停止充电
{
g_flag_stop_charge|=0X02; //充电桩停止充电标志
g_charge_step=STEP_STOP_CHARGE; //进入充电中止阶段
g_state_charging[2]=4; //充电中止原因:充电桩中止充电
}
g_timeover_charge_temp&=0XDF; //清通讯超时标志
{ //记录c充电桩中止充电原因
byte i,j;
word temp;
for(i=0;i<2;i++)
{
temp=msg.TAB[i];
for(j=0;j<4;j++)
{
if((temp&0X03)==0X01)
{
g_state_charging[3]=4*i+j;
break;
}
}
if(j!=4)
{
break;
}
for(j=0;j<2;j++)
{
if((temp&0X03)==0X01)
{
g_state_charging[3]=8+4*i+j;
break;
}
}
if(j!=2)
{
break;
}
}
}
}
else if(msg.CAN_ID==ID_CSD) //充电机数据统计报文
{
if( g_charge_step==STEP_STOP_CHARGE)
{
g_charge_step=STEP_FINISH_CHARGE;
}
g_finish_charge|=0X01; //收到CSD报文标志
g_timeover_charge_temp&=0XBF;
g_receive_charge[12]=(msg.TAB[3]<<8)+msg.TAB[2];
}
else if(msg.CAN_ID==ID_CEM) //充电机判断超时
{
g_timeover_charge=20;
}
}
void OverTimeCharge(void) //充电超时
{
static byte s_count_timeover=0;
static byte s_count_5A=0;
static byte s_timeover_charge=0;
if(g_timeover_charge) //超时
{
if(g_charge_step!=STEP_OVERTIME_CHARGE1)
{
g_charge_step=STEP_OVERTIME_CHARGE1;
}
s_timeover_charge=g_timeover_charge;
g_timeover_charge=0;
s_count_timeover++;
}
if(g_charge_step==STEP_OVERTIME_CHARGE1)
{
if((g_count_10ms_charge%25)==7)
{
if(s_timeover_charge<16) //BMS判断通讯超时
{
SendBEM(s_timeover_charge);
}
}
if(g_count_10ms_charge%10==4)
{
if(g_send_charge[21]<I_5A_CHARGE)
{
s_count_5A++;
if(s_count_5A>100) //10s
{
StopSwitchCharge(); //关闭充电继电器
s_count_5A=0;
s_count_timeover=0;
g_state_charging[1]=2; //1级故障
g_state_charging[2]=13;
}
}
else
{
StopSwitchCharge(); //关闭充电继电器
s_count_5A=0;
if(s_count_timeover>=4) //已经重新连接过三次
{
s_count_timeover=0;
g_charge_step=STEP_ERR_CHARGE;
g_chg.state=4; //充电结束
/******************************* g_warn.flag|=0X80; //充电桩通讯故障**********************/
}
else
{
if(s_timeover_charge>16)
{
g_charge_step=STEP_CRM_CHARGE1; //等待充电辨识
g_timeover_charge_temp&=0X0F; //超时标志
}
}
}
}
}
}
/********************************************************/
//充电基本函数
/********************************************************/
void ChargeBasic()
{
static byte s_charge_step=0;
static word s_count_100ms=0;
if(g_chg.state!=4) //无充电故障
{
g_count_10ms_charge++; //10ms计数
if(g_count_10ms_charge>=1000)
{
g_count_10ms_charge=0;
}
if((g_count_10ms_charge%10)==0)
{
s_count_100ms++;
}
if(s_charge_step!=g_charge_step)
{
s_charge_step=g_charge_step;
s_count_100ms=0;
}
HandShakeCharge(s_count_100ms); //握手
ConfigeCharge(s_count_100ms); //参数配置
Charging(); //充电阶段
FinishCharge(s_count_100ms); //充电结束
OverTimeCharge(); //超时处理
}
}
/**************************************************************************************/
/**************************************************************************************/
//直流充电对外函数
/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/
//充电模块基本数据
/**************************************************************************************/
void SetDataCharge(void)
{
g_send_charge[0]=g_warn.parameter[4*ADD_OV_TOTAL+LEVEL_WARN-1]; //最高允许充电总电压 //0.1V
g_send_charge[1]=3;//g_battery.type; //电池类型
g_send_charge[2]=g_SOC.C/10*4; //电池容量 //Ah
g_send_charge[3]=g_num.system[0]*8; //额定电池电压 //0.1V
g_send_charge[4]=g_warn.parameter[4*ADD_OV_CELL+LEVEL_WARN-1]; //最高允许充电单体电压 //mV
g_send_charge[5]=g_warn.parameter[4*ADD_OI_CHG+LEVEL_WARN-1]; //最高允许充电电流 //0.1A,偏移-400A,充电为负
g_send_charge[6]=(((32*g_num.system[0])/100)*(g_SOC.C/10))/10; //额定总能量, //0.1kW.h
g_send_charge[7]=g_warn.parameter[4*ADD_OT_CHG+LEVEL_WARN-1]; //最高允许温度, //1C,偏移-50C
g_send_charge[8]=g_SOC.SOC; //SOC //0.1%
g_send_charge[9]=g_battery.V_total<4000?4000:g_battery.V_total; //当前充电总电压 //0.1V
/********************************************************************/
//以下内容在ChargeIV()中设置
g_send_charge[10]=g_chg.V; //充电电压需求 //0.1V
g_send_charge[11]=g_chg.I; //充电电流需求 //同上电流
g_send_charge[12]=(g_chg.flag==0)?2:1; //充电模式 //1恒压,2恒流
if(g_battery.V_max[4]>3480) //最高单体电压 //mV
{
g_send_charge[13]=3480;
}
else if(g_battery.V_max[4]<3000) //最高单体电压 //mV
{
g_send_charge[13]=3000;
}
else
{
g_send_charge[13]=g_battery.V_max[4];
}
//剩余充电时间根据SOC与充电电流估算
//g_send_charge[14]=g_send_charge[14]; //估计剩余充电时间 //min
g_send_charge[15]=g_battery.NO_V_max[4]; //最高电压序号
if(g_battery.T_max[4]>1100) //最高温度 //mV
{
g_send_charge[16]=1100;
}
else if(g_battery.T_max[4]<500) //最高温度 //mV
{
g_send_charge[16]=500;
}
else
{
g_send_charge[16]=g_battery.T_max[4];
} //最高温度
g_send_charge[17]=g_battery.NO_T_max[4]; //最高温度序号
if(g_battery.T_min[4]>1100) //最低温度 //mV
{
g_send_charge[18]=1100;
}
else if(g_battery.T_min[4]<500) //最低温度 //mV
{
g_send_charge[18]=500;
}
else
{
g_send_charge[18]=g_battery.T_min[4];
}
g_send_charge[19]=g_battery.NO_T_min[4]; //最低温度序号
g_send_charge[20]=0X1000; //充电状态,12位:0充电禁止,1充电允许
g_send_charge[21]=g_battery.I_total;
//g_send_charge[22]=g_battery.V_min[4]; //最低电压 //mV
if(g_battery.V_min[4]>3480) //最高单体电压 //mV
{
g_send_charge[22]=3480;
}
else if(g_battery.V_min[4]<3000) //最高单体电压 //mV
{
g_send_charge[22]=3000;
}
else
{
g_send_charge[22]=g_battery.V_min[4];
}
}
/**************************************/
//充电发送CAN选择
void CAN_SendCharge(can_msg msg)
{
g_flag_send_CANaaaa=MSCAN4SendMsg(msg);
}
/**************************************************/
//功能:检测到充电枪后的启动操作(五洲龙电池包打开电池包内继电器)(开始充电流程前的准备工作)
//返回值:0启动操作未完成,1启动操作已完成
/**************************************************/
byte StartCharge()
{
/*if(OpenRelayCB(&g_contral,&g_other,&g_num))
{
return 1;
}*/
return 1;
}
/**********************************************************/
//充电准备:确定充电桩输出能力后的自检及闭合充电继电器
//返回值:0正在准备,1,准备就绪,可以充电 2,故障
/**********************************************************/
byte ReadyCharge(void) //准备充电
{
static byte s_step=0;
static word s_count=0;
if(s_step==0)
{
u8 i;
u16 V_min=0XFFFF;
u8 NO_V_min=0;
ContralRelayCHG(1);
if(g_battery.V_min[4]==0) //电压
{
return 0;
}
for(i=0;i<NUM_PARALLEL;i++)
{
if(g_battery.V_total_mode[i]<V_min)
{
V_min=g_battery.V_total_mode[i];
NO_V_min=i;
}
}
for(i=0;i<NUM_PARALLEL;i++)
{
//if(g_battery.V_total_mode[i]<g_battery.V_total_mode[NO_V_min]+20) //电池组总电压与最高电压压差小于5V闭合电池组继电器
{
g_contral.state_battery_mode|=(0X01<<i);
}
}
s_count=0;
s_step=1; //
}
else if(s_step==1)
{
s_count++;
if(s_count>1200)
{
s_step=0;
s_count=0;
return 1;
}
}
return 0;
}
/********************************************/
//断开充电继电器
/********************************************/
void StopSwitchCharge(void) //关闭充电开关
{
ContralRelayCHG(0);
g_contral.state_battery_mode=0;
}
/*************************************************************************/
//充电枪电压温度转换函数
//输入:V_data采集电压,V_total总电压、RES_series_connect,串联电阻
/*************************************************************************/
word T_CalCharge(word V_data,word V_total,word RES_series_connect) //计算温度,参数:采集电压,总电压、串联电阻
{
word res_data; //NTC阻值
word temp_res_table[100]={ 65500,65300,65300,65200,65100,
34363,30053,26336,23124,20341,
17927,15827,13998,12402,11006,
9784, 8711, 7768 ,6938 ,6206 ,
5560 ,4987 ,4481 ,4031 ,3631 ,
3275 ,2958 ,2676 ,2423 ,2197 ,
1994 ,1812 ,1649 ,1502 ,1369 ,
1250 ,1142 ,1045 ,957 ,877 ,
805 ,740 ,680 ,626 ,576 ,
531 ,490 ,453 ,419 ,387 ,
359 ,333 ,308 ,286 ,266 ,
247 ,230 ,214 ,200 ,186 ,
174 ,162 ,152 ,142 ,133 ,
124 ,116 ,109 ,102 ,96 ,
90 ,85 ,80 ,75 ,70 ,67}; //NTC阻值表,表示温度-50度到100度每间隔2度对应的阻值
res_data=((((dword)(RES_series_connect/10))*V_data)/(V_total-V_data))&0XFFFF; //计算NTC电阻值
return (750);//restotemp(res_data,temp_res_table));
}
/******************************************************************/
//充电枪温度检测及过温判断
//返回:0,正常,1过温
/******************************************************************/
byte JugeTCharge(void)
{
static byte s_count_OT=0;
word T_charge[2];
T_charge[0]=ADCapture(13,12,4); //电压采集
T_charge[1]=ADCapture(6,12,4); //电压采集
T_charge[0]=T_CalCharge(T_charge[0],5170,1000); //电压转换为温度 单位:0.1C偏移-50C
T_charge[1]=T_CalCharge(T_charge[1],5170,1000); //电压转换为温度 单位:0.1C偏移-50C
if(T_charge[0]<T_charge[1])
{
T_charge[0]=T_charge[1];
}
T_charge[0]=(T_charge[0]+5)/10; //单位:C 偏移-50C
/*if(CountJuge(&s_count_OT,10,T_charge[0]>130)) //判断连续10次温度高于80C
{
return 1; //充电枪过温
}*/
return 0;
}
volatile byte g_flag_stop_chg_test=0;
/*****************************************************************/
//返回值:0正常充电,1其他:停止充电
/*****************************************************************/
byte JugeStopCharge() //中止充电判断
{
static byte s_count=0;
static byte s_count1=0;
//故障判断
//if(JugeTCharge()) //充电枪上温度检测与故障判断
//{
//g_state_charging[2]=7; //充电枪温度过高
//g_state_charging[1]=2; //2级故障
//}
if(g_warn.state[ADD_OV_CELL]==LEVEL_WARN||g_warn.state[ADD_OV_TOTAL]==LEVEL_WARN) //单体过压或总压过压
{
g_state_charging[2]=14; //电压异常
g_state_charging[1]=2; //2级故障
g_flag_stop_chg_test=1;
}
if(g_warn.state[ADD_OT_CHG]==LEVEL_WARN)
{
g_state_charging[2]=9; //电池过温
g_state_charging[1]=2; //2级故障
g_flag_stop_chg_test=3;
}
if(g_warn.state[ADD_OI_CHG]==LEVEL_WARN)
{
g_state_charging[2]=13; //电流过大
g_state_charging[1]=2; //2级故障
g_flag_stop_chg_test=7;
}
if(g_chg.flag_full)
{
g_state_charging[2]=3; //达到充满电压
g_flag_stop_chg_test=6;
}
if(g_count_10ms_charge&0X01)
{
if(g_battery.I_total+100<g_send_charge[11])
{
s_count++;
if(s_count>30)
{
g_state_charging[2]=13; //电流过大
g_state_charging[1]=2; //2级故障
g_flag_stop_chg_test=7;
}
}
else
{
s_count=0;
}
}
if(g_warn.flag_contral&&g_state_charging[2]==0)
{
g_state_charging[2]=12; //其他
g_state_charging[1]=2; //2级故障
g_flag_stop_chg_test=2;
}
return(g_state_charging[2]);
}
/*************************************************************************************/
//直流充电函数
/*************************************************************************************/
void ChargeDC(void)
{
static u8 s_count=0;
if(g_other.flag_10ms==0)
{
return;
}
ReadCharge();
if(g_chg.state>=4) //结束充电
{
//关闭相关继电器
//清除相关标志位
StopSwitchCharge();
g_charge_step=0;
g_state_charging[1]=0;
if(g_chg.state==8) //充电枪断开
{
g_chg.state=0;
g_contral.state_system=0;
}
s_count=0;
}
else if(g_chg.state==1) //充电状态
{
s_count++;
if(s_count>10) //等待100ms确定放电模块已经关闭
{
g_charge_step=0;
g_state_charging[1]=0;
g_contral.state_system=1;
g_contral.state_CHG=1;
g_state_charging[2]=0; //充电结束原因清0
g_charge_step=1; //充电流程:检测到充电枪
g_timeover_charge_temp=0; //充电超时标志清0
g_timeover_charge=0; //充电超时标志清0
g_flag_stop_charge=0; //充电结束标志
s_count=0;
g_chg.state=2;
}
}
else if(g_chg.state==2||g_chg.state==3)
{
if(1==StartCharge()) //1,物理连接正常,可以开启充电流程,返回0,操作未完成,其他物理连接不正常
{
SetDataCharge(); //设置充电相关参数
ChargeBasic(); //充电基本函数
}
}
}
/*#if CHARGE_TYPE==1 //直流充电
#pragma CODE_SEG NON_BANKED
#pragma CODE_SEG DEFAULT
#endif*/