#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