GBT27930-2015电动汽车非车载传导式充电机与电池管理系统之间的通信协议-开发记录

目前因为没有插枪拔枪检测电路,所以收到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*/

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值