Files

2682 lines
92 KiB
C
Raw Permalink 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 "bms/bms_task.h"
#include "app_init/app_init.h"
#include "app_init/task_lock.h"
#include "mylog/mylog.h"
#include "publicdata/publicdata.h"
#include "wdt_task/wdt_task.h"
#define BMS_TASK_ID (TASK_ID_BmsComm)
#define BMS_SLEEP_TIME_MS() (MY_GET_SLEEP_TIME(BMS_TASK_ID))
#define BMS_LOCK_INIT() (u8_task_lock_ctrl(BMS_TASK_ID, TASK_LOCK_OP_INIT))
#define BMS_LOCK_TAKE() (u8_task_lock_ctrl(BMS_TASK_ID, TASK_LOCK_OP_TAKE))
#define BMS_LOCK_GIVE() (u8_task_lock_ctrl(BMS_TASK_ID, TASK_LOCK_OP_GIVE))
#define BMS_FEED_DOG() (v_wdt_setFlag(BMS_TASK_ID))
#define BMS_LOG(fmt, ...) MYLOG_MSG(BMS_TASK_ID, (fmt), ##__VA_ARGS__)
S_BMS_DATA s_bms_data; //BMS数据
/****************************************************************************系统集成改动部分-开始******************************************************/
/*线程初始化及线程锁操作函数*/
#if 1
/****************************************************
*功能说明: 获取遥信遥测变量控制锁
*参数说明:
* 输入参数: void
* 输出参数: U8_T 1成功或者0失败
*备注:
****************************************************/
static U8_T u8_bms_get_lock()
{
BMS_LOCK_TAKE();
return 1;
}
/****************************************************
*函数名称: void u8_free_yxyc_lock()
*功能说明: 释放bms变量控制锁
*参数说明:
* 输入参数: void
* 输出参数: void
*备注:
****************************************************/
static void u8_bms_free_lock()
{
BMS_LOCK_GIVE();
}
#endif
#if 1 //can数据收发接口
static U32_T u32_bms1_can_tx(CAN_DATA *pt_msg)
{
v_can_tx(BMS_CAN_ID_1, pt_msg);
return 0;
}
static U32_T u32_bms1_can_rx(CAN_DATA *pt_msg)
{
U32_T u32_rcvCnt=0;
u32_rcvCnt = u8_can_rx(BMS_CAN_ID_1,pt_msg);
return u32_rcvCnt;
}
static U32_T u32_bms2_can_tx(CAN_DATA *pt_msg)
{
v_can_tx(BMS_CAN_ID_2, pt_msg);
return 0;
}
static U32_T u32_bms2_can_rx(CAN_DATA *pt_msg)
{
U32_T u32_rcvCnt=0;
u32_rcvCnt = u8_can_rx(BMS_CAN_ID_2,pt_msg);
return u32_rcvCnt;
}
#endif
#if 1 //周期计数控制
/****************************************************
*函数名称: U8_T u8_tim_ret(U8_T gunNo,E_BMS_TIM e_flag,U16_T cnt_tim)
*功能说明: 获取是否到达对应定时时间
*参数说明:
* 输入参数: U8_T gunNo,E_BMS_TIM e_flag,U16_T cnt_tim
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static U8_T u8_tim_ret(U8_T gunNo,E_BMS_TIM e_flag,U16_T cnt_tim)
{
U8_T ret = 0;
T_BMS_TIM *t_bms_tim = &s_bms_data.t_bms_tim[gunNo];
switch (e_flag)
{
case cnt50ms:
if(t_bms_tim->cnt50ms >= cnt_tim)
{
t_bms_tim->cnt50ms = 0;
ret = 1;
}
break;
case cnt250ms:
if(t_bms_tim->cnt250ms >= cnt_tim)
{
t_bms_tim->cnt250ms = 0;
ret = 1;
}
break;
case cnt500ms:
if(t_bms_tim->cnt500ms >= cnt_tim)
{
t_bms_tim->cnt500ms = 0;
ret = 1;
}
break;
case cnt_global:
if(t_bms_tim->u16_global_timerCnt >= cnt_tim)
{
t_bms_tim->u16_global_timerCnt = 0;
ret = 1;
}
break;
case cnt_bcl:
if(t_bms_tim->u16_bcl_timerCnt >= cnt_tim)
{
t_bms_tim->u16_bcl_timerCnt = 0;
ret = 1;
}
break;
case cnt_bro_aa:
if(t_bms_tim->u16_bro_timerCnt >= cnt_tim)
{
t_bms_tim->u16_bro_timerCnt = 0;
ret = 1;
}
break;
default:
break;
}
return ret;
}
/****************************************************
*函数名称: U8_T u8_tim_reset(U8_T gunNo,E_BMS_TIM e_flag)
*功能说明: 重置对应定时计数
*参数说明:
* 输入参数: U8_T gunNo,E_BMS_TIM e_flag
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static U8_T u8_tim_reset(U8_T gunNo,E_BMS_TIM e_flag)
{
T_BMS_TIM *t_bms_tim = &s_bms_data.t_bms_tim[gunNo];
switch (e_flag)
{
case cnt50ms:
t_bms_tim->cnt50ms = 0;
break;
case cnt250ms:
t_bms_tim->cnt250ms = 0;
break;
case cnt500ms:
t_bms_tim->cnt500ms = 0;
break;
case cnt_global:
t_bms_tim->u16_global_timerCnt = 0;
break;
case cnt_bcl:
t_bms_tim->u16_bcl_timerCnt = 0;
break;
case cnt_bro_aa:
t_bms_tim->u16_bro_timerCnt = 0;
break;
default:
break;
}
return 1;
}
/****************************************************
*功能说明: bms 发送周期计数累加 10ms
*参数说明:
* 输入参数:
* 输出参数:
****************************************************/
void v_bms_add_timer(void)
{
U8_T i;
T_BMS_TIM *t_bms_tim = NULL;
for(i=0;i<2;i++)
{
t_bms_tim = &s_bms_data.t_bms_tim[i];
//bms发送周期计数
if(t_bms_tim->cnt50ms < BMS_TIM_50MS)
t_bms_tim->cnt50ms++;
if(t_bms_tim->cnt250ms < BMS_TIM_250MS)
t_bms_tim->cnt250ms++;
if(t_bms_tim->cnt500ms < BMS_TIM_500MS)
t_bms_tim->cnt500ms++;
//bms超时周期计数
if(t_bms_tim->u16_global_timerCnt < BMS_TIM_60S)
t_bms_tim->u16_global_timerCnt ++;
if(t_bms_tim->u16_bcl_timerCnt < BMS_TIM_60S) //BSD报文超时复用该变量 所以扩展到10秒
t_bms_tim->u16_bcl_timerCnt ++;
if(t_bms_tim->u16_bro_timerCnt < BMS_TIM_60S)
t_bms_tim->u16_bro_timerCnt ++;
}
}
#endif
#if 1 //公共使用函数u
/****************************************************
*函数名称: void v_set_rt_state(U8_T gunNo)
*功能说明: 设置对外实时状态
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230605
*修改内容: 20230605 第一次创建子函数
****************************************************/
static void v_set_rt_state(U8_T gunNo,BMS_STATE_E state)
{
//外侧已经申请锁了 这里不需要再申请了
if(state == s_bms_data.s_bms_rt_data[gunNo].e_real_state)
return;
BMS_LOG("gun %d set rt state %d --> %d\n",gunNo,s_bms_data.s_bms_rt_data[gunNo].e_real_state,state);
s_bms_data.s_bms_rt_data[gunNo].e_real_state = state;
}
static void v_set_bms_stop_info(U8_T gunNo ,E_BMS_STOP_INFO e_stop_reason)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_stop_info == 0)
pt_bms->e_stop_info = e_stop_reason; //充电停止原因
v_set_rt_state(gunNo, BMS_STATE_STOP); //对外状态 停止
}
/****************************************************
*功能说明: 设置BMS控制流程状态
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230605
*修改内容: 20230605 第一次创建子函数
****************************************************/
static void v_set_flow_state(U8_T gunNo,GB_BMS_STATE_E state)
{
if(state == s_bms_data.s_bms_rt_data[gunNo].e_state)
return;
BMS_LOG("gun %d set flow state %d --> %d\n",gunNo,s_bms_data.s_bms_rt_data[gunNo].e_state,state);
u8_bms_get_lock();//申请锁
s_bms_data.s_bms_rt_data[gunNo].e_state = state;
u8_bms_free_lock();//释放锁
}
#endif
#if 1 //超时判断
/****************************************************
*功能说明: bms超时处理
*参数说明:
* 输入参数: U8_T type_flag类型 U8_T gunNo 枪号 reconn_flag 重连标志 0不重连 1重连 timeout_flag超时报文标志
* 输出参数: U8_T 0赋值失败 1赋值成功
****************************************************/
static U8_T u8_bms_timeout(U8_T type_flag,U8_T gunNo, U8_T reconn_flag , U8_T timeout_flag)
{
U8_T ret = 0;
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if((pt_bms->u16_timeout_flag & timeout_flag) != 0) //已经存在 则不动作
return ret;
if ((s_bms_data.u8_gun_type[gunNo] == 0))
pt_bms->u8_reconn_flag = 0; //欧标:通信超时 不重连
else
pt_bms->u8_reconn_flag = reconn_flag; //国标:重新进行握手连接
pt_bms->u16_timeout_flag |= timeout_flag; //CEM
if(timeout_flag == GB_BRM_TIMEOUT_FLAG){
if(pt_bms->e_stop_info == 0) pt_bms->e_stop_info = E_BMS_STOP_15011; //充电停止原因
}
else if(timeout_flag == GB_BCP_TIMEOUT_FLAG){
if(pt_bms->e_stop_info == 0) pt_bms->e_stop_info = E_BMS_STOP_15003; //充电停止原因
}
else if(timeout_flag == GB_BRO_TIMEOUT_FLAG){
if(pt_bms->e_stop_info == 0)
{
if(type_flag == 0x00)
pt_bms->e_stop_info = E_BMS_STOP_15009; //BRO00 超时 充电停止原因
else if(type_flag == 0x01)
pt_bms->e_stop_info = E_BMS_STOP_15010; //BROAA超时 充电停止原因
else if(type_flag == 0x02)
pt_bms->e_stop_info = E_BMS_STOP_15004; //充电停止原因
}
}
else if(timeout_flag == GB_BCS_TIMEOUT_FLAG){
if(pt_bms->e_stop_info == 0) pt_bms->e_stop_info = E_BMS_STOP_15005; //充电停止原因
}
else if(timeout_flag == GB_BCL_TIMEOUT_FLAG){
if(pt_bms->e_stop_info == 0) pt_bms->e_stop_info = E_BMS_STOP_15006; //充电停止原因
}
else if(timeout_flag == GB_BST_TIMEOUT_FLAG){
if(pt_bms->e_stop_info == 0) pt_bms->e_stop_info = E_BMS_STOP_15007; //充电停止原因
}
else if(timeout_flag == GB_BSD_TIMEOUT_FLAG){
if(pt_bms->e_stop_info == 0) pt_bms->e_stop_info = E_BMS_STOP_15011; //充电停止原因
}
v_set_rt_state(gunNo, BMS_STATE_TIMEOUT); //bms状态 = 超时, flow任务检测到后停止此次充电任务
v_set_flow_state(gunNo,GB_BMS_TX_CEM); //发送BEM
ret = 1;
return ret ;
}
/****************************************************
*功能说明: bms超时处理 bhm测试
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_timeout_bhm(U8_T gunNo)
{
S_BMS_RT_DATA *rt_bms = &s_bms_data.s_bms_rt_data[gunNo];
v_set_rt_state(gunNo, BMS_STATE_HANDSHAKE_FAIL);
BMS_LOG("BMS HS TO\n");
//清除底层的多包状态
v_sae1393_clear_multi_pacet(&s_bms_data.s_gb_bms_can[gunNo].pt_dll);
rt_bms->e_bms_standard = BMS_2011;
}
/****************************************************
*功能说明: bms超时处理 brm超时
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_bms_timeout_brm(U8_T gunNo)
{
U8_T ret ;
//山东省电动优化:取消重连机制
if(u16_bms_get_sys_para(0,E_BMS_GET_PARA_GB_EN) == 1) //国标
ret = u8_bms_timeout(0,gunNo,1,GB_BRM_TIMEOUT_FLAG);
else
ret = u8_bms_timeout(0,gunNo,0,GB_BRM_TIMEOUT_FLAG);
//第一次赋值
if(ret == 1)
{
BMS_LOG("BMS HS BRM TO\n");
}
}
/****************************************************
*功能说明: bms超时处理 bcp超时
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_bms_timeout_bcp(U8_T gunNo)
{
U8_T ret ;
ret = u8_bms_timeout(0,gunNo,1,GB_BCP_TIMEOUT_FLAG);
//第一次赋值
if(ret == 1)
{
BMS_LOG("BMS BCP TO\n");
}
}
/****************************************************
*功能说明: bms超时处理 bro超时
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_bms_timeout_bro(U8_T gunNo,U8_T u8_flag)
{
U8_T ret ;
ret = u8_bms_timeout(u8_flag,gunNo,1,GB_BRO_TIMEOUT_FLAG);
//第一次赋值
if(ret == 1)
{
if(u8_flag == 0x00)
BMS_LOG("BMS BRO 0x00 RX TO(5s)\n");
else if(u8_flag == 0x01)
BMS_LOG("BMS BRO 0xAA RX TO(60s)\n");
else if(u8_flag == 0x02)
BMS_LOG("BMS BRO RX TO(5s)\n");
}
}
/****************************************************
*功能说明: bms超时处理 bcs超时
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_bms_timeout_bcs(U8_T gunNo,U8_T u8_flag)
{
U8_T ret ;
ret = u8_bms_timeout(0,gunNo,1,GB_BCS_TIMEOUT_FLAG);
//第一次赋值
if(ret == 1)
{
if(u8_flag == 00)
BMS_LOG("BMS BCS TO\n");
else
BMS_LOG("BMS CHG BCS TO\n");
}
}
/****************************************************
*功能说明: bms超时处理 bcl超时
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_bms_timeout_bcl(U8_T gunNo,U8_T u8_flag)
{
U8_T ret ;
ret = u8_bms_timeout(0,gunNo,1,GB_BCL_TIMEOUT_FLAG);
//第一次赋值
if(ret == 1)
{
if(u8_flag == 00)
{
BMS_LOG("BMS BCL TO\n");
}
else
BMS_LOG("BMS CHG BCL TO\n");
}
}
/****************************************************
*功能说明: bms超时处理 bst超时
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_bms_timeout_bst(U8_T gunNo)
{
U8_T ret ;
ret = u8_bms_timeout(0,gunNo,0,GB_BST_TIMEOUT_FLAG);
//第一次赋值
if(ret == 1)
{
BMS_LOG("BMS END BST RX TO\n");
}
}
/****************************************************
*功能说明: bms超时处理 bsd超时
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_bms_timeout_bsd(U8_T gunNo,U8_T u8_flag)
{
U8_T ret ;
ret = u8_bms_timeout(0,gunNo,0,GB_BSD_TIMEOUT_FLAG);
//第一次赋值
if(ret == 1)
{
BMS_LOG("BMS END BSD RX TO\n");
}
}
//超时处理
void v_bms_timeout_handle(U8_T gunNo)
{
S_BMS_RT_DATA *pt_bms;
S_BMS_RT_DATA *gb_data;
// U16_T u16_OTcnt_5s_BHM = 500; //超时计数基准 5s=10ms*500
// U16_T u16_OTcnt_5s_BRM = 3000; //超时计数基准 5s=10ms*500 国标5s,省电动优化为30s,取消重连机制
// U16_T u16_OTcnt_5s_BCP = 520; //超时计数基准 5s=10ms*500
// U16_T u16_OTcnt_5s_BRO = 500; //超时计数基准 5s=10ms*500
// U16_T u16_OTcnt_60s_BRO_0xAA = 6000; //超时计数基准 60s=10ms*6000
// U16_T u16_OTcnt_5s_BCS_1 = 520; //超时计数基准 5s=10ms*500
// U16_T u16_OTcnt_1s_BCL_1 = 120; //超时计数基准 1s=10ms*100
// U16_T u16_OTcnt_5s_BCS_2 = 500; //超时计数基准 5s=10ms*500
// U16_T u16_OTcnt_1s_BCL_2 = 100; //超时计数基准 1s=10ms*100
// U16_T u16_OTcnt_5s_BST = 520; //超时计数基准 5s=10ms*500 -- 充电结束阶段的暂不延长
// U16_T u16_OTcnt_10s_BSD = 1000; //超时计数基准 10s=10ms*1000
U8_T brm_outTime_k = 1; //BRM报文接收超时判定系数 1为不延长,5秒 6为30秒
U8_T bhm_outTime_k = 1; //BhM报文接收超时判定系数 1为不延长,5秒 2为10秒
U8_T bcl_outTime_k = 1; //BCL报文接收超时判定系数 1为不延长,1秒 2为2秒
U8_T bcs_outTime_k = 1; //BCS报文接收超时判定系数 1为不延长,5秒 2为10秒
if(u16_bms_get_sys_para(0,E_BMS_GET_PARA_GB_EN) == 0)
{
//非国标下 BRM超时判定时间延长至30秒
brm_outTime_k = 6;
bhm_outTime_k = 2;
bcl_outTime_k = 2;
bcs_outTime_k = 2;
//BMS_LOG("非国标,超时时间延长\n");
}
pt_bms = &(s_bms_data.s_bms_rt_data[gunNo]);
gb_data = &(s_bms_data.s_bms_rt_data[gunNo]);
if(pt_bms->u8_reconn_flag == 1) //如果正在进行重连,则不再做超时判定
return;
switch(gb_data->e_state)
{
case GB_BMS_STOP: //停止充电
{
break;
}
case GB_BMS_HANDSHAKE_TX_CHM: //握手阶段,发送充电机握手CHM,等待接收车辆握手BHM - 自辅源闭合起经过5s
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S*bhm_outTime_k) == 0)
break;
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if (!(s_bms_data.u8_gun_type[gunNo] == 0))
v_bms_timeout_bhm(gunNo);
#endif
break;
case GB_BMS_HANDSHAKE_TX_CRM_00: //握手阶段,发送CRM_00,等待接收BMS和车辆辨识报文BRM
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_10S*brm_outTime_k) == 0)
break;
}
else
#endif
{
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S*brm_outTime_k) == 0)
break;
}
v_bms_timeout_brm(gunNo);
break;
case GB_BMS_HANDSHAKE_TX_CRM_AA: //握手阶段,己收到BMS和车辆辨识报文BRM,发送CRM_AA,等待接收电池充电参数报文BCP
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_60S) == 0)
break;
}
else
#endif
{
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S) == 0)
break;
}
v_bms_timeout_bcp(gunNo);
break;
case GB_BMS_CFG_TX_CTS_CML: //充电参数配置阶段,己收到电池充电参数报文BCP,发送CTS和CML,等待接收BMS完成充电准备报文BRO
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S) == 0)
break;
v_bms_timeout_bro(gunNo,0x00);
break;
case GB_BMS_CFG_RX_BRO_AA: //充电参数配置阶段,己收到电池充电参数报文BRO_00,发送CTS和CML,等待接收BMS完成充电准备报文BRO_AA
if(u8_tim_ret(gunNo,cnt_bro_aa,BMS_TIM_60S) == 1)
{
v_bms_timeout_bro(gunNo,0x01);
}
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S) == 1)
{
v_bms_timeout_bro(gunNo,0x02);
}
break;
case GB_BMS_CFG_TX_CRO_00: //充电参数配置阶段,接收BMS完成充电准备报文BRO_AA,发送充电机充电准备完成报文CRO_00
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S) == 1)
{
v_bms_timeout_bro(gunNo,0x01);
}
break;
case GB_BMS_CFG_TX_CRO_AA: //充电参数配置阶段,接收BMS完成充电准备报文BRO,发送充电机充电准备完成报文CRO_AA,等待接收电池总充电状态BCS/BCL
#if 1
//if((t_gb_bms_data.u8_bcs_rx_flag == 1) || (t_gb_bms_data.u8_bcl_rx_flag == 1))
{
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S*bcs_outTime_k) == 1)
{
v_bms_timeout_bcs(gunNo,0x00);
}
if(u8_tim_ret(gunNo,cnt_bcl,BMS_TIM_1S*bcl_outTime_k) == 1)
{
v_bms_timeout_bcl(gunNo,0x00);
}
}
#endif
break;
case GB_BMS_CHARGE_STAGE: //充电阶段,接收报文BCS和BCL
// if(g_t_share_data.t_sys_cfg.u8_GBenable == 0)
// break;
#if 1
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S*bcs_outTime_k) == 1)
{
v_bms_timeout_bcs(gunNo,0x01);
}
if(u8_tim_ret(gunNo,cnt_bcl,BMS_TIM_1S*bcl_outTime_k) == 1)
{
v_bms_timeout_bcl(gunNo,0x01);
}
#endif
break;
case GB_BMS_CHARGE_TX_CST: //充电结束阶段,发送充电机中止充电报文CST,等待接收BMS中止充电报文BST
if(pt_bms->u8_bms_rx_flag[9] == 0) //bst未接收到
{
if(u8_tim_ret(gunNo,cnt_global,BMS_TIM_5S) == 1)
{
v_bms_timeout_bst(gunNo);
}
}
if(pt_bms->u8_bms_rx_flag[10] == 0) //BSD未收到
{
if(u8_tim_ret(gunNo,cnt_bcl,BMS_TIM_10S) == 1)
v_bms_timeout_bsd(gunNo,0); //-- bms协议一致性测试使用
}
break;
case GB_BMS_FINISH_RX_BSD: //充电结束阶段,已收到BSD,发送CSD
if(pt_bms->u8_bms_rx_flag[10] == 0) //BSD未收到
{
if(u8_tim_ret(gunNo,cnt_bcl,BMS_TIM_10S) == 1)
v_bms_timeout_bsd(gunNo,0); //-- bms协议一致性测试使用
}
break;
default:
break;
}
}
#endif
#if 1 //接收相关
/****************************************************
*函数名称: v_bms_err_data()
*功能说明: 判断电流数据是否在有效范围内
*参数说明:
* 输入参数: U8_T gunNo
* 输出参数:
****************************************************/
void v_bms_err_data(U8_T gunNo )
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->t_bcp_data.f32_batt_charge_max_curr < 0.0f &&
pt_bms->t_bcp_data.f32_batt_charge_max_curr > 2000.0f) //如果电流不在0-2000A范围内则停止充电
{
BMS_LOG("BMS Imax=%.2f\n", pt_bms->t_bcp_data.f32_batt_charge_max_curr);
pt_bms->e_state = GB_BMS_STOP;
v_set_rt_state(gunNo, BMS_STATE_ERR); //bms状态转数据异常
}
}
/****************************************************
*功能说明: BHM数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号 ,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bhm_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
F32_T f32_data;
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
/*
1.1 2.8 CR_Plc_EvPermissibleMaxVolt Max permissible voltage (not supported at this stage in CCS) 0.1 0 0~6553.5 V 不支持 不判断
车最高允许充电电压 最高允许充电总电压
3.1 3.8 CR_Plc_Aagvalue Average Attenuation Gain, at start: 00  end of SLAC:≠ 0 1 0 0 ~ 255 添加项 判断
信号衰减值 开始时的平均衰减增益:00 ;SLAC计算结果:≠ 0
4.1 4.2 CR_Plc_CpStatus See reference 1 0 0 ~ 7 添加项 判断
CP状态 0:12v未插枪;1:9v已插枪;2:9v占空比状态;3:6v占空比准备充电状态
4.5 4.6 CR_Plc_CommStart 0: PLC_Comm did not start; 1: Start PLC_Comm 1 0 0 ~ 7 添加项 判断
通信启动 0:通信未启动;1:启动PLC通信
5.1 6.8 SECC固件版本编译日期-年 "例 5.1~8.8 22 20 01 06
例 22 20;2022年
例 01 ;1月
例 06 ;6日" 添加项 不判断
7.1 7.8 SECC固件版本编译日期-月 添加项 不判断
8.1 8.8 SECC固件版本编译日期-日 添加项 不判断
*/
if ((pt_msg->u16_len >= 2) /*&& (pt_msg->u8_pri == 6)*/) //收到BHM
{
//最大允许充电电压
f32_data = GetU16Data(pt_msg->u8_data[1],pt_msg->u8_data[0]) / 10.0;
#if CAN_PLC_FLAG
pt_bms->t_bhm_data.u8_CR_Plc_Aagvalue = pt_msg->u8_data[2]; // 信号衰减值
pt_bms->t_bhm_data.u8_CR_Plc_CpStatus = (pt_msg->u8_data[3]&0x03); // CP状态 0:12v未插枪;1:9v已插枪;2:9v占空比状态;3:6v占空比准备充电状态
pt_bms->t_bhm_data.u8_CR_Plc_CommStart= (pt_msg->u8_data[3]>>4)&0x03; // 通信启动 0:通信未启动;1:启动PLC通信
#define BMS_GUNLINK_KEEP_EN (1) //枪连接防抖使能
#if BMS_GUNLINK_KEEP_EN
#define BMS_GUNLINK_KEEP_TIME (3) //枪连接防抖次数
static U8_T u8_preGunLink[GUN_MAX_CNT] = {0},u8_keepTimes[GUN_MAX_CNT] = {0};
U8_T u8_gunLink = (pt_bms->t_bhm_data.u8_CR_Plc_CpStatus == 0)?0:1;
#endif /* CAN_PLC_FLAG */
if(u8_gunLink != u8_preGunLink[gunNo])
{
if(++u8_keepTimes[gunNo] >= BMS_GUNLINK_KEEP_TIME) //连续3次变位 则更新
{
u8_preGunLink[gunNo] = u8_gunLink;
}
}
else
{
u8_keepTimes[gunNo] = 0;
}
s_bms_data.u8_gun_linkState[gunNo] = u8_preGunLink[gunNo];
#else
if(pt_bms->t_bhm_data.u8_CR_Plc_CpStatus == 0)
s_bms_data.u8_gun_linkState[gunNo] = 0;
else
s_bms_data.u8_gun_linkState[gunNo] = 1;
#endif
snprintf((char*)pt_bms->t_bhm_data.u8_SECC_ver, sizeof(pt_bms->t_bhm_data.u8_SECC_ver),
"%02d%02d-%02d-%02d", bcd_to_dec(pt_msg->u8_data[5]),
bcd_to_dec(pt_msg->u8_data[4]),
bcd_to_dec(pt_msg->u8_data[6]),
bcd_to_dec(pt_msg->u8_data[7])); //SECC固件版本编译日期-年月日
u8_tim_reset(gunNo,cnt_global); //清空计时
pt_bms->e_bms_standard = BMS_PLC;
}
}
else /* 国标 */
#endif
{
if(pt_bms->e_state != GB_BMS_HANDSHAKE_TX_CHM) //只有在发送chm阶段接收
return;
if ((pt_msg->u16_len >= 2) /*&& (pt_msg->u8_pri == 6)*/) //收到BHM
{
//最大允许充电电压
f32_data = (((U16_T)(pt_msg->u8_data[1])<<8) |
pt_msg->u8_data[0]) / 10.0;
//BHM最高允许充电电压 低于200 认定为错误数据
if(f32_data < 200)
return;
pt_bms->t_bhm_data.f32_max_charge_volt = f32_data;
if(pt_bms->u8_bms_rx_flag[0] == 0)
{
pt_bms->u8_bms_rx_flag[0] = 1; //bms报文接收标志
BMS_LOG("BHM Vmax=%.2f\n", pt_bms->t_bhm_data.f32_max_charge_volt);
}
u8_tim_reset(gunNo,cnt_global); //清空计时
pt_bms->e_bms_standard = BMS_2015;
if(pt_bms->e_state == GB_BMS_HANDSHAKE_TX_CHM)
{
//bms实时数据-更新状态-握手启动成功
v_set_rt_state(gunNo, BMS_STATE_HANDSHAKE_START_OK); //bms状态
}
}
}
}
/****************************************************
*功能说明: BRM数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_brm_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
U8_T i;
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state != GB_BMS_HANDSHAKE_TX_CRM_00) //只在此阶段阶段接收
return;
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
/*
1.1 1.8 CR_Plc_VersionMinor GBT-1, PLC-1 1 0~1 1->1
版本 版本,国标:1PLC:1
2.1 2.8 无含义 填:00
3.1 8.8 EVCC MAC 地址
*/
if (pt_msg->u16_len >= 8)
{
pt_bms->u8_bms_rx_flag[1] = 1; //bms报文接收标志
pt_bms->t_brm_data.u8_batt_type = pt_msg->u8_data[3];
pt_bms->t_brm_data.f32_batt_rated_c10 = (((U16_T)(pt_msg->u8_data[5])<<8) |
pt_msg->u8_data[4]) / 10.0;
pt_bms->t_brm_data.f32_batt_rated_volt = (((U16_T)(pt_msg->u8_data[7])<<8) |
pt_msg->u8_data[6]) / 10.0;
//暂不做内容接收
u8_tim_reset(gunNo,cnt_global); //清空计时
if(s_bms_data.s_bms_rt_data[gunNo].e_state == GB_BMS_HANDSHAKE_TX_CRM_00)
s_bms_data.s_bms_rt_data[gunNo].e_state = GB_BMS_HANDSHAKE_TX_CRM_AA; //状态转4
}
}
else
#endif
{
if ((pt_msg->u16_len >= 41) /*&& (pt_msg->u8_pri == 7)*/)
{
pt_bms->u8_bms_rx_flag[1] = 1; //bms报文接收标志
pt_bms->t_brm_data.u32_bms_version = ((U32_T)(pt_msg->u8_data[2])<<16) |
((U32_T)(pt_msg->u8_data[1])<<8) |
pt_msg->u8_data[0];
pt_bms->t_brm_data.u8_batt_type = pt_msg->u8_data[3];
pt_bms->t_brm_data.f32_batt_rated_c10 = (((U16_T)(pt_msg->u8_data[5])<<8) |
pt_msg->u8_data[4]) / 10.0;
pt_bms->t_brm_data.f32_batt_rated_volt = (((U16_T)(pt_msg->u8_data[7])<<8) |
pt_msg->u8_data[6]) / 10.0;
memcpy((char *)(pt_bms->t_brm_data.u8_batt_vender), (char *)(&(pt_msg->u8_data[8])), 4);
pt_bms->t_brm_data.u32_batt_serial = ((U32_T)(pt_msg->u8_data[15])<<24) |
((U32_T)(pt_msg->u8_data[14])<<16) |
((U32_T)(pt_msg->u8_data[13])<<8) |
pt_msg->u8_data[12];
pt_bms->t_brm_data.u8_batt_make[0] = pt_msg->u8_data[16];
pt_bms->t_brm_data.u8_batt_make[1] = pt_msg->u8_data[17];
pt_bms->t_brm_data.u8_batt_make[2] = pt_msg->u8_data[18];
pt_bms->t_brm_data.u32_batt_charge_times = ((U32_T)(pt_msg->u8_data[21])<<16) |
((U32_T)(pt_msg->u8_data[20])<<8) |
pt_msg->u8_data[19];
pt_bms->t_brm_data.u8_batt_belong = pt_msg->u8_data[22];
pt_bms->t_brm_data.u8_Bms_edition = pt_msg->u8_data[23]; //增加充电机通信协议版本解读(兼容2015+团标)
memcpy((char *)(pt_bms->t_brm_data.u8_car_vin), (char *)(&(pt_msg->u8_data[24])), 17);
// 车架号校验 每一位必须为字母或数字 否则置为全0
for (i = 0; i < 17; i ++)
{
if(((pt_bms->t_brm_data.u8_car_vin[i] >= '0') && (pt_bms->t_brm_data.u8_car_vin[i] <= '9'))
|| ((pt_bms->t_brm_data.u8_car_vin[i] >= 'A') && (pt_bms->t_brm_data.u8_car_vin[i] <= 'Z'))
|| ((pt_bms->t_brm_data.u8_car_vin[i] >= 'a') && (pt_bms->t_brm_data.u8_car_vin[i] <= 'z')))
{
;//数据有效
}
else
{
memset(&pt_bms->t_brm_data.u8_car_vin[0], 0x30, 17);//如果收到的VIN无效,赋值为0
break;
}
}
memcpy((char *)(pt_bms->t_brm_data.u8_bms_soft_version),(char *)(&(pt_msg->u8_data[41])),8);
if (pt_bms->e_bms_standard == BMS_2011)
{
if (pt_bms->t_brm_data.u32_bms_version == 0x00000101)
pt_bms->e_bms_standard = BMS_2015;
else
pt_bms->e_bms_standard = BMS_2011;
}
u8_tim_reset(gunNo,cnt_global); //清空计时
if(s_bms_data.s_bms_rt_data[gunNo].e_state == GB_BMS_HANDSHAKE_TX_CRM_00)
s_bms_data.s_bms_rt_data[gunNo].e_state = GB_BMS_HANDSHAKE_TX_CRM_AA; //状态转4
// BMS_LOG("BMS版本号:%d\n", pt_bms->u32_bms_version);
// BMS_LOG("电池类型:%x\n", pt_bms->u8_batt_type);
// BMS_LOG("整车动力蓄电池系统额定容量:%d\n", (U32_T)(pt_bms->f32_batt_rated_c10*10));
// BMS_LOG("整车动力蓄电池系统额定总电压:%f\n", (U32_T)(pt_bms->f32_batt_rated_volt*10));
BMS_LOG("vin_len=%d, VIN=%s\n",strlen((const char*)(pt_bms->t_brm_data.u8_car_vin)), pt_bms->t_brm_data.u8_car_vin);
}
}
}
/****************************************************
*功能说明: BCP数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bcp_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state != GB_BMS_HANDSHAKE_TX_CRM_AA) //只在此阶段阶段接收
return;
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
/*
1.1 2.8 CR_Plc_MaxVoltSingleBattery 0 (no value with CCS) 0.01 0 0~24 V
单体电池最大电压 默认0x00
3.1 4.7 CR_Plc_EvmaxCurrent EV Maximum permissible charging current 0.1 -400 A
最高容许充电电流 车辆最高容许充电电流
4.8 4.8 CR_Plc_EvmaxCurrent EV Maximum permissible charging current 1 0 0~1 A
最高容许充电电流大于400A标志位 "0:小于400A电流计算:400A - 3.1~4.7的电流值;
1:大于400A电流计算:3.1~4.7的电流值 + 400A"
5.1 6.8 CR_Plc_EvNormialEnergy 0 (no value with CCS) 0.1 0 0~1000 KWh
动力蓄电池标称总能量 默认0x00
7.1 8.8 CR_Plc_EvmaxVolt Total max permissible charging voltage 0.1 0 V
最高容许充电总电压 车辆最高容许充电总电压(绝缘检测电压)
9.1 9.8 CR_Plc_EvAvailableTemp 0 (no value with CCS) Maximum permissible temperature 1 -50 负50至200 ℃
总高容许温度 默认0x00
10.1 11.8 CR_Plc_EvRessSOC Status Of Charge 0.1 0 0~100 %
整车动力蓄电池荷电状态电量 默认0x00
12.1 13.8 CR_Plc_EvCurrentVolt 0 (no value with CCS) 0.1 0 V
整车动力蓄电池当前电池电压 默认0x00
14.1 14.4 CR_Plc_EvTransferType Supported Energy Type (default 3, see appendix) 1 0
电动车传输协议能量类型 默认0x03,支持的能量传输类型
*/
if ((pt_msg->u16_len >= 13) /*&& (pt_msg->u8_pri == 7)*/)
{
pt_bms->u8_bms_rx_flag[2] = 1; //bms报文接收标志
pt_bms->t_bcp_data.f32_cell_charge_max_volt = (((U16_T)(pt_msg->u8_data[1])<<8) |
pt_msg->u8_data[0]) / 100.0;
if((pt_msg->u8_data[3]&0x80) == 0x80) //最高容许充电电流大于400A标志位
{
pt_bms->t_bcp_data.f32_batt_charge_max_curr = -(((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) & 0x7FFF) / 10.0 + 400);
}else
pt_bms->t_bcp_data.f32_batt_charge_max_curr = -((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) / 10.0 - 400);
pt_bms->t_bcp_data.f32_batt_rated_enery = (((U16_T)(pt_msg->u8_data[5])<<8) |
pt_msg->u8_data[4]) / 10.0;
pt_bms->t_bcp_data.f32_batt_charge_max_volt = (((U16_T)(pt_msg->u8_data[7])<<8) |
pt_msg->u8_data[6]) / 10.0;
pt_bms->t_bcp_data.s16_batt_allow_max_temp = (S16_T)(pt_msg->u8_data[8]) - 50;
pt_bms->t_bcp_data.f32_batt_start_soc = (((U16_T)(pt_msg->u8_data[10])<<8) |
pt_msg->u8_data[9]) / 10.0;
pt_bms->t_bcp_data.f32_batt_volt = (((U16_T)(pt_msg->u8_data[12])<<8) |
pt_msg->u8_data[11]) / 10.0;
pt_bms->t_bcp_data.u8_CR_Plc_EvTransferType = pt_msg->u8_data[13]; //电动车传输协议能量类型 默认0x03,支持的能量传输类型
// BMS_LOG("单体动力蓄电池最高允许充电电压=%d\n", (U32_T)(pt_bms->f32_cell_charge_max_volt*100));
// BMS_LOG("最高允许充电电流=%d\n", (U32_T)(pt_bms->f32_batt_charge_max_curr*10));
// BMS_LOG("动力蓄电池标称总能量=%d\n", (U32_T)(pt_bms->f32_batt_rated_enery*10));
// BMS_LOG("最高允许充电电压=%d\n", (U32_T)(pt_bms->f32_batt_charge_max_volt_judge*10));
// BMS_LOG("最高允许温度=%d\n", (U32_T)(pt_bms->s16_batt_allow_max_temp*10));
// BMS_LOG("整车动力蓄电池荷电状态=%d\n", (U32_T)(pt_bms->f32_batt_start_soc*10));
BMS_LOG("BMS battV=%.2f\n", pt_bms->t_bcp_data.f32_batt_volt);
v_bms_err_data(gunNo );//电流数据不在有效数据范围内停止充电
if(pt_bms->e_state == GB_BMS_HANDSHAKE_TX_CRM_AA)
pt_bms->e_state = GB_BMS_CFG_TX_CTS_CML; //跳转5
u8_tim_reset(gunNo,cnt_global); //清空计时
}
}
else
#endif
{
if ((pt_msg->u16_len >= 13) /*&& (pt_msg->u8_pri == 7)*/)
{
pt_bms->u8_bms_rx_flag[2] = 1; //bms报文接收标志
pt_bms->t_bcp_data.f32_cell_charge_max_volt = (((U16_T)(pt_msg->u8_data[1])<<8) |
pt_msg->u8_data[0]) / 100.0;
if(pt_bms->t_brm_data.u8_Bms_edition == 0x5A) //接收到2015+协议标识 5A电流偏移量改为3000A
{
pt_bms->t_bcp_data.f32_batt_charge_max_curr = -((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) / 10.0 - 3000);
}
else
pt_bms->t_bcp_data.f32_batt_charge_max_curr = -((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) / 10.0 - 400);
pt_bms->t_bcp_data.f32_batt_rated_enery = (((U16_T)(pt_msg->u8_data[5])<<8) |
pt_msg->u8_data[4]) / 10.0;
pt_bms->t_bcp_data.f32_batt_charge_max_volt = (((U16_T)(pt_msg->u8_data[7])<<8) |
pt_msg->u8_data[6]) / 10.0;
pt_bms->t_bcp_data.s16_batt_allow_max_temp = (S16_T)(pt_msg->u8_data[8]) - 50;
pt_bms->t_bcp_data.f32_batt_start_soc = (((U16_T)(pt_msg->u8_data[10])<<8) |
pt_msg->u8_data[9]) / 10.0;
pt_bms->t_bcp_data.f32_batt_volt = (((U16_T)(pt_msg->u8_data[12])<<8) |
pt_msg->u8_data[11]) / 10.0;
// BMS_LOG("单体动力蓄电池最高允许充电电压=%d\n", (U32_T)(pt_bms->f32_cell_charge_max_volt*100));
// BMS_LOG("最高允许充电电流=%d\n", (U32_T)(pt_bms->f32_batt_charge_max_curr*10));
// BMS_LOG("动力蓄电池标称总能量=%d\n", (U32_T)(pt_bms->f32_batt_rated_enery*10));
// BMS_LOG("最高允许充电电压=%d\n", (U32_T)(pt_bms->f32_batt_charge_max_volt_judge*10));
// BMS_LOG("最高允许温度=%d\n", (U32_T)(pt_bms->s16_batt_allow_max_temp*10));
// BMS_LOG("整车动力蓄电池荷电状态=%d\n", (U32_T)(pt_bms->f32_batt_start_soc*10));
BMS_LOG("BMS battV=%.2f\n", pt_bms->t_bcp_data.f32_batt_volt);
v_bms_err_data(gunNo );//电流数据不在有效数据范围内停止充电
if(pt_bms->e_state == GB_BMS_HANDSHAKE_TX_CRM_AA)
pt_bms->e_state = GB_BMS_CFG_TX_CTS_CML; //跳转5
u8_tim_reset(gunNo,cnt_global); //清空计时
}
}
}
/****************************************************
*功能说明: BRO数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bro_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state < GB_BMS_CFG_TX_CTS_CML &&
pt_bms->e_state > GB_BMS_CFG_TX_CRO_AA) //只在此阶段阶段接收
return;
if ((pt_msg->u16_len >= 1) /*&& (pt_msg->u8_pri == 4)*/)
{
pt_bms->u8_bms_rx_flag[3] = 1; //bms报文接收标志
if ((pt_msg->u8_data[0] == 0x00) ||
(pt_msg->u8_data[0] == 0xFF)) //bms未完成准备
{
if(pt_bms->e_state == GB_BMS_CFG_TX_CTS_CML)
{
BMS_LOG("BMS BRO 0x00 not ready\n");
pt_bms->e_state = GB_BMS_CFG_RX_BRO_AA; //跳转6
u8_tim_reset(gunNo,cnt_bro_aa); //broAA 接收清零
}
else if(pt_bms->e_state == GB_BMS_CFG_TX_CRO_00 ||
pt_bms->e_state == GB_BMS_CFG_TX_CRO_AA)//bms出现问题,不是准备就绪状态了,充电机1s内停止通信,断开K3K4,电子锁解锁,按故障处理方式b处理
{
pt_bms->e_state = GB_BMS_STOP;
v_set_rt_state(gunNo, BMS_STATE_ERR); //bms状态转数据异常
BMS_LOG("BMS BRO 0xAA data err st=%d\n",pt_bms->e_state);
}
}
else if (pt_msg->u8_data[0] == 0xAA) //充电机完成准备
{
if(pt_bms->e_state == GB_BMS_CFG_TX_CTS_CML ||
pt_bms->e_state == GB_BMS_CFG_RX_BRO_AA)
{
BMS_LOG("BMS BRO 0xAA ready\n");
pt_bms->e_state = GB_BMS_CFG_TX_CRO_00; //跳转7
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
v_set_rt_state(gunNo, BMS_STATE_HANDSHAKE_START_OK); //欧标:BMS状态-开始预充电
else
#endif
v_set_rt_state(gunNo, BMS_STATE_PRECHARGE); //国标:BMS状态-开始预充电
}
u8_tim_reset(gunNo,cnt_bro_aa); //broAA 接收清零
}
u8_tim_reset(gunNo,cnt_global); //清空计时
}
}
/****************************************************
*功能说明: BCS数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bcs_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state != GB_BMS_CFG_TX_CRO_AA &&
pt_bms->e_state != GB_BMS_CHARGE_STAGE) //只在此阶段阶段接收
return;
pt_bms->u8_bms_rx_flag[4] = 1; //bms报文接收标志
pt_bms->t_bcs_data.f32_charge_volt = (((U16_T)(pt_msg->u8_data[1])<<8) |
pt_msg->u8_data[0]) / 10.0;
if(pt_bms->t_brm_data.u8_Bms_edition == 0x5A)
{
pt_bms->t_bcs_data.f32_charge_curr = -((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) / 10.0 - 3000);
}else
pt_bms->t_bcs_data.f32_charge_curr = -((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) / 10.0 - 400);
pt_bms->t_bcs_data.f32_cell_max_volt = ((((U16_T)(pt_msg->u8_data[5])<<8) |
pt_msg->u8_data[4]) & 0x0FFF) / 100.0;
pt_bms->t_bcs_data.u8_cell_max_volt_group_num = (pt_msg->u8_data[5]>>4);
pt_bms->t_bcs_data.u8_batt_soc = pt_msg->u8_data[6];
pt_bms->t_bcs_data.u16_remain_charge_time = ((U16_T)(pt_msg->u8_data[8])<<8) |
pt_msg->u8_data[7];
u8_tim_reset(gunNo,cnt_global); //清空计时
//BMS_LOG("bms--启动中--收到BCS\n");
// BMS_LOG("111充电电压测量值=%d\n", (U32_T)(pt_bms->f32_charge_volt*10) );
// BMS_LOG("充电电流测量值=%d\n", (U32_T)(pt_bms->f32_charge_curr*10));
// BMS_LOG("最高单体动力蓄电池电压 = %d , 组号=%d\n", (U32_T)(pt_bms->f32_cell_max_volt*100), pt_bms->u8_cell_max_volt_group_num);
// BMS_LOG("当前荷电状态SOC% =%d\n", pt_bms->u8_batt_soc);
//BMS_LOG("估算剩余充电时间=%d\n", pt_bms->t_bcs_data.u16_remain_charge_time);
}
/****************************************************
*功能说明: BCL数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bcl_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state != GB_BMS_CFG_TX_CRO_AA &&
pt_bms->e_state != GB_BMS_CHARGE_STAGE) //只在此阶段阶段接收
return;
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
/*
1.1 2.8 CR_Plc_EvTargetVolt Charging Target Voltage 0.1 0 0~6553.5 V
电压需求 充电目标电压
3.1 4.7 CR_Plc_EvTargetCurrent Charging Target Current 0.1 -400 A
电流需求 充电目标电流
4.8 4.8 CR_Plc_EvTargetCurrent Charging Target Current 1 0 0~1 A
电流需求电流大于400A标志位 "0:小于400A电流需求计算:400A - 3.1~4.7的电流值;
1:大于400A电流需求计算:3.1~4.7的电流值 + 400A"
5.1 5.8 CR_Plc_ChargingMode 0x2(no value with CCS, however almost EV adopt CC), 1: CV, 2: CC 1 1~2
充电模式 充电模式(0x01:恒压充电;0x02恒流充电)
6.1 7.8 CR_Plc_EvMaxVoltLimit EV Maximum Voltage Limit value 0.1 0 0~6553.5 V
最高允许充电电压 最高允许充电电压
8.1 8.8 CR_Plc_PreCharge_Stauts 1: PreCharge Status : 0: No PreCharge Status 1 0 0~2
预充电状态 1:预充电状态: 0:无预充电状态
*/
if ((pt_msg->u16_len >= 5) /*&& (pt_msg->u8_pri == 6)*/)
{
pt_bms->u8_bms_rx_flag[5] = 1; //bms报文接收标志
pt_bms->t_bcl_data.f32_batt_need_volt = (((U16_T)(pt_msg->u8_data[1])<<8) |
pt_msg->u8_data[0]) / 10.0;
if((pt_msg->u8_data[3] & 0x80) == 0x80)
{
pt_bms->t_bcl_data.f32_batt_need_curr = (((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) & 0x7FFF) / 10.0 + 400);
}
else
pt_bms->t_bcl_data.f32_batt_need_curr = -((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) / 10.0 - 400);
pt_bms->t_bcl_data.u8_charge_mode = pt_msg->u8_data[4];
pt_bms->t_bcl_data.f32_batt_charge_max_volt = (((U16_T)(pt_msg->u8_data[6])<<8) |
pt_msg->u8_data[5]) / 10.0;
pt_bms->t_bcl_data.u8_preCharge = pt_msg->u8_data[7];
v_bms_err_data(gunNo );//电流数据不在有效数据范围内停止充电
u8_tim_reset(gunNo,cnt_bcl); //清空计时
if(pt_bms->e_real_state < BMS_STATE_PRECHARGE)
{
v_set_rt_state(gunNo, BMS_STATE_PRECHARGE); //BMS状态-开始预充电
}
//BMS_LOG("bms--启动中--收到BCL\n");
//BMS_LOG("111电压需求=%d\n", (U32_T)(pt_bms->f32_batt_need_volt*10) );
//BMS_LOG("电流需求=%d\n", (U32_T)(pt_bms->f32_batt_need_curr*10));
//BMS_LOG("充电模式 = %d\n", pt_bms->u8_charge_mode);
}
}
else
#endif
{
if ((pt_msg->u16_len >= 5) /*&& (pt_msg->u8_pri == 6)*/)
{
pt_bms->u8_bms_rx_flag[5] = 1; //bms报文接收标志
pt_bms->t_bcl_data.f32_batt_need_volt = (((U16_T)(pt_msg->u8_data[1])<<8) |
pt_msg->u8_data[0]) / 10.0;
if(pt_bms->t_brm_data.u8_Bms_edition == 0x5A) //该表示为5A
{
pt_bms->t_bcl_data.f32_batt_need_curr = -((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) / 10.0 - 3000);
}else
pt_bms->t_bcl_data.f32_batt_need_curr = -((((U16_T)(pt_msg->u8_data[3])<<8) |
pt_msg->u8_data[2]) / 10.0 - 400);
pt_bms->t_bcl_data.u8_charge_mode = pt_msg->u8_data[4];
v_bms_err_data(gunNo );//电流数据不在有效数据范围内停止充电
u8_tim_reset(gunNo,cnt_bcl); //清空计时
//BMS_LOG("bms--启动中--收到BCL\n");
//BMS_LOG("111电压需求=%d\n", (U32_T)(pt_bms->f32_batt_need_volt*10) );
//BMS_LOG("电流需求=%d\n", (U32_T)(pt_bms->f32_batt_need_curr*10));
//BMS_LOG("充电模式 = %d\n", pt_bms->u8_charge_mode);
}
}
}
/****************************************************
*功能说明: BSM数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bsm_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
U16_T u16_batt_new_state,u16_batt_old_state;
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state != GB_BMS_CHARGE_STAGE) //只在此阶段阶段接收
return;
if ((pt_msg->u16_len >= 7) /*&& (pt_msg->u8_pri == 6)*/)
{
pt_bms->u8_bms_rx_flag[6] = 1; //bms报文接收标志
pt_bms->t_bsm_data.u8_cell_max_volt_id = pt_msg->u8_data[0];
pt_bms->t_bsm_data.s16_batt_max_temp = (S16_T)(pt_msg->u8_data[1]) - 50;
pt_bms->t_bsm_data.u8_max_temp_id = pt_msg->u8_data[2];
pt_bms->t_bsm_data.s16_batt_min_temp = (S16_T)(pt_msg->u8_data[3]) - 50;
pt_bms->t_bsm_data.u8_min_temp_id = pt_msg->u8_data[4];
u16_batt_new_state = 0; //电池状态
if ((pt_msg->u8_data[5]&0x03) == 0x01) //单体动力蓄电池电压过高
{
u16_batt_new_state |= 0x0001;
v_set_bms_stop_info(gunNo , E_BMS_STOP_15012);
}
else if ((pt_msg->u8_data[5]&0x03) == 0x02) //单体动力蓄电池电压过低
{
u16_batt_new_state |= 0x0002;
v_set_bms_stop_info(gunNo , E_BMS_STOP_15013);
}
else
{
u16_batt_new_state &= ~0x0003;
}
if ((pt_msg->u8_data[5]&0x0C) == 0x04) //整车动力蓄电池荷电状态SOC过高
{
u16_batt_new_state |= 0x0004;
v_set_bms_stop_info(gunNo , E_BMS_STOP_15014);
}
else if ((pt_msg->u8_data[5]&0x0C) == 0x08) //整车动力蓄电池荷电状态SOC过低
{
u16_batt_new_state |= 0x0008;
v_set_bms_stop_info(gunNo , E_BMS_STOP_15015);
}
else
{
u16_batt_new_state &= ~0x000C;
}
if ((pt_msg->u8_data[5]&0x30) == 0x10) //动力蓄电池充电过流
{
u16_batt_new_state |= 0x0010;
v_set_bms_stop_info(gunNo , E_BMS_STOP_15016);
}
else
{
u16_batt_new_state &= ~0x0010;
}
if ((pt_msg->u8_data[5]&0xC0) == 0x40) //动力蓄电池温度过高
{
u16_batt_new_state |= 0x0020;
v_set_bms_stop_info(gunNo , E_BMS_STOP_15017);
}
else
{
u16_batt_new_state &= ~0x0020;
}
if ((pt_msg->u8_data[6]&0x03) == 0x01) //动力蓄电池绝缘状态不正常
{
u16_batt_new_state |= 0x0040;
v_set_bms_stop_info(gunNo , E_BMS_STOP_15018);
}
else
{
u16_batt_new_state &= ~0x0040;
}
if ((pt_msg->u8_data[6]&0x0C) == 0x04) //动力蓄电池组输出连接器连接状态不正常
{
u16_batt_new_state |= 0x0080;
v_set_bms_stop_info(gunNo , E_BMS_STOP_15019);
}
else
{
u16_batt_new_state &= ~0x0080;
}
if ((pt_msg->u8_data[6]&0x30) == 0x10) //充电允许,00禁止,01允许
u16_batt_new_state |= 0x0100; //允许则置1
else
u16_batt_new_state &= ~0x0100; //禁止
u16_batt_old_state = pt_bms->t_bsm_data.u16_batt_state;
pt_bms->t_bsm_data.u16_batt_state = u16_batt_new_state;
if((u16_batt_new_state & 0x00FF) != 0) //bsm异常
{
pt_bms->e_state = GB_BMS_CHARGE_TX_CST; //; //跳转 GB_BMS_STOP
u8_tim_reset(gunNo,cnt_bcl);
u8_tim_reset(gunNo,cnt_bro_aa); //broAA 接收清零
BMS_LOG("BMS BSM abn stop\n");
}
//BMS_LOG("BSM,允许充电状态,原=%x,新=%x\n", u16_batt_old_state, u16_batt_new_state);
if (((u16_batt_old_state & 0xFF00) == 0x0100) && ((u16_batt_new_state & 0xFF00) == 0)) //原来允许,现在禁止充电
{
v_set_rt_state(gunNo, BMS_STATE_BSM_FORBID); //bms:充电禁止状态
//pt_bms->ulong_BSM_forbit_timer = get_current_seconds();
BMS_LOG("BMS BSM forbid chg\n");
}
else if(((u16_batt_old_state & 0xFF00) == 0) && ((u16_batt_new_state & 0xFF00) == 0x0100)) //((u16_batt_new_state & 0xFF00) == 1) //现在允许充电
{
v_set_rt_state(gunNo, BMS_STATE_CHARGING); //bms状态转10,充电中
//pt_bms->ulong_BSM_forbit_timer = 0;
BMS_LOG("BMS BSM allow chg\n");
}
}
}
/****************************************************
*函数名称: void v_bms_bmv_send(U8_T gunNo,CAN_DATA_T *pt_msg)
*功能说明: BMV数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bmv_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
U16_T i;
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state != GB_BMS_CHARGE_STAGE) //只在此阶段阶段接收
return;
if ((pt_msg->u16_len <= 512) /*&& (pt_msg->u8_pri == 7)*/)
{
pt_bms->u8_bms_rx_flag[7] = 1; //bms报文接收标志
for (i=0; i<pt_msg->u16_len/2; i++)
{
pt_bms->t_bmv_data.u_data[i].s_bit.bit_cell_volt = ((((U16_T)(pt_msg->u8_data[2*i+1])<<8) |
pt_msg->u8_data[2*i]) & 0x0FFF) / 100.0;
pt_bms->t_bmv_data.u_data[i].s_bit.bit_cell_group_numt = (pt_msg->u8_data[2*i+1]>>4);
}
}
}
/****************************************************
*函数名称: void v_bms_bmt_send(U8_T gunNo,CAN_DATA_T *pt_msg)
*功能说明: BMT数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bmt_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
U8_T i;
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state != GB_BMS_CHARGE_STAGE) //只在此阶段阶段接收
return;
if ((pt_msg->u16_len <= 128) /*&& (pt_msg->u8_pri == 7)*/)
{
pt_bms->u8_bms_rx_flag[8] = 1; //bms报文接收标志
for (i=0; i<pt_msg->u16_len; i++)
{
pt_bms->t_bmt_data.u8_batt_temp[i] = (pt_msg->u8_data[i]);
}
}
}
/****************************************************
*函数名称: void v_bms_bst_send(U8_T gunNo,CAN_DATA_T *pt_msg)
*功能说明: BST数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bst_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state == GB_BMS_STOP) //空闲是不接收
return;
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
/*
1.1 1.2 CF_Plc_ReachSoC 0: fail, 1: reach , 2:unknown 1 0 0~2 不支持 不判断
达到所需的SOC目标值 0:未到达,1:到达,2:未知
1.3 1.4 CF_Plc_ReachTotalVolt 0: fail, 1: reach , 2:unknown 1 0 0~2 不支持 不判断
达到总电压设定值 0:未到达,1:到达,2:未知
1.5 1.6 CF_Plc_ReachSingleVolt 0: fail, 1: reach , 2:unknown 1 0 0~2 不支持 不判断
到达单体电压设定值 0:未到达,1:到达,2:未知
1.7 1.8 CF_Plc_ChargerSuspend 0: normal, 1: suspension, 2:unknown 1 0 0~2 判断
充电机主动中止 0:正常,1:暂停,2:未知
2.1 2.2 CF_Plc_InstationFault 0: normal, 1: fault, 2:unknown 1 0 0~2 不支持 不判断
绝缘故障 0:正常,1:故障,2:未知
2.3 2.4 CF_Plc_ConnectorHighTemp 0: normal, 1: fault, 2:unknown 1 0 0~2 不支持 不判断
输出连接器过温故障 0:正常,1:故障,2:未知
2.5 2.6 CF_Plc_BmsOverTemp 0: normal, 1: fault, 2:unknown 1 0 0~2 不支持 不判断
BMS元件、输出连接线过温 0:正常,1:故障,2:未知
2.7 2.8 CF_Plc_ConnectorFault 0: normal, 1: fault, 2:unknown 1 0 0~2 不支持 不判断
充电连接器故障 0:正常,1:故障,2:未知
3.1 3.2 CF_Plc_BatOverTemp 0: normal, 1: overtemp, 2:unknown 1 0 0~2 不支持 不判断
电池组温度过高故障 0:正常,1:过热,2:未知
3.3 3.4 CF_Plc_HighVoltRelay 0: normal, 1: fault, 2:unknown 1 0 0~2 不支持 不判断
高压继电器故障 0:正常,1:故障,2:未知
3.5 3.6 CF_Plc_ErrCheckPoint2 0: normal, 1: fault, 2:unknown 1 0 0~2 不支持 不判断
检测点2电压检测故障 0:正常,1:故障,2:未知
3.7 3.8 CF_Plc_OtherFault 0: normal, 1: fault, 2:unknown 1 0 0~2 不支持 不判断
其他故障 0:正常,1:故障,2:未知
4.1 4.2 CF_Plc_CurrOver 0: curren, 1: current exceed, 2:unknown 1 0 0~2 不支持 不判断
电流过大 0:当前,1:电流超出,2:未知
4.3 4.4 CF_Plc_AbnormalVolt 0: normal, 1: abnormal, 2:unknown 1 0 0~2 不支持 不判断
电压异常 0:正常,1:异常,2:未知
4.7 4.7 CF_Plc_FullChgComplete 0: not Full 1: full charging complete 1 0 0~1 添加项 判断
车充电是否完成 0:未满1:完全充电完成
4.8 4.8 CF_Plc_ChgFinished_ 0: charging, 1: charging stop request 1 0 0~1 添加项 判断
桩充电状态 0:充电,1:充电停止请求
5.1 5.8 Message_Sequence 1 0x01~0x30 添加项 不判断
通信流程消息序列 通信流程消息序列
6.1 6.8 CR_Plc_ErrorCodeII 0x01~0xA6 添加项 不判断
错误代码II 错误代码,见附录
7.1 7.8 CR_Plc_ErrorCode ErrorCode 0x01~0xE5 添加项 不判断
错误代码 错误代码,见附录
8.1 8.3 ErrorCode by CP or PP state 0x01~0x05 添加项 不判断
CP或PP状态的错误代码 错误代码,见附录
8.4 8.7 CR_PLc_EvErrCode 0x01~0x11 添加项 不判断
EV车辆发送的错误代码 错误代码,见附录
*/
if ((pt_msg->u16_len >= 4) /*&& (pt_msg->u8_pri == 4)*/)
{
pt_bms->u8_bms_rx_flag[9] = 1; //bms报文接收标志
if(pt_bms->e_state != GB_BMS_CHARGE_TX_CST && //
pt_bms->e_state != GB_BMS_FINISH_RX_BSD)
{
pt_bms->e_state = GB_BMS_CHARGE_TX_CST;
BMS_LOG("BMS BST rx stop\n");
u8_tim_reset(gunNo,cnt_bcl);
}
u8_tim_reset(gunNo,cnt_global);
//保存充电停止原因,用于发送充电机停止充电报文时回复
memcpy(pt_bms->t_bst_data.u8_bst_data,pt_msg->u8_data,8);
pt_bms->t_cst_data.u8_cst_data[0] = 0x40; //车辆主动中止
pt_bms->t_cst_data.u8_cst_data[1] = 0;
pt_bms->t_cst_data.u8_cst_data[2] = 0xF0;
pt_bms->t_cst_data.u8_cst_data[3] = 0xF0;
}
}
else
#endif
{
if ((pt_msg->u16_len >= 4) /*&& (pt_msg->u8_pri == 4)*/)
{
pt_bms->u8_bms_rx_flag[9] = 1; //bms报文接收标志
if(pt_bms->e_state != GB_BMS_CHARGE_TX_CST && //
pt_bms->e_state != GB_BMS_FINISH_RX_BSD)
{
pt_bms->e_state = GB_BMS_CHARGE_TX_CST;
u8_tim_reset(gunNo,cnt_bcl);
}
u8_tim_reset(gunNo,cnt_global);
//保存充电停止原因,用于发送充电机停止充电报文时回复
memcpy(pt_bms->t_bst_data.u8_bst_data,pt_msg->u8_data,4);
if (pt_bms->e_bms_standard == BMS_2015)
pt_bms->t_cst_data.u8_cst_data[0] = 0x40;
else
pt_bms->t_cst_data.u8_cst_data[0] = 0xC0;
pt_bms->t_cst_data.u8_cst_data[1] = 0;
pt_bms->t_cst_data.u8_cst_data[2] = 0xF0;
pt_bms->t_cst_data.u8_cst_data[3] = 0xF0;
#if 1
//解释BMS停止充电原因
if ((pt_msg->u8_data[0]&0x03) == 0x01) //达到所需SOC目标值
v_set_bms_stop_info(gunNo , E_BMS_STOP_1000);
if ((pt_msg->u8_data[0]&0x0C) == 0x04) //达到总电压设定值
v_set_bms_stop_info(gunNo , E_BMS_STOP_1000);
if ((pt_msg->u8_data[0]&0x30) == 0x10) //达到单体电压设定值
v_set_bms_stop_info(gunNo , E_BMS_STOP_1000);
if ((pt_msg->u8_data[1]&0x03) == 0x01) //绝缘故障
v_set_bms_stop_info(gunNo , E_BMS_STOP_15022);
if ((pt_msg->u8_data[1]&0x0C) == 0x04) //输出连接器过温故障
v_set_bms_stop_info(gunNo , E_BMS_STOP_15023);
if ((pt_msg->u8_data[1]&0x30) == 0x10) //BMS元件、输出连接器过温
v_set_bms_stop_info(gunNo , E_BMS_STOP_15024);
if ((pt_msg->u8_data[1]&0xC0) == 0x40) //充电连接器故障
v_set_bms_stop_info(gunNo , E_BMS_STOP_15025);
if ((pt_msg->u8_data[2]&0x03) == 0x01) //电池组温度过高故障
v_set_bms_stop_info(gunNo , E_BMS_STOP_15026);
if (pt_bms->e_bms_standard == BMS_2015)
{
if ((pt_msg->u8_data[2]&0x0C) == 0x04) //高压继电器故障
v_set_bms_stop_info(gunNo , E_BMS_STOP_15029);
if ((pt_msg->u8_data[2]&0x30) == 0x10) //检测点2电压检测故障
v_set_bms_stop_info(gunNo , E_BMS_STOP_15028);
if ((pt_msg->u8_data[2]&0xC0) == 0x40) //其它故障
v_set_bms_stop_info(gunNo , E_BMS_STOP_15027);
}
else
{
if ((pt_msg->u8_data[2]&0x0C) == 0x04) //其它故障
v_set_bms_stop_info(gunNo , E_BMS_STOP_15021);
}
if ((pt_msg->u8_data[3]&0x03) == 0x01) //电流超过需求值
v_set_bms_stop_info(gunNo , E_BMS_STOP_15030);
if ((pt_msg->u8_data[3]&0x0C) == 0x04) //电压异常
v_set_bms_stop_info(gunNo , E_BMS_STOP_15031);
if(s_bms_data.s_bms_rt_data[gunNo].e_stop_info == E_BMS_STOP_NULL)
v_set_bms_stop_info(gunNo , E_BMS_STOP_1000);
//BMS_LOG("BMS - bst停止充电,停止原因 = %lld\n", pt_bms->t_bst_data.u8_bst_data);//g_t_share_data.t_rt_data.t_ctrl.u_stop_chag_reason[gunNo].u64_stopChag_reason);
#endif
}
}
}
/****************************************************
*函数名称: void v_bms_bsd_send(U8_T gunNo,CAN_DATA_T *pt_msg)
*功能说明: BSD数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bsd_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if(pt_bms->e_state < GB_BMS_CHARGE_TX_CST) //只在此阶段阶段接收
return;
if (pt_msg->u32_pgn == GB_BMS_PGN_BSD)
{
if ((pt_msg->u16_len >= 7) /*&& (pt_msg->u8_pri == 6)*/)
{
pt_bms->u8_bms_rx_flag[10] = 1; //bms报文接收标志
pt_bms->t_bsd_data.u8_batt_end_soc = pt_msg->u8_data[0];
pt_bms->t_bsd_data.f32_cell_batt_min_volt = (((U16_T)(pt_msg->u8_data[2])<<8) |
pt_msg->u8_data[1]) / 100.0;
pt_bms->t_bsd_data.f32_cell_batt_max_volt = (((U16_T)(pt_msg->u8_data[4])<<8) |
pt_msg->u8_data[3]) / 100.0;
pt_bms->t_bsd_data.u8_batt_min_temp = (U8_T)(pt_msg->u8_data[5]) - 50;
pt_bms->t_bsd_data.u8_batt_max_temp = (U8_T)(pt_msg->u8_data[6]) - 50;
pt_bms->t_bsd_data.u8_batt_end_soc = pt_msg->u8_data[0];
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
pt_bms->t_bsd_data.u8_CF_Plc_WeldDetectionReq = pt_msg->u8_data[0]&0x01; //欧标:粘连检测要求
#endif
u8_tim_reset(gunNo,cnt_bcl);
if(pt_bms->e_state != GB_BMS_FINISH_RX_BSD)
{
BMS_LOG("BSD rx, stop SOC=%d\n", pt_bms->t_bsd_data.u8_batt_end_soc);
v_set_bms_stop_info(gunNo,E_BMS_STOP_1011); //bms停止
pt_bms->e_state = GB_BMS_FINISH_RX_BSD; //; //跳转 GB_BMS_STOP
}
}
}
}
/****************************************************
*函数名称: void v_bms_bem_send(U8_T gunNo,CAN_DATA_T *pt_msg)
*功能说明: BEM数据接收解析函数
*参数说明:
* 输入参数: U8_T gunNo 枪号,CAN_DATA_T *pt_msg 接收can数据
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_bem_rx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
if ((pt_msg->u16_len >= 4) /*&& (pt_msg->u8_pri == 2)*/)
{
pt_bms->u8_bms_rx_flag[11] = 1; //bms报文接收标志
//只判定在【握手辨识,充电中】过程中的BEM,握手启动及充电结束阶段不管
if((s_bms_data.s_bms_rt_data[gunNo].e_state >= GB_BMS_HANDSHAKE_TX_CRM_00) &&
(s_bms_data.s_bms_rt_data[gunNo].e_state <= GB_BMS_CHARGE_STAGE))
{
BMS_LOG("BEM rx, comm TO -> reconn x3\n");
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
memcpy(pt_bms->t_bem_data.u8_bem_data,pt_msg->u8_data,8);
else
#endif
memcpy(pt_bms->t_bem_data.u8_bem_data,pt_msg->u8_data,4);
(void)u8_bms_timeout(0,gunNo,1,GB_BCP_TIMEOUT_FLAG);
v_set_rt_state(gunNo, BMS_STATE_TIMEOUT); //bms.state=6 - 报文超时,flow任务除了检测ctr.cmd外,还应检测
}
}
}
/****************************************************
*函数名称: void v_bmsComm_rx_handle(U8_T gunNo)
*功能说明: bms 解帧函数
*参数说明:
* 输入参数: U8_T gunNo, 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
void v_bmsComm_rx_handle(U8_T gunNo)
{
CAN_DATA_T *pt_msg = &s_bms_data.s_gb_bms_can[gunNo].pt_msg; //待解析的报文
u8_bms_get_lock();//申请锁
// printf_hex("bms recv:",pt_msg->u8_data,pt_msg->u16_len);
#if 1
switch(pt_msg->u32_pgn)
{
case GB_BMS_PGN_BHM: //BHM
{
v_bms_bhm_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BRM:
{
v_bms_brm_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BCP:
{
v_bms_bcp_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BRO:
{
v_bms_bro_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BCS:
{
v_bms_bcs_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BCL:
{
v_bms_bcl_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BSM:
{
v_bms_bsm_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BMV:
{
v_bms_bmv_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BMT:
{
v_bms_bmt_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BST:
{
v_bms_bst_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BSD:
{
v_bms_bsd_rx(gunNo,pt_msg);
break;
}
case GB_BMS_PGN_BEM:
{
v_bms_bem_rx(gunNo,pt_msg);
break;
}
default:
break;
}
#endif
u8_bms_free_lock();//释放锁
}
/****************************************************
*函数名称: void v_bms_rx_data(U8_T gunNo)
*功能说明: bms CAN数据接收函数
*参数说明:
* 输入参数: U8_T gunNo, 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_bms_rx_data(U8_T gunNo)
{
U8_T i,canRcvCnt = 0; //接收can报文数目
CAN_DATA rxMsg[CAN_RECV_BUF_SIZE] = {0};
S_GB_BMS_CAN *s_gb_bms_can = &s_bms_data.s_gb_bms_can[gunNo];
//接收数据并解析,实时数据/状态
//canRcvCnt = s_bms_data[gunNo].s_gb_bms_can.pt_dll->u32_can_rx(&rxMsg[0]);
canRcvCnt = s_gb_bms_can->pt_dll.u32_can_rx(&rxMsg[0]);
if(canRcvCnt > 0)
{
// printf("接收can1报文数 = %d\n", canRcvCnt);
for(i=0; i<canRcvCnt; i++)
{
if(u32_sae1393_rx(&s_gb_bms_can->pt_dll, &s_gb_bms_can->pt_msg, rxMsg[i]) == 1) //=1说明接收到完整帧,可解析
v_bmsComm_rx_handle(gunNo);
}
}
}
#endif
#if 1 //发送相关
/****************************************************
*函数名称: void v_bms_tx( CAN_DATA_T *pt_can_data)
*功能说明: BMS数据发送函数--发送can报文都是单包数据
*参数说明:
* 输入参数: DLL_DATA_T *pt_dll_data, CAN_DATA_T *pt_can_data
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_tx(U8_T gunNo,CAN_DATA_T *pt_msg)
{
u32_sae1393_tx(&s_bms_data.s_gb_bms_can[gunNo].pt_dll, pt_msg);
}
/****************************************************
*函数名称: void v_bms_chm_send(U8_T gunNo)
*功能说明: CHM组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_chm_send(U8_T gunNo)
{
CAN_DATA_T pt_msg;
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
/*
1.1 1.8 CR_Secc_VersionMinor 1:国标, 1:欧美标(默认值默认传递绝缘有限),2 (添加实时传递绝缘状态支持)
通信版本
2.1 2.8 CR_Secc_VersionMajorL 1:国标, 0:欧美标,
通信版本
3.1 3.8 CR_Secc_VersionMajorH 0:国标, 1:欧美标
通信版本
4.1 4.4 CR_Secc_EvseTransferType Supported Energy Type (default 3, see appendix)
供电设备传输类型 (默认值3,见附录)支持的能量类型
4.5 4.5 CF_Secc_StartPlc 0: PLC wait to start 1: PLC start chargeing seq.
启动Plc 0:PLC等待启动 1:PLC启动充电顺序。
5.1 6.8 CR_Secc_MaxPowerLimit Maximum Power Limit (mandatory)
最大功率限制 最大功率限制(强制)
*/
U16_T u16_sys_data[3] = {0};
u16_sys_data[0] = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MAX_VOL); //最大输出电压 精度0.1
u16_sys_data[1] = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MAX_CUR); //最大输出电流 精度0.1
u16_sys_data[2] = ((u16_sys_data[0]/10)*(u16_sys_data[1]/10))/1000;
pt_msg.u32_pgn = GB_BMS_PGN_CHM;
pt_msg.u8_pri = 6;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
pt_msg.u16_len = 8;
pt_msg.u8_data[0] = 0x01;
pt_msg.u8_data[1] = 0x01;
pt_msg.u8_data[2] = 0x00;
if(s_bms_data.u8_gun_linkState[gunNo]) //抢连接
pt_msg.u8_data[3] = 0x13;
else
pt_msg.u8_data[3] = 0x03;
//最大功率限值
pt_msg.u8_data[4] = u16_sys_data[2] & 0xff;
pt_msg.u8_data[5] = (u16_sys_data[2] >> 8) & 0xff;
}
else
#endif
{
pt_msg.u32_pgn = GB_BMS_PGN_CHM;
pt_msg.u8_pri = 6;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
pt_msg.u16_len = 3;
if(u16_bms_get_sys_para(gunNo,E_BMS_GET_PARA_SC_EN) == 1
&& pt_bms->u16_stoptimeflag<= (4*10)) //团标使能和启动前10S发送协议版本SC1 250ms周期 4周期为1秒
{
pt_msg.u8_data[0] = 0x31;
pt_msg.u8_data[1] = 0x43;
pt_msg.u8_data[2] = 0x53;
pt_bms->u16_stoptimeflag++;
}else
{
pt_msg.u8_data[0] = 0x01;
pt_msg.u8_data[1] = 0x01;
pt_msg.u8_data[2] = 0x00;
}
}
v_bms_tx(gunNo,&pt_msg);
}
/****************************************************
*函数名称: void v_bms_crm_send(U8_T gunNo,U8_T flag)
*功能说明: CRM组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号 U8_T flag 准备就绪标志
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_crm_send(U8_T gunNo,U8_T flag)
{
CAN_DATA_T pt_msg;
pt_msg.u32_pgn = GB_BMS_PGN_CRM;
pt_msg.u8_pri = 6;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
pt_msg.u16_len = 8;
pt_msg.u8_data[0] = flag; //辨识结果,0x00-不能辨识,0xAA-bms能辨识
pt_msg.u8_data[1] = 1;//pile_num[0]; //充电机编号 0-0xffffffff
pt_msg.u8_data[2] = 0;//pile_num[1];
pt_msg.u8_data[3] = 0;//pile_num[2];
pt_msg.u8_data[4] = 1;//pile_num[3];
pt_msg.u8_data[5] = 0; //所在区域编码,可选
pt_msg.u8_data[6] = 0;
pt_msg.u8_data[7] = 0;
v_bms_tx(gunNo,&pt_msg);
}
/****************************************************
*函数名称: void v_bms_cml_send(U8_T gunNo)
*功能说明: CML组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_cml_send(U8_T gunNo)
{
CAN_DATA_T pt_msg;
U16_T u16_data;
U16_T u16_sys_data[4];
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
u16_sys_data[0] = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MAX_VOL); //最大输出电压 精度0.1
u16_sys_data[1] = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MIN_VOL); //最小输出电压 精度0.1
u16_sys_data[2] = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MAX_CUR); //最大输出电流 精度0.1
u16_sys_data[3] = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MIN_CUR); //最小输出电流 精度0.1
pt_msg.u32_pgn = GB_BMS_PGN_CML;
pt_msg.u8_pri = 6;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
u16_data = u16_sys_data[0]; //最高输出电压
pt_msg.u8_data[0] = (U8_T)u16_data;
pt_msg.u8_data[1] = (U8_T)(u16_data>>8);
u16_data = u16_sys_data[1]; //最低输出电压
pt_msg.u8_data[2] = (U8_T)u16_data;
pt_msg.u8_data[3] = (U8_T)(u16_data>>8);
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
pt_msg.u16_len = 8;
if(u16_sys_data[2] > 4000) //
{
u16_data = (((U16_T)((u16_sys_data[2]/10-400)*10)) | 0x8000); //最大输出电流(按电流上限输出充电机最高电流)
}
else
u16_data = (400 - u16_sys_data[2]/10)*10; //最大输出电流(按电流上限输出充电机最高电流)
pt_msg.u8_data[4] = (U8_T)u16_data;
pt_msg.u8_data[5] = (U8_T)(u16_data>>8);
u16_data = (400 - u16_sys_data[3]/10)*10; //最小输出电流(按电流上限输出充电机最低电流)
pt_msg.u8_data[6] = (U8_T)u16_data;
pt_msg.u8_data[7] = (U8_T)(u16_data>>8);
}
else
#endif
{
if(pt_bms->t_brm_data.u8_Bms_edition == 0x5A) //接收到2015+协议标识 5A 2015+团标协议 FF国标协议
{
u16_data = (3000 - u16_sys_data[2]/10)*10; //最大输出电流(按电流上限输出充电机最高电流)
}else
u16_data = (400 - u16_sys_data[2]/10)*10; //最大输出电流(按电流上限输出充电机最高电流)
pt_msg.u8_data[4] = (U8_T)u16_data;
pt_msg.u8_data[5] = (U8_T)(u16_data>>8);
if (pt_bms->e_bms_standard == BMS_2011)
{
pt_msg.u16_len = 6;
}
else
{
pt_msg.u16_len = 8;
if(pt_bms->t_brm_data.u8_Bms_edition == 0x5A) //接收到2015+协议标识 5A 2015+团标协议 FF国标协议
{
u16_data = (3000 - u16_sys_data[3]/10)*10; //最小输出电流(按电流上限输出充电机最低电流)
}else
u16_data = (400 - u16_sys_data[0]/10)*10; //最小输出电流(按电流上限输出充电机最低电流)
pt_msg.u8_data[6] = (U8_T)u16_data;
pt_msg.u8_data[7] = (U8_T)(u16_data>>8);
}
}
v_bms_tx(gunNo,&pt_msg);
}
/****************************************************
*函数名称: void v_bms_cts_send(U8_T gunNo)
*功能说明: CTS组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_cts_send(U8_T gunNo)
{
CAN_DATA_T pt_msg;
Comm_Time t_time;
v_bms_get_rt_time(&t_time); //获取当前时间
pt_msg.u32_pgn = GB_BMS_PGN_CTS;
pt_msg.u8_pri = 6;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
pt_msg.u16_len = 7;
pt_msg.u8_data[0] = dec_to_bcd(t_time.ucSec);
pt_msg.u8_data[1] = dec_to_bcd(t_time.ucMin);
pt_msg.u8_data[2] = dec_to_bcd(t_time.ucHour);
pt_msg.u8_data[3] = dec_to_bcd(t_time.ucDay);
pt_msg.u8_data[4] = dec_to_bcd(t_time.ucMonth);
pt_msg.u8_data[5] = dec_to_bcd(t_time.iYear%100);
pt_msg.u8_data[6] = dec_to_bcd(t_time.iYear/1000);
v_bms_tx(gunNo,&pt_msg);
}
/****************************************************
*函数名称: void v_bms_cro_send(U8_T gunNo,U8_T flag)
*功能说明: CRO组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号 ,U8_T flag 准备就绪标志
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_cro_send(U8_T gunNo,U8_T flag)
{
CAN_DATA_T pt_msg;
pt_msg.u32_pgn = GB_BMS_PGN_CRO;
pt_msg.u8_pri = 4;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
pt_msg.u16_len = 1;
pt_msg.u8_data[0] = flag;
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
pt_msg.u16_len = 2;
if(flag == 0xAA)
pt_msg.u8_data[1] = 0x01;
else
pt_msg.u8_data[1] = 0x00;
}
#endif
v_bms_tx(gunNo,&pt_msg);
}
/****************************************************
*函数名称: void v_bms_ccs_send(U8_T gunNo)
*功能说明: CCS组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_ccs_send(U8_T gunNo)
{
CAN_DATA_T pt_msg;
U16_T u16_data;
U16_T u16_out_data[2];
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
u16_out_data[0] = u16_bms_get_sys_para(gunNo, E_BMS_GET_GUN_OUT_VOL); //输出电压 精度0.1
u16_out_data[1] = u16_bms_get_sys_para(gunNo, E_BMS_GET_GUN_OUT_CUR); //输出电流 精度0.1
pt_msg.u32_pgn = GB_BMS_PGN_CCS;
pt_msg.u8_pri = 6;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
u16_data = u16_out_data[0]; //电压输出值
pt_msg.u8_data[0] = (U8_T)u16_data;
pt_msg.u8_data[1] = (U8_T)(u16_data>>8);
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
/*
1.1 2.8 CR_Secc_EvseOutVolt Voltage output value 0.1 0 0~6553.5 V
当前输出电压 电压输出值
3.1 4.7 CR_Secc_EvseOutCurrent Current output value 0.1 -400 A
当前输出电流 电流输出值
4.8 4.8 CR_Secc_EvseOutCurrent Current output value 1 0 0~1 A
当前输出电流大于400A标志位 "0:小于400A电流计算:400A - 3.1~4.7的电流值;
1:大于400A电流计算:3.1~4.7的电流值 + 400A"
5.1 6.8 CR_Secc_MaxPowerLimit Maximum Power Limit (mandatory) 1000 0 0~600 W
桩最大功率限制 最大功率限制
7.1 7.2 CF_Secc_EvseSuspended 0: suspended, 1: permissible
桩停止状态位 0:暂停,1:允许
7.3 7.5 CR_Secc_EvsseIsolationStatus see the appendix 1 0 0~3
桩隔离状态(绝缘检测) 0 无效;1 有效;2 警告;3故障
7.6 7.6 CR_Secc_EvseMaxCurr_IsUse 0: No Use ; 1:Use 1 0 0~1
桩最大电流使用 0:不使用(默认CML中最大电流值); 1:使用(CCS中最大电流值)
7.7 8.8 CR_Secc_EvseMaxCurr_A Max output current 1 0 0 ~ 1000 A
桩最大输出电流 最大输出电流
*/
U16_T u16_sys_data[3] = {0};
u16_sys_data[0] = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MAX_VOL); //最大输出电压 精度0.1
u16_sys_data[1] = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MAX_CUR); //最大输出电流 精度0.1
u16_sys_data[2] = ((u16_sys_data[0]/10)*(u16_sys_data[1]/10))/1000;
pt_msg.u16_len = 8;
if(u16_sys_data[1] > 4000) //
{
u16_data = (((U16_T)((u16_out_data[1]-4000))) | 0x8000); //最大输出电流(按电流上限输出充电机最高电流)
}
else
u16_data = (U16_T)((4000 - u16_out_data[1])); //电流输出值
pt_msg.u8_data[2] = (U8_T)u16_data;
pt_msg.u8_data[3] = (U8_T)(u16_data>>8);
u16_data = u16_sys_data[2]; //桩最大功率限制
pt_msg.u8_data[4] = (U8_T)u16_data;
pt_msg.u8_data[5] = (U8_T)(u16_data>>8);
U8_T CF_Secc_EvseSuspended = 0; //桩停止状态位 0:暂停,1:允许
U8_T CR_Secc_EvsseIsolationStatus = 1; //桩隔离状态(绝缘检测) 0 无效;1 有效;2 警告;3故障
U8_T CR_Secc_EvseMaxCurr_IsUse = 1; //桩最大电流使用 0:不使用(默认CML中最大电流值); 1:使用(CCS中最大电流值)
U16_T CR_Secc_EvseMaxCurr_A = u16_bms_get_sys_para(gunNo , E_BMS_GET_PARA_MAX_CUR) / 10; //最大输出电流 精度0.1
u16_data = (CR_Secc_EvseMaxCurr_A << 10) +
(CF_Secc_EvseSuspended) + (CR_Secc_EvsseIsolationStatus << 2) + (CR_Secc_EvseMaxCurr_IsUse << 5);
pt_msg.u8_data[6] = (U8_T)u16_data;
pt_msg.u8_data[7] = (U8_T)(u16_data>>8);
}
else
#endif
{
if(pt_bms->t_brm_data.u8_Bms_edition == 0x5A) //接收到2015+协议标识 5A 2015+团标协议 FF国标协议
{
u16_data = (U16_T)((3000 - u16_out_data[1]/10)*10); //电流输出值
}else
u16_data = (U16_T)((400 - u16_out_data[1]/10)*10); //电流输出值
pt_msg.u8_data[2] = (U8_T)u16_data;
pt_msg.u8_data[3] = (U8_T)(u16_data>>8);
u16_data = u16_bms_get_sys_para(gunNo,E_BMS_GET_GUN_CHR_TIME); //累计充电时间 min
pt_msg.u8_data[4] = (U8_T)u16_data;
pt_msg.u8_data[5] = (U8_T)(u16_data>>8);
if (pt_bms->e_bms_standard == BMS_2011)
{
pt_msg.u16_len = 6;
}
else
{
pt_msg.u16_len = 7;
if ((pt_bms->t_bsm_data.u16_batt_state&(1<<8)) == 0)
pt_msg.u8_data[6] = 0xFC;
else
pt_msg.u8_data[6] = 0xFD;
pt_msg.u8_data[7] = 0xFF;
}
}
v_bms_tx(gunNo,&pt_msg);
}
/****************************************************
*函数名称: void v_bms_cst_send(U8_T gunNo)
*功能说明: CST组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_cst_send(U8_T gunNo)
{
CAN_DATA_T pt_msg;
U8_T u8_data[4];
if(u8_bms_get_cst(gunNo,u8_data) == 0)
return;
pt_msg.u32_pgn = GB_BMS_PGN_CST;
pt_msg.u8_pri = 4;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
pt_msg.u16_len = 4;
pt_msg.u8_data[0] = u8_data[0]; //中止原因
pt_msg.u8_data[1] = u8_data[1];
pt_msg.u8_data[2] = u8_data[2];
pt_msg.u8_data[3] = u8_data[3];
v_bms_tx(gunNo,&pt_msg);
}
/****************************************************
*函数名称: void v_bms_csd_send(U8_T gunNo)
*功能说明: CSD组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_csd_send(U8_T gunNo)
{
CAN_DATA_T pt_msg;
U16_T u16_data;
U8_T pile_num[17];
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
v_bms_get_pile_nun(pile_num);
pt_msg.u32_pgn = GB_BMS_PGN_CSD;
pt_msg.u8_pri = 6;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
pt_msg.u16_len = 8;
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
/*
1.1 2.8 CR_Secc_CumulativeChTime 0 (no value with CCS), Cumulative Charging Time 1 0 0~600 min 判断
累计充电时间 0(CCS无值);累计充电时间
3.1 4.8 CR_Secc_EvseOutVolt Voltage output value 0.1 0 0~6553.5 V 添加项 不判断
桩枪线当前输出电压 电压输出值
5.1 5.3 CR_Secc_EvseIsolationStatus see the appendix 1 0 0~3 添加项 判断
桩隔离状态(绝缘检测) 0 无效;1 有效;2 警告;3故障
*/
//充电时长
u16_data = u16_bms_get_sys_para(gunNo,E_BMS_GET_GUN_CHR_TIME); //累计充电时间 min
pt_msg.u8_data[0] = (U8_T)u16_data;
pt_msg.u8_data[1] = (U8_T)(u16_data>>8);
//桩枪线当前输出电压 0.1V
u16_data = u16_bms_get_sys_para(gunNo,E_BMS_GET_GUN_OUT_VOL); //输出电压 精度0.1
pt_msg.u8_data[2] = (U8_T)u16_data;
pt_msg.u8_data[3] = (U8_T)(u16_data>>8);
//桩隔离状态(绝缘检测) 0 无效;1 有效;2 警告;3故障
U8_T CR_Secc_EvsseIsolationStatus = 1;
pt_msg.u8_data[4] = CR_Secc_EvsseIsolationStatus & 0x07;
}
else
#endif
{
//充电时长
u16_data = u16_bms_get_sys_para(gunNo,E_BMS_GET_GUN_CHR_TIME); //累计充电时间 min
pt_msg.u8_data[0] = (U8_T)u16_data;
pt_msg.u8_data[1] = (U8_T)(u16_data>>8);
//电量
u16_data = u16_bms_get_sys_para(gunNo,E_BMS_GET_GUN_CHR_POWER); //充电电量 0.1kwh
pt_msg.u8_data[2] = (U8_T)u16_data;
pt_msg.u8_data[3] = (U8_T)(u16_data>>8);
pt_msg.u8_data[4] = pile_num[0];
if (pt_bms->e_bms_standard == BMS_2011)
{
pt_msg.u16_len = 5;
}
else
{
pt_msg.u16_len = 8;
pt_msg.u8_data[5] = pile_num[1];
pt_msg.u8_data[6] = pile_num[2];
pt_msg.u8_data[7] = pile_num[3];
}
}
pt_bms->u8_csd_send_cnt ++; //csd发送次数加一
v_bms_tx(gunNo,&pt_msg);
}
/****************************************************
*函数名称: void v_bms_cem_send(U8_T gunNo)
*功能说明: CEM组帧发送函数
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230210
*修改内容: 20230210 第一次创建子函数
****************************************************/
static void v_bms_cem_send(U8_T gunNo)
{
CAN_DATA_T pt_msg;
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
memset(&pt_msg, 0, sizeof(CAN_DATA_T));
pt_msg.u32_pgn = GB_BMS_PGN_CEM;
pt_msg.u8_pri = 2;
pt_msg.u8_src_addr = GB_CHARGER_ADDR;
pt_msg.u8_dest_addr = GB_BMS_ADDR;
pt_msg.u16_len = 4;
pt_msg.u8_data[0] = 0xFC;
pt_msg.u8_data[1] = 0xF0;
pt_msg.u8_data[2] = 0xC0;
pt_msg.u8_data[3] = 0xFC;
if ((pt_bms->u16_timeout_flag & GB_BRM_TIMEOUT_FLAG) != 0)
pt_msg.u8_data[0] |= 0x01;
else if ((pt_bms->u16_timeout_flag & GB_BCP_TIMEOUT_FLAG) != 0)
pt_msg.u8_data[1] |= 0x01;
else if ((pt_bms->u16_timeout_flag & GB_BRO_TIMEOUT_FLAG) != 0)
pt_msg.u8_data[1] |= 0x04;
else if ((pt_bms->u16_timeout_flag & GB_BCS_TIMEOUT_FLAG) != 0)
pt_msg.u8_data[2] |= 0x01;
else if ((pt_bms->u16_timeout_flag & GB_BCL_TIMEOUT_FLAG) != 0)
pt_msg.u8_data[2] |= 0x04;
else if ((pt_bms->u16_timeout_flag & GB_BST_TIMEOUT_FLAG) != 0)
pt_msg.u8_data[2] |= 0x10;
else if ((pt_bms->u16_timeout_flag & GB_BSD_TIMEOUT_FLAG) != 0)
pt_msg.u8_data[3] |= 0x01;
pt_bms->t_cem_data.u8_cem_data[0] = pt_msg.u8_data[0];
pt_bms->t_cem_data.u8_cem_data[1] = pt_msg.u8_data[1];
pt_bms->t_cem_data.u8_cem_data[2] = pt_msg.u8_data[2];
pt_bms->t_cem_data.u8_cem_data[3] = pt_msg.u8_data[3];
pt_bms->u8_cem_send_cnt ++; //cem发送次数加一
// BMS_LOG("CEM发送");
v_bms_tx(gunNo,&pt_msg);
}
//发送
void v_bmsComm_tx_handle(U8_T gunNo)
{
S_BMS_RT_DATA *pt_bms = &(s_bms_data.s_bms_rt_data[gunNo]); //bms
static U8_T cst_cnt[GUN_MAX_CNT] = {0};
// pt_bms->e_state = GB_BMS_CFG_RX_BRO_AA;
switch(pt_bms->e_state)
{
case GB_BMS_STOP: //空闲状态,无报文发送
{
//清除底层的多包状态
v_sae1393_clear_multi_pacet(&s_bms_data.s_gb_bms_can[gunNo].pt_dll);
break;
}
case GB_BMS_HANDSHAKE_TX_CHM: //握手启动阶段,发送CHM(协议版本V1.1)250ms
{
if(u8_tim_ret(gunNo,cnt250ms,BMS_TIM_250MS) == 0)
break;
v_bms_chm_send(gunNo);
break;
}
case GB_BMS_HANDSHAKE_TX_CRM_00: //握手辨识阶段,发送CRM-0x00250ms
{
if(u8_tim_ret(gunNo,cnt250ms,BMS_TIM_250MS) == 0)
break;
v_bms_crm_send(gunNo,0x00);
break;
}
case GB_BMS_HANDSHAKE_TX_CRM_AA: //握手辨识阶段结束,等待BCP进行参数设置,发送CRM_0xAA,250ms
{
if(u8_tim_ret(gunNo,cnt250ms,BMS_TIM_250MS) == 0)
break;
v_bms_crm_send(gunNo,0xAA);
break;
}
case GB_BMS_CFG_TX_CTS_CML: //参数配置阶段,收到BCP,发送CML(充电机最大输出能力)/CTS对时(可选,不在此处发送)
case GB_BMS_CFG_RX_BRO_AA: //参数配置阶段,收到BRO-0xAA,发送CML, 250ms CTS500ms
{
if(u8_tim_ret(gunNo,cnt250ms,BMS_TIM_250MS) == 1)
{
v_bms_cml_send(gunNo);
}
if(u8_tim_ret(gunNo,cnt500ms,BMS_TIM_500MS) == 1)
{
v_bms_cts_send(gunNo);
}
break;
}
case GB_BMS_CFG_TX_CRO_00: //桩根据接收BMS数据开始预充电,CRO-0x00,250ms
{
if(u8_tim_ret(gunNo,cnt250ms,BMS_TIM_250MS) == 0)
break;
v_bms_cro_send(gunNo,0x00);
break;
}
case GB_BMS_CFG_TX_CRO_AA: //参数配置阶段,预充完成,周期发送CRO-0xAA,250ms,等待BCL、BCS
{
if(u8_tim_ret(gunNo,cnt250ms,BMS_TIM_250MS) == 0)
break;
v_bms_cro_send(gunNo,0xAA);
break;
}
case GB_BMS_CHARGE_STAGE: //充电中阶段,CCS,50ms
{
if(u8_tim_ret(gunNo,cnt50ms,BMS_TIM_50MS) == 0)
break;
v_bms_ccs_send(gunNo);
break;
}
case GB_BMS_CHARGE_TX_CST: //充电机或充电桩停止充电,发送停止报文并等着接收BMS停止充电报文,发送CST 10ms,等待BST
{
if(cst_cnt[gunNo] ++ < 1)
break;
cst_cnt[gunNo] = 0;
v_bms_cst_send(gunNo);
break;
}
case GB_BMS_FINISH_RX_BSD: //收到BSD,发送CSD 250ms //充电机没有真正停机以前,还是要发充电状态报文,以保证在车的接触器断开时充电机己经停机
{
if(u8_tim_ret(gunNo,cnt250ms,BMS_TIM_250MS) == 0)
break;
v_bms_csd_send(gunNo);
break;
}
case GB_BMS_TX_CEM: //检测到报文超时 发送cem
{
if(u8_tim_ret(gunNo,cnt250ms,BMS_TIM_250MS)) //有错误且时间周期满足,即发送CEM
{
v_bms_cem_send(gunNo);
}
break;
}
default:
break;
}
}
#endif
#if 1 //bms流程相关
/****************************************************
*功能说明: BMS变量控制状态跳转
*参数说明:
* 输入参数: U8_T gunNo 枪号
* 输出参数: void
*最后修改时间: 20230228
*修改内容: 20230228 第一次创建子函数
****************************************************/
static void v_control_steate_jump(U8_T gunNo)
{
S_BMS_RT_DATA *gb_bms_data = &(s_bms_data.s_bms_rt_data[gunNo]);
U8_T ctrl_state = u16_bms_get_sys_para(gunNo,E_BMS_GET_GUN_FIOW_CTRL); //获取BMS流程状态 0无意义 1空闲 2开始握手 3绝缘完成,开始握手辨识 4预充完成,发送cro_aa 5充电停止 发送cst 6停止充电完成 停止发送CSD 7BMS通讯超时
E_BMS_STOP_INFO e_stop_info = E_BMS_STOP_NULL;
BMS_BHM_DATA_T t_bhm_save;
if(ctrl_state == 2) //1 开始BMS握手启动阶段
{
if(gb_bms_data->e_state == GB_BMS_STOP) //0空闲/停止充电
{
BMS_LOG("BMS HS start\n");
memset(gb_bms_data, 0, sizeof(S_BMS_RT_DATA)); //参数清0
gb_bms_data->e_bms_standard = BMS_2015;
v_set_flow_state(gunNo,GB_BMS_HANDSHAKE_TX_CHM); //跳转1
u8_tim_reset(gunNo,cnt_global); //计时更新,BHM超时计时
}
else if ((s_bms_data.u8_gun_type[gunNo] == 0) && gb_bms_data->e_state == GB_BMS_HANDSHAKE_TX_CHM) //欧标:2收到BHM,可以做绝缘检测,等待绝缘检测成功后发送CRO-00
{
//logMsg_bms("bms---开始握手辨识\n");
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if(gb_bms_data->t_bhm_data.u8_CR_Plc_Aagvalue != 0) //当CR_Plc_Aagvalue ≠0 时发送CRM -00
v_set_flow_state(gunNo,GB_BMS_HANDSHAKE_TX_CRM_00); //跳转3
#endif
u8_tim_reset(gunNo,cnt_global); //计时更新,BRM超时计时
}
else if(gb_bms_data->u8_reconn_flag == 1 && u16_bms_get_sys_para(gunNo,E_BMS_GET_GUN_FLOW_RENEW))
{
e_stop_info = s_bms_data.s_bms_rt_data[gunNo].e_stop_info; //重连清空前保存 bms超时原因
t_bhm_save = gb_bms_data->t_bhm_data;
memset(&s_bms_data.s_bms_rt_data[gunNo], 0, sizeof(S_BMS_RT_DATA)); //参数清0
s_bms_data.s_bms_rt_data[gunNo].e_stop_info = e_stop_info;
gb_bms_data->t_bhm_data = t_bhm_save;
v_set_flow_state(gunNo,GB_BMS_HANDSHAKE_TX_CRM_00); //跳转3
u8_tim_reset(gunNo,cnt_global); //计时更新,BRM超时计时
v_set_rt_state(gunNo, BMS_STATE_HANDSHAKE_START_OK); //bms状态??
u16_bms_get_sys_para(gunNo,E_BMS_CLEAR_GUN_FLOW_RENEW); //清空重连标志
gb_bms_data->u8_reconn_flag = 0; //重连标识置0
BMS_LOG("BMS reconn, HS ident\n");
}
}
else if (!(s_bms_data.u8_gun_type[gunNo] == 0) && ctrl_state == 3) //国标:2 开始BMS握手辨识阶段
{
if(gb_bms_data->e_state == GB_BMS_HANDSHAKE_TX_CHM) //2收到BHM,可以做绝缘检测,等待绝缘检测成功后发送CRO-00
{
BMS_LOG("BMS HS ident\n");
v_set_flow_state(gunNo,GB_BMS_HANDSHAKE_TX_CRM_00); //跳转3
u8_tim_reset(gunNo,cnt_global); //计时更新,BRM超时计时
}
else if(gb_bms_data->u8_reconn_flag == 1 && u16_bms_get_sys_para(gunNo,E_BMS_GET_GUN_FLOW_RENEW))
{
e_stop_info = s_bms_data.s_bms_rt_data[gunNo].e_stop_info; //重连清空前保存 bms超时原因
t_bhm_save = gb_bms_data->t_bhm_data;
memset(&s_bms_data.s_bms_rt_data[gunNo], 0, sizeof(S_BMS_RT_DATA)); //参数清0
s_bms_data.s_bms_rt_data[gunNo].e_stop_info = e_stop_info;
gb_bms_data->t_bhm_data = t_bhm_save;
v_set_flow_state(gunNo,GB_BMS_HANDSHAKE_TX_CRM_00); //跳转3
u8_tim_reset(gunNo,cnt_global); //计时更新,BRM超时计时
v_set_rt_state(gunNo, BMS_STATE_HANDSHAKE_START_OK); //bms状态??
u16_bms_get_sys_para(gunNo,E_BMS_CLEAR_GUN_FLOW_RENEW); //清空重连标志
gb_bms_data->u8_reconn_flag = 0; //重连标识置0
BMS_LOG("BMS reconn, HS ident\n");
}
}
else if(ctrl_state == 4) //3 启动充电
{
if(gb_bms_data->e_state == GB_BMS_CFG_TX_CRO_00) //7收到BRO-aa,发送CRO-00,等待允许发送cro-aa
{
BMS_LOG("BMS start chg\n");
v_set_flow_state(gunNo,GB_BMS_CFG_TX_CRO_AA); //跳转8
u8_tim_reset(gunNo,cnt_global);
u8_tim_reset(gunNo,cnt_bcl);
//没通信前设置未允许充电
s_bms_data.s_bms_rt_data[gunNo].t_bsm_data.u16_batt_state |= (1<<8); //BSM-允许充电
}
}
else if(ctrl_state == 5) //4 充电机停机,发送CST
{
if(gb_bms_data->e_state == GB_BMS_HANDSHAKE_TX_CHM) //0空闲/停止充电
{
memset(&s_bms_data.s_bms_rt_data[gunNo], 0, sizeof(S_BMS_RT_DATA));
v_set_flow_state(gunNo,GB_BMS_STOP);
BMS_LOG("BMS HS stage CST req, reset\n");
}
else if((gb_bms_data->e_state != GB_BMS_STOP) && //除了空闲及发送错误帧状态
(gb_bms_data->e_state != GB_BMS_CHARGE_TX_CST) &&
(gb_bms_data->e_state != GB_BMS_FINISH_RX_BSD) &&
(gb_bms_data->e_state != GB_BMS_TX_CEM) )
{
BMS_LOG("BMS st=%d, CST cmd rx\n", gb_bms_data->e_state);
v_set_bms_stop_info(gunNo,E_BMS_STOP_1001);
//v_gb_bms_CST_stopReason(); //填充CST停止原因
v_set_flow_state(gunNo,GB_BMS_CHARGE_TX_CST); //跳转11
u8_tim_reset(gunNo,cnt_global);
u8_tim_reset(gunNo,cnt_bcl);
}
}
else if(ctrl_state == 1 || ctrl_state == 6)
{
if(gb_bms_data->e_state != GB_BMS_STOP)
{
BMS_LOG("Idle, st reset\n");
v_set_flow_state(gunNo,GB_BMS_STOP); //跳转3
}
memset(gb_bms_data, 0, sizeof(S_BMS_RT_DATA)); //参数清0
}
//bcs bcl都接收到了 进入充电中
if((gb_bms_data->u8_bms_rx_flag[4] == 1) && (gb_bms_data->u8_bms_rx_flag[5] == 1))
{
if(gb_bms_data->e_state == GB_BMS_CFG_TX_CRO_AA)
{
v_set_rt_state(gunNo, BMS_STATE_CHARGING); //bms状态转10,充电中
v_set_flow_state(gunNo,GB_BMS_CHARGE_STAGE); //转充电中
s_bms_data.s_bms_rt_data[gunNo].e_stop_info = E_BMS_STOP_NULL; //进入到充电 bms故障原因就为0 避免在启动时的故障
BMS_LOG("BCS+BCL rx, enter chg\n");
}
}
}
#endif
#if 1 //数据初始化
/**
* ************************************************************************
* @brief - BMS 任务数据初始化
*
*
*
* @author jiankalka
* @date 2025-08-13
* ************************************************************************
*/
static void v_bms_data_init()
{
memset(&s_bms_data, 0, sizeof(S_BMS_DATA));
s_bms_data.s_gb_bms_can[0].pt_dll.u32_can_tx = u32_bms1_can_tx;
s_bms_data.s_gb_bms_can[0].pt_dll.u32_can_rx = u32_bms1_can_rx;
s_bms_data.s_bms_rt_data[0].e_state = GB_BMS_STOP;
s_bms_data.s_bms_rt_data[0].e_bms_standard = BMS_2015;
s_bms_data.s_gb_bms_can[1].pt_dll.u32_can_tx = u32_bms2_can_tx ;
s_bms_data.s_gb_bms_can[1].pt_dll.u32_can_rx = u32_bms2_can_rx;
s_bms_data.s_bms_rt_data[1].e_state = GB_BMS_STOP;
s_bms_data.s_bms_rt_data[1].e_bms_standard = BMS_2015;
s_bms_data.u8_gunCnt = u16_bms_get_sys_para(0,E_BMS_GET_PARA_GUN_CNT); //获取枪数量
memcpy(s_bms_data.u8_gun_type, g_t_share_data.t_sys_fix_cfg.u8_gun_type, GUN_MAX_CNT); //枪类型 0欧标 1国标
}
#endif
void v_bms_task(void *arg)
{
uint16_t sleep_time_ms;
uint32_t last_send_time;
uint32_t current_time;
uint8_t gunNo;
(void)arg;
(void)BMS_LOCK_INIT();
sleep_time_ms = BMS_SLEEP_TIME_MS();
last_send_time = get_current_seconds();
v_bms_data_init();
for (;;) {
BMS_FEED_DOG();
current_time = get_current_seconds();
if ((TASK_RUN_PRINT_TIME != 0U) && (u32_safe_seconds_since(last_send_time) >= TASK_RUN_PRINT_TIME)) {
if (BMS_LOCK_TAKE() == 1U) {
BMS_LOG("bms task is runing, sleep time is %ums", sleep_time_ms);
(void)BMS_LOCK_GIVE();
}
last_send_time = current_time;
}
for(gunNo=0; gunNo<s_bms_data.u8_gunCnt; gunNo++)
{
// //控制状态跳转检查
v_control_steate_jump(gunNo);
// //接收
v_bms_rx_data(gunNo);
// //发送
v_bmsComm_tx_handle(gunNo);
// //超时处理
// #if BMS_TEST == 0
v_bms_timeout_handle(gunNo);
// #endif
}
mSleep(sleep_time_ms);
}
}