Files
CCU621M/app/bms/bms_interface.c
T

383 lines
14 KiB
C

#include "bms/bms_interface.h"
#include "publicdata/publicdata.h"
#include "app_rtc/app_rtc.h"
#include "flowctrl/flow_interface.h"
#include "meter_calculate/meter_calculate_impl.h"
#include "bms/bms_task.h"
extern S_BMS_DATA s_bms_data; //BMS数据
/**
* ************************************************************************
* @brief - 获取BMS流程控制状态
*
* @param[in] u8_gunNo - 抢号 0-1
*
* @return U8_T - 0无意义 1空闲 2开始握手 3绝缘完成,开始握手辨识 4预充完成,发送cro_aa 5充电停止 发送cst 6停止充电完成 停止发送CSD 7BMS通讯超时
*
* @author jiankalka
* @date 2025-08-21
* ************************************************************************
*/
static U8_T u8_bms_get_flow_status(U8_T u8_gunNo)
{
U8_T ret_state = 0;
E_FLOW_REAL_STATE flow_state;
flow_state = (E_FLOW_REAL_STATE)u16_flow_put_data(u8_gunNo , E_FLOW_PUT_DATA_GUN_REAL_STATE,0); //0空闲 1充电启动 2绝缘启动 3绝缘计算完成 4绝缘检测模块停止 5开始预充 6预充完成 7充电中 8BMS通讯超时 9充电停止 10充电停止完成
switch (flow_state)
{
case E_FLOW_REAL_FREE : //空闲
ret_state = 1; //空闲
break;
case E_FLOW_REAL_CHARGE_START : //充电启动
ret_state = 2; //开始握手
break;
case E_FLOW_REAL_INSUL_START : //绝缘启动
break;
case E_FLOW_REAL_INSUL_OK : //绝缘计算完成
break;
case E_FLOW_REAL_INSUL_MDU_STOP : //绝缘检测模块停止
if ((s_bms_data.u8_gun_type[u8_gunNo] == 0))
ret_state = 4; //欧标:发送cro_aa
else
ret_state = 3; //国标:绝缘完成,开始握手辨识
break;
case E_FLOW_REAL_PRE_START : //开始预充
break;
case E_FLOW_REAL_PRE_OK : //预充完成
ret_state = 4; //预充完成,发送cro_aa
break;
case E_FLOW_REAL_CHARGEING : //充电中
break;
case E_FLOW_REAL_BMS_OUTTIME : //BMS通讯超时
break;
case E_FLOW_REAL_STOP : //充电停止
ret_state = 5; //停止充电(充电模块退出运行可给其他充电端口使用)
break;
case E_FLOW_REAL_STOP_OK : //充电停止完成
ret_state = 6; //停止充电完成
break;
default:
ret_state = 0;
break;
}
return ret_state;
}
/**
* ************************************************************************
* @brief - BMS任务获取 系统参数
*
* @param[in] gunNo - 枪号 0-1 当获取数据不分枪号时,该值无意义
* @param[in] e_type -
* E_BMS_GET_PARA_GUN_CNT=0, //枪数量 返回值1-N
E_BMS_GET_PARA_GB_EN, //国标使能 返回值 0不使能 1使能
E_BMS_GET_PARA_SC_EN, //团标使能 返回值 0不使能 1使能
E_BMS_GET_PARA_MAX_VOL, //最大电压 精度 0.1
E_BMS_GET_PARA_MIN_VOL, //最小电压 精度 0.1
E_BMS_GET_PARA_MAX_CUR, //最大电流 精度 0.1
E_BMS_GET_PARA_MIN_CUR, //最小电流 精度 0.1
E_BMS_GET_GUN_OUT_VOL, //输出电压 精度0.1
E_BMS_GET_GUN_OUT_CUR, //输出电流 精度0.1
E_BMS_GET_GUN_CHR_TIME, //充电时长 单位min
E_BMS_GET_GUN_CHR_POWER, //充电电量 单位0.1 kWh
E_BMS_GET_GUN_FIOW_CTRL, //BMS充电状态 0无意义 1空闲 2开始握手 3绝缘完成,开始握手辨识 4预充完成,发送cro_aa 5充电停止 发送cst 6停止充电完成 停止发送CSD 7BMS通讯超时
E_BMS_GET_GUN_FLOW_RENEW, //获取重连标识
E_BMS_CLEAR_GUN_FLOW_RENEW, //清空重连标识
* @return U16_T -
*
* @author jiankalka
* @date 2025-08-13
* ************************************************************************
*/
U16_T u16_bms_get_sys_para(U8_T gunNo , E_BMS_GET_PARA_TYPE e_type)
{
U16_T u16_ret = 0;
switch (e_type)
{
case E_BMS_GET_PARA_GUN_CNT: //枪数量
u16_ret = g_t_share_data.t_sys_fix_cfg.u8_gunCnt;
break;
case E_BMS_GET_PARA_GB_EN: //国标使能
u16_ret = g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_GBEnable;
break;
case E_BMS_GET_PARA_SC_EN: //团标使能
u16_ret = g_t_share_data.t_sys_fix_cfg.u_enable.bit_enable.bit_YeLenEn;
break;
case E_BMS_GET_PARA_MAX_VOL: //最大电压 精度 0.1
u16_ret = g_t_share_data.t_sys_fix_cfg.u16_max_volt;
break;
case E_BMS_GET_PARA_MIN_VOL: //最小电压 精度 0.1
u16_ret = g_t_share_data.t_sys_fix_cfg.u16_min_volt;
break;
case E_BMS_GET_PARA_MAX_CUR: //最大电流 精度 0.1
u16_ret = g_t_share_data.t_sys_fix_cfg.u16_max_cur;
break;
case E_BMS_GET_PARA_MIN_CUR: //最小电流 精度 0.1
u16_ret = 50;
break;
case E_BMS_GET_GUN_OUT_VOL: //输出电压 精度 0.1
u16_ret = (U16_T)(u64_get_meter_data(gunNo,0,E_METER_DATA_VOL)/1000);
break;
case E_BMS_GET_GUN_OUT_CUR: //输出电流 精度 0.1
u16_ret = (U16_T)(u64_get_meter_data(gunNo,0,E_METER_DATA_CUR)/1000);
break;
case E_BMS_GET_GUN_CHR_TIME: //充电时长 单位min
u16_ret = u32_meterlog_put_data(gunNo,E_METERLOG_PUT_LOG_INFO_CHAR_TIME,NULL,0); //获取充电时间
break;
case E_BMS_GET_GUN_CHR_POWER: //充电电量 单位0.1 kWh
u16_ret = (U16_T)u32_flow_put_data(gunNo,E_FLOW_PUT_DATA_USED_ENERGY) / NUM_100; //精度转换,由0.0001转换为0.1
break;
case E_BMS_GET_GUN_FIOW_CTRL: //BMS充电状态 0无意义 1空闲 2开始握手 3绝缘完成,开始握手辨识 4预充完成,发送cro_aa 5充电停止 发送cst 6停止充电完成 停止发送CSD 7BMS通讯超时
u16_ret = u8_bms_get_flow_status(gunNo);
break;
case E_BMS_GET_GUN_FLOW_RENEW: //获取重连标识
u16_ret = u16_flow_put_data(gunNo ,E_FLOW_PUT_DATA_GUN_RECONN_FLAG,0); //输出bms重连开始标志 参数:0获取 1清空
break;
case E_BMS_CLEAR_GUN_FLOW_RENEW: //清空重连标识
u16_ret = u16_flow_put_data(gunNo ,E_FLOW_PUT_DATA_GUN_RECONN_FLAG,1); //输出bms重连开始标志 参数:0获取 1清空
break;
default:
break;
}
return u16_ret;
}
U16_T u16_bms_put_data(U8_T gunNo , E_BMS_PUT_DATA_TYPE e_type,U8_T u8_dataPara)
{
U16_T u16_ret = 0;
S_BMS_RT_DATA *pt_bms = &s_bms_data.s_bms_rt_data[gunNo];
switch (e_type)
{
case E_BMS_PUT_DATA_BMS_GB_VER : //BMS 国标协议版本 0 2011版 1 2015版
{
u16_ret = pt_bms->e_bms_standard;
break;
}
case E_BMS_PUT_DATA_BMS_STATE : //BMS 获取BMS状态 0无 1握手完成 2握手失败 3开始预充 4开始充电 5禁止充电 6停止充电 7报文接收超时
{
u16_ret = pt_bms->e_real_state;
break;
}
case E_BMS_PUT_DATA_BMS_MAX_VOL : //BMS 最大充电电压值 精度 0.1V
{
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
if ((s_bms_data.u8_gun_type[gunNo] == 0))
{
u16_ret = (U16_T)(pt_bms->t_bcp_data.f32_batt_charge_max_volt*10);
if(u16_ret < (U16_T)(pt_bms->t_bcl_data.f32_batt_charge_max_volt*10))
u16_ret = (U16_T)(pt_bms->t_bcl_data.f32_batt_charge_max_volt*10);
}
else
#endif
u16_ret = (U16_T)(pt_bms->t_bhm_data.f32_max_charge_volt*10);
break;
}
case E_BMS_PUT_DATA_BMS_MAX_CUR : //BMS 最大充电电流值 精度 0.1V
{
u16_ret = (U16_T)(pt_bms->t_bcp_data.f32_batt_charge_max_curr*10);
break;
}
case E_BMS_PUT_DATA_BMS_REAL_BATT_VOL : //BMS 当前电池电压值 精度 0.1V
{
u16_ret = (U16_T)(pt_bms->t_bcp_data.f32_batt_volt*10);
break;
}
case E_BMS_PUT_DATA_BMS_NEED_VOL : //BMS 需求电压值 精度 0.1V
{
u16_ret = (U16_T)(pt_bms->t_bcl_data.f32_batt_need_volt *10);
break;
}
case E_BMS_PUT_DATA_BMS_NEED_CUR : //BMS 需求电流值 精度 0.1A
{
u16_ret = (U16_T)(pt_bms->t_bcl_data.f32_batt_need_curr *10);
break;
}
case E_BMS_PUT_DATA_BMS_CAN_SEND_CNT : //BMS 报文发送次数 参数值 0代表cem 1代表csd
{
if(u8_dataPara == 0)
u16_ret = pt_bms->u8_cem_send_cnt;
else
u16_ret = pt_bms->u8_csd_send_cnt;
break;
}
case E_BMS_PUT_DATA_BMS_STOP_RES : //BMS 停止原因 详看E_FAULT_INFO枚举内容 BMS部分
{
u16_ret = pt_bms->e_stop_info;
break;
}
case E_BMS_PUT_DATA_BMS_RECONN_FLAG : //BMS 重连标志 0不重连 1重连
{
u16_ret = pt_bms->u8_reconn_flag;
break;
}
case E_BMS_PUT_DATA_GUN_SOC: //BMS SOC %
{
u16_ret = pt_bms->t_bcs_data.u8_batt_soc;
break;
}
case E_BMS_PUT_DATA_GUN_ONE_BATT_MAX_TEMP: //单体电池最大温度 -50度
{
u16_ret = pt_bms->t_bsm_data.s16_batt_max_temp;
break;
}
case E_BMS_PUT_DATA_GUN_ONE_BATT_MAX_VOL: //单体电池最大电压 0.1V
{
u16_ret = (U16_T)(pt_bms->t_bcs_data.f32_cell_max_volt * 10);
break;
}
case E_BMS_PUT_DATA_GUN_BATT_TYPE: //电池类型 01H,铅酸电池;02H:镍氢电池;03H:磷酸铁锂电池;04H:锰酸锂电池;05H:钴酸锂电池;
{
u16_ret = pt_bms->t_brm_data.u8_batt_type;
break;
}
case E_BMS_PUT_DATA_GUN_BATT_RATED_C10: //整车动力蓄电池系统额定容量,数据范围0~1000A.h,精度0.1
{
u16_ret = (U16_T)(pt_bms->t_brm_data.f32_batt_rated_c10*10);
break;
}
default:
break;
}
return u16_ret;
}
void v_bms_get_rt_time(Comm_Time *time)
{
GetCurrentTime(time);
}
/****************************************************
*函数名称: v_get_cst(U8_T gunNo,U8_T *u8_data)
*功能说明: 获取cst停止原因
*参数说明:
* 输入参数:
* 输出参数: void
*最后修改时间: 20230602
*修改内容: 20230602 第一次创建子函数
****************************************************/
U8_T u8_bms_get_cst(U8_T gunNo,U8_T *u8_data)
{
BMS_CST_DATA_U cst_data;
E_FAULT_INFO e_stop_res = (E_FAULT_INFO)u16_flow_get_sys_data(gunNo, E_FLOW_GET_DATA_GUN_STOP_REASON_0, 0);
memset(&cst_data , 0 ,sizeof(BMS_CST_DATA_U));
if(e_stop_res == E_NORMAL_1001 || e_stop_res == E_NORMAL_1002)
cst_data.CST_TMO_FLAG.MAN_MADE_STOP = 1;
else if(e_stop_res == E_NORMAL_1003 || e_stop_res == E_NORMAL_1004)
cst_data.CST_TMO_FLAG.PILE_NORMAL_STOP = 1;
else if(e_stop_res == E_FAULT_13017 )
{
cst_data.CST_TMO_FLAG.FAULT_STOP = 1;
cst_data.CST_TMO_FLAG.EMERGENCY_STOP = 1;
}
else if(e_stop_res == E_FAULT_13016 || /* 充电中导引/连接类 */
e_stop_res == E_FAULT_13015 ||
e_stop_res == E_FAULT_15019)
{
cst_data.CST_TMO_FLAG.FAULT_STOP = 1;
cst_data.CST_TMO_FLAG.PILE_CONNET_FAULT = 1;
}
else if(e_stop_res == E_FAULT_15037 || /* 输出超车辆最高允许充电电压 D0.4504 等 */
e_stop_res == E_FAULT_13048 ||
e_stop_res == E_FAULT_15039 ||
e_stop_res == E_FAULT_15045)
{
cst_data.CST_TMO_FLAG.FAULT_STOP = 1;
cst_data.CST_TMO_FLAG.OVER_VOLT = 1;
}
else if(s_bms_data.s_bms_rt_data[gunNo].t_cst_data.CST_TMO_FLAG.BMS_STOP) //BMS主动中止
cst_data.CST_TMO_FLAG.BMS_STOP = 1;
else
{
cst_data.CST_TMO_FLAG.FAULT_STOP = 1;
cst_data.CST_TMO_FLAG.OTHER = 1;
}
cst_data.CST_TMO_FLAG.reserve1 = 0x0F;
cst_data.CST_TMO_FLAG.reserve = 0x0F;
memcpy(u8_data,&cst_data,sizeof(BMS_CST_DATA_U));
return 1;
//logMsg("fault_info= %x , %x %x %x %x\n",fault_info,u8_data[0],u8_data[1],u8_data[2],u8_data[3]);
}
/****************************************************
*函数名称: v_bms_get_pile_nun()
*功能说明: 获取获取充电桩桩编号
*参数说明:
* 输入参数:U8_T *pilenum
* 输出参数:
****************************************************/
void v_bms_get_pile_nun(U8_T *pilenum)
{
U8_T len = strlen((char *)g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum);
memset(pilenum,0,len+1);
memcpy(pilenum,g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_platA_pileNum,len);
}
/**
* ************************************************************************
* @brief - 对外提供VIN信息获取接口函数
*
* @param[in] u8_gunNo - 抢号 0-N
* @param[in] u8_vin - 获取数据数组
* @param[in] u8_len - 数组长度
*
*
* @author jiankalka
* @date 2025-09-15
* ************************************************************************
*/
void v_bms_put_vin_str(U8_T u8_gunNo,U8_T *u8_vin,U8_T u8_len)
{
if(u8_vin == NULL ) return;
if(u8_gunNo >= 2) return;
memset(u8_vin , 0 ,u8_len);
strncpy((char *)u8_vin , (char *)s_bms_data.s_bms_rt_data[u8_gunNo].t_brm_data.u8_car_vin ,u8_len);
}
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
U8_T u8_test_gunLink[GUN_MAX_CNT];
/**
* ************************************************************************
* @brief - can 转PLC 获取枪连接状态
*
* @param[in] gunNo - 枪号 0-1
*
* @return U8_T - 抢连接状态 0未连接 1已连接
*
* @author jiankalka
* @date 2025-11-14
* ************************************************************************
*/
U8_T u8_bms_get_gunLink(U8_T gunNo)
{
U8_T u8_gunLink;
u8_gunLink = s_bms_data.u8_gun_linkState[gunNo];
//u8_gunLink = u8_test_gunLink[gunNo];
return u8_gunLink;
}
#endif