Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,382 @@
|
||||
#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
|
||||
|
||||
@@ -0,0 +1,368 @@
|
||||
|
||||
#ifndef BMS_INTERFACE_H
|
||||
#define BMS_INTERFACE_H
|
||||
|
||||
#ifdef __cplusplus /*C++编译环境下兼容C语言*/
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------ Exported includes(头文件) ----------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/*------ Exported macro(宏定义) -------------------------*/
|
||||
|
||||
/*------ Exported struct(结构体定义) --------------------*/
|
||||
//BMS接收数据类型 0bhm 1brm 2bcp 3bro 4bcs 5bcl 6bsm 7bmv 8bmt 9bst 10bsd 11bem
|
||||
typedef enum
|
||||
{
|
||||
E_BMS_TYPE_BHM = 0,
|
||||
E_BMS_TYPE_BRM,
|
||||
E_BMS_TYPE_BCP,
|
||||
E_BMS_TYPE_BRO,
|
||||
E_BMS_TYPE_BCS,
|
||||
E_BMS_TYPE_BCL,
|
||||
E_BMS_TYPE_BSM,
|
||||
E_BMS_TYPE_BMV,
|
||||
E_BMS_TYPE_BMT,
|
||||
E_BMS_TYPE_BST,
|
||||
E_BMS_TYPE_BSD,
|
||||
E_BMS_TYPE_BEM,
|
||||
BMS_RECV_TYPE_NUM,//BMS接收数据类型数量
|
||||
}E_BSM_CAR_DATA_TYPE;
|
||||
|
||||
//BMS_BHM报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
F32_T f32_max_charge_volt; //最高允许充电总电压
|
||||
|
||||
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
|
||||
U8_T u8_CR_Plc_Aagvalue; // 信号衰减值
|
||||
U8_T u8_CR_Plc_CpStatus; // CP状态 0:12v未插枪;1:9v已插枪;2:9v占空比状态;3:6v占空比准备充电状态
|
||||
U8_T u8_CR_Plc_CommStart; // 通信启动 0:通信未启动;1:启动PLC通信
|
||||
U8_T u8_SECC_ver[10]; //SECC固件版本编译日期-年月日
|
||||
#endif
|
||||
}BMS_BHM_DATA_T;
|
||||
//BMS_BRM报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
//握手辨识BRM
|
||||
U32_T u32_bms_version; //BMS通信协议版本,例如版本V1.0,表示为0x000100
|
||||
U8_T u8_batt_type; //电池类型,01H,铅酸电池;02H:镍氢电池;03H:磷酸铁锂电池;04H:锰酸锂电池;05H:钴酸锂电池;
|
||||
//06H:三元材料电池;07H:聚合物锂离子电池;08H;钛酸锂电池;FFH:其他电池
|
||||
F32_T f32_batt_rated_c10; //整车动力蓄电池系统额定容量,数据范围0~1000A.h,精度0.1
|
||||
F32_T f32_batt_rated_volt; //整车动力蓄电池系统额定总电压,数据范围0~750V,精度0.1
|
||||
U8_T u8_batt_vender[4]; //电池生产厂商,标准ASCII
|
||||
U32_T u32_batt_serial; //电池组序号
|
||||
U8_T u8_batt_make[4]; //电池生产年月日
|
||||
U32_T u32_batt_charge_times; //BMS电池组充电次数
|
||||
U8_T u8_batt_belong; //电池产权标识
|
||||
U8_T u8_Bms_edition; //充电机通信协议版本号 5A 2015+团标协议 FF 国标协议
|
||||
|
||||
U8_T u8_car_vin[18]; //车辆识别码VIN
|
||||
U8_T u8_bms_soft_version[8]; //BMS软件版本号
|
||||
|
||||
}BMS_BRM_DATA_T;
|
||||
|
||||
//BMS_BCP报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
F32_T f32_cell_charge_max_volt; //单体动力蓄电池最高允许充电电压,数据范围0~24V,精度0.01
|
||||
F32_T f32_batt_charge_max_curr; //最高允许充电电流,数据范围0~400A,精度0.1
|
||||
F32_T f32_batt_rated_enery; //动力蓄电池标称总能量,数据范围0~1000kW.h,精度0.1
|
||||
F32_T f32_batt_charge_max_volt; //最高允许充电总电压,数据范围0~750V,精度0.1,此变量用于判断电压超出最高允许充电电压
|
||||
S16_T s16_batt_allow_max_temp; //最高允许动力蓄电池温度,数据范围-50度~200度
|
||||
F32_T f32_batt_start_soc; //整车动力蓄电池荷电状态(SOC),数据范围0~100%,精度0.1,这个SOC是充电开始时的SOC
|
||||
F32_T f32_batt_volt; //整车动力蓄当前电池总电压,数据范围0~750V,精度0.1
|
||||
|
||||
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
|
||||
U8_T u8_CR_Plc_EvTransferType; //电动车传输协议能量类型 默认0x03,支持的能量传输类型
|
||||
#endif
|
||||
}BMS_BCP_DATA_T;
|
||||
|
||||
//BMS_BSD报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
U8_T u8_batt_end_soc; //BMS终止荷电状态SOC
|
||||
F32_T f32_cell_batt_min_volt; //BMS动力蓄电池单体最低电压
|
||||
F32_T f32_cell_batt_max_volt; //BMS动力蓄电池单体最高电压
|
||||
U8_T u8_batt_min_temp; //BMS动力蓄电池最低温度
|
||||
U8_T u8_batt_max_temp; //BMS动力蓄电池最高温度
|
||||
|
||||
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
|
||||
U8_T u8_CF_Plc_WeldDetectionReq; //粘连检测要求 0:无焊接检测1:焊接检测请求(发送CSD当前充电枪电压)
|
||||
#endif
|
||||
}BMS_BSD_DATA_T;
|
||||
|
||||
//BMS_BCL报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
F32_T f32_batt_need_volt; //电压需求,数据范围0~750V,精度0.1
|
||||
F32_T f32_batt_need_curr; //电流需求,数据范围0~400V,精度0.1
|
||||
U8_T u8_charge_mode; //充电模式,0x01:恒压充电;0x02:恒流充电
|
||||
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
|
||||
F32_T f32_batt_charge_max_volt; //欧标车辆充电中最高允许电压在BCL中
|
||||
U8_T u8_preCharge; //预充电状态 1:预充电状态: 0:无预充电状态
|
||||
#endif
|
||||
}BMS_BCL_DATA_T;
|
||||
|
||||
//BMS_BCS报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
F32_T f32_charge_volt; //充电电压测量值,数据范围0~750V,精度0.1
|
||||
F32_T f32_charge_curr; //充电电流测量值,数据范围0~400A,精度0.1
|
||||
F32_T f32_cell_max_volt; //最高单体动力蓄电池电压,数据范围0~24V,精度0.01
|
||||
U8_T u8_cell_max_volt[2];
|
||||
U8_T u8_cell_max_volt_group_num; //最高单体动力蓄电池电压所在组号,范围1~16
|
||||
U8_T u8_batt_soc; //当前荷电状态,数据范围0~100%
|
||||
U16_T u16_remain_charge_time; //估算剩余充电时间,数据范围0~600min
|
||||
}BMS_BCS_DATA_T;
|
||||
|
||||
//BMS_BMV报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
// 1-12位:单体动力蓄电池电压,数据分辨率:0.01 V/位,0 V偏移量;数据范围:0~24 V;
|
||||
// 13-16位:电池分组号,数据分辨率:1/位,0偏移量;数据范围:0~15。
|
||||
union
|
||||
{
|
||||
U16_T u16_data;
|
||||
struct
|
||||
{
|
||||
U16_T bit_cell_volt:12; //单体电压
|
||||
U16_T bit_cell_group_numt:4; //单体电池组号
|
||||
}s_bit;
|
||||
}u_data[NUM_256];
|
||||
}BMS_BMV_DATA_T;
|
||||
|
||||
//BMS_BMT报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
U8_T u8_batt_temp[NUM_128]; //动力蓄电池温度,数据范围-50度~200度 原始数据存储
|
||||
}BMS_BMT_DATA_T;
|
||||
//BMS_BSM报文数据结构体
|
||||
typedef struct
|
||||
{
|
||||
U8_T u8_cell_max_volt_id; //最高单体动力蓄电池电压所在编号,数据范围1~256
|
||||
S16_T s16_batt_max_temp; //最高动力蓄电池温度,数据范围-50度~200度
|
||||
U8_T u8_max_temp_id; //最高温度检测点编号,数据范围1~128
|
||||
S16_T s16_batt_min_temp; //最低动力蓄电池温度,数据范围-50度~200度
|
||||
U8_T u8_min_temp_id; //最低温度检测点编号,数据范围1~128
|
||||
U16_T u16_batt_state; //电池状态
|
||||
//bit0:单体动力蓄电池电压过高
|
||||
//bit1:单体动力蓄电池电压过低
|
||||
//bit2:整车动力蓄电池荷电状态SOC过高
|
||||
//bit3:整车动力蓄电池荷电状态SOC过低
|
||||
//bit4:动力蓄电池充电过流
|
||||
//bit5:动力蓄电池温度过高
|
||||
//bit6:动力蓄电池绝缘状态不正常
|
||||
//bit7:动力蓄电池组输出连接器连接状态不正常
|
||||
//bit8:充电允许,0:禁止,1:允许
|
||||
}BMS_BSM_DATA_T;
|
||||
|
||||
//BMS_BEM报文数据联合体
|
||||
typedef union
|
||||
{
|
||||
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
|
||||
U8_T u8_bem_data[8];
|
||||
struct
|
||||
{
|
||||
U8_T RECV_CRM_00_TMO:2; //接收CRM=00超时
|
||||
U8_T RECV_CRM_AA_TMO:2; //接收CRM=AA超时
|
||||
U8_T reserve1:4; //保留1
|
||||
U8_T RECV_CML_TMO:2; //接收CML超时
|
||||
U8_T RECV_CRO_AA_TMO:2; //接收CRO=AA超时
|
||||
U8_T reserve2:4; //保留2
|
||||
U8_T RECV_CCS_TMO:2; //接收CCS超时
|
||||
U8_T RECV_CST_TMO:2; //接收CTS超时
|
||||
U8_T reserve3:4; //保留3
|
||||
U8_T RECV_CSD_TMO:2; //接收CSD超时
|
||||
U8_T reserve4:6; //保留3
|
||||
|
||||
U8_T Message_Sequence:8; //通信流程消息序列
|
||||
U8_T CR_Plc_ErrorCodeII:8; //错误代码II 见附录
|
||||
U8_T CR_Plc_ErrorCode:8; //错误代码 见附录
|
||||
U8_T ErrorCode_CPorPP_state:3; //CP或PP状态的错误代码 见附录
|
||||
U8_T CR_PLc_EvErrCode:4; //EV车辆发送的错误代码 见附录
|
||||
U8_T reserve5:1; //预留位
|
||||
}BEM_TMO_FLAG;
|
||||
#else
|
||||
U8_T u8_bem_data[4];
|
||||
struct
|
||||
{
|
||||
U8_T RECV_CRM_00_TMO:2; //接收CRM=00超时
|
||||
U8_T RECV_CRM_AA_TMO:2; //接收CRM=AA超时
|
||||
U8_T reserve1:4; //保留1
|
||||
U8_T RECV_CML_TMO:2; //接收CML超时
|
||||
U8_T RECV_CRO_AA_TMO:2; //接收CRO=AA超时
|
||||
U8_T reserve2:4; //保留2
|
||||
U8_T RECV_CCS_TMO:2; //接收CCS超时
|
||||
U8_T RECV_CST_TMO:2; //接收CTS超时
|
||||
U8_T reserve3:4; //保留3
|
||||
U8_T RECV_CSD_TMO:2; //接收CSD超时
|
||||
U8_T reserve4:6; //保留3
|
||||
}BEM_TMO_FLAG;
|
||||
#endif
|
||||
}BMS_BEM_DATA_U;
|
||||
|
||||
//BMS_CEM报文数据联合体
|
||||
typedef union
|
||||
{
|
||||
U8_T u8_cem_data[4];
|
||||
struct
|
||||
{
|
||||
U8_T RECV_BRM_TMO:2; //接收RRM超时
|
||||
U8_T reserve1:6; //保留1
|
||||
U8_T RECV_BCP_TMO:2; //接收BCP超时
|
||||
U8_T RECV_BRO_AA_TMO:2; //接收BRO=AA超时
|
||||
U8_T reserve2:4; //保留2
|
||||
U8_T RECV_BCS_TMO:2; //接收BCS超时
|
||||
U8_T RECV_BCL_TMO:2; //接收BCL超时
|
||||
U8_T RECV_BST_TMO:2; //接收BTS超时
|
||||
U8_T reserve3:2; //保留3
|
||||
U8_T RECV_BSD_TMO:2; //接收BSD超时
|
||||
U8_T reserve4:6; //保留3
|
||||
}CEM_TMO_FLAG;
|
||||
|
||||
}BMS_CEM_DATA_U;
|
||||
|
||||
//BMS_BST报文数据联合体
|
||||
typedef union
|
||||
{
|
||||
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
|
||||
U8_T u8_bst_data[8];
|
||||
struct
|
||||
{
|
||||
U8_T ACHIEVE_AIM_SOC:2; //达到目标SOC
|
||||
U8_T ACHIEVE_VOLT:2; //接收总电压设定值
|
||||
U8_T ACHIEVE_CELL_VOLT:2; //达到单体电压设定值
|
||||
U8_T CHARGER_STOP:2; //充电机主动终止
|
||||
U8_T INSU_FAULT:2; //绝缘故障
|
||||
U8_T DC_OUT_OVER_TEMP:2; //输出连接器过温故障
|
||||
U8_T BMS_OVER_TEMP:2; //BMS元件、输出连接器过温故障
|
||||
U8_T CONNECT_FAULT:2; //充电连接器故障
|
||||
U8_T BATT_OVER_TEMP:2; //电池组温度过高故障
|
||||
U8_T HV_RELAYS_FAULT:2; //高压继电器故障
|
||||
U8_T CONN_CHECK_TWO_FAULT:2; //检测点2电压检测故障
|
||||
U8_T OTHER_FAULT:2; //其它故障
|
||||
U8_T OVER_CURR:2; //电流过大
|
||||
U8_T OVER_VOLT:2; //电压过大
|
||||
U8_T reserve:2; //预留位
|
||||
U8_T CF_Plc_FullChgComplete:1; //车充电是否完成 0:未满1:完全充电完成
|
||||
U8_T CF_Plc_ChgFinished:1; //桩充电状态 0:充电,1:充电停止请求
|
||||
|
||||
U8_T Message_Sequence:8; //通信流程消息序列
|
||||
U8_T CR_Plc_ErrorCodeII:8; //错误代码II 见附录
|
||||
U8_T CR_Plc_ErrorCode:8; //错误代码 见附录
|
||||
U8_T ErrorCode_CPorPP_state:3; //CP或PP状态的错误代码 见附录
|
||||
U8_T CR_PLc_EvErrCode:4; //EV车辆发送的错误代码 见附录
|
||||
U8_T reserve2:1; //预留位
|
||||
}BST_TMO_FLAG;
|
||||
#else
|
||||
U8_T u8_bst_data[4];
|
||||
struct
|
||||
{
|
||||
U8_T ACHIEVE_AIM_SOC:2; //达到目标SOC
|
||||
U8_T ACHIEVE_VOLT:2; //接收总电压设定值
|
||||
U8_T ACHIEVE_CELL_VOLT:2; //达到单体电压设定值
|
||||
U8_T CHARGER_STOP:2; //充电机主动终止
|
||||
U8_T INSU_FAULT:2; //绝缘故障
|
||||
U8_T DC_OUT_OVER_TEMP:2; //输出连接器过温故障
|
||||
U8_T BMS_OVER_TEMP:2; //BMS元件、输出连接器过温故障
|
||||
U8_T CONNECT_FAULT:2; //充电连接器故障
|
||||
U8_T BATT_OVER_TEMP:2; //电池组温度过高故障
|
||||
U8_T HV_RELAYS_FAULT:2; //高压继电器故障
|
||||
U8_T CONN_CHECK_TWO_FAULT:2; //检测点2电压检测故障
|
||||
U8_T OTHER_FAULT:2; //其它故障
|
||||
U8_T OVER_CURR:2; //电流过大
|
||||
U8_T OVER_VOLT:2; //电压过大
|
||||
U8_T reserve:4; //预留位
|
||||
|
||||
}BST_TMO_FLAG;
|
||||
#endif
|
||||
}BMS_BST_DATA_U;
|
||||
|
||||
//BMS_CST报文数据联合体
|
||||
typedef union
|
||||
{
|
||||
U8_T u8_cst_data[4];
|
||||
struct
|
||||
{
|
||||
U8_T PILE_NORMAL_STOP:2; //达到充电机设定的条件中止
|
||||
U8_T MAN_MADE_STOP:2; //人工中止
|
||||
U8_T FAULT_STOP:2; //故障中止
|
||||
U8_T BMS_STOP:2; //BMS主动中止
|
||||
U8_T PILE_TEMP_OVER:2; //充电机过温故障
|
||||
U8_T PILE_CONNET_FAULT:2; //充电连接器故障
|
||||
U8_T PILE_TEMP_CVER2:2; //充电机内部过温故障
|
||||
U8_T NOT_NEOUGH_ENERGY:2; //所需电量不能传送
|
||||
U8_T EMERGENCY_STOP:2; //充电机急停故障
|
||||
U8_T OTHER:2; //其他故障
|
||||
U8_T reserve:4; //预留位
|
||||
U8_T OVER_CURR:2; //电流过大
|
||||
U8_T OVER_VOLT:2; //电压过大
|
||||
U8_T reserve1:4; //预留位
|
||||
}CST_TMO_FLAG;
|
||||
|
||||
}BMS_CST_DATA_U;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
E_BMS_GET_PARA_GUN_CNT=0, //枪数量
|
||||
E_BMS_GET_PARA_GB_EN, //国标使能
|
||||
E_BMS_GET_PARA_SC_EN, //团标使能
|
||||
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, //清空重连标识
|
||||
}E_BMS_GET_PARA_TYPE;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
E_BMS_PUT_DATA_BMS_GB_VER =0, //BMS 国标协议版本 0 2011版 1 2015版
|
||||
E_BMS_PUT_DATA_BMS_STATE, //BMS 获取BMS状态 0无 1握手完成 2握手失败 3开始预充 4开始充电 5禁止充电 6停止充电 7报文接收超时
|
||||
E_BMS_PUT_DATA_BMS_MAX_VOL, //BMS 最大充电电压值 精度 0.1V
|
||||
E_BMS_PUT_DATA_BMS_MAX_CUR, //BMS 最大充电电流值 精度 0.1A
|
||||
E_BMS_PUT_DATA_BMS_REAL_BATT_VOL, //BMS 当前电池电压值 精度 0.1V
|
||||
E_BMS_PUT_DATA_BMS_NEED_VOL, //BMS 需求电压值 精度 0.1V
|
||||
E_BMS_PUT_DATA_BMS_NEED_CUR, //BMS 需求电流值 精度 0.1A
|
||||
E_BMS_PUT_DATA_BMS_CAN_SEND_CNT, //BMS 报文发送次数 参数值 0代表cem 1代表csd
|
||||
E_BMS_PUT_DATA_BMS_STOP_RES, //BMS 停止原因 详看E_FAULT_INFO枚举内容 BMS部分
|
||||
E_BMS_PUT_DATA_BMS_RECONN_FLAG, //BMS 重连标志 0不重连 1重连
|
||||
|
||||
E_BMS_PUT_DATA_GUN_SOC, //BMS SOC %
|
||||
E_BMS_PUT_DATA_GUN_ONE_BATT_MAX_TEMP, //单体电池最大温度 度
|
||||
E_BMS_PUT_DATA_GUN_ONE_BATT_MAX_VOL, //单体电池最大电压 0.1V
|
||||
E_BMS_PUT_DATA_GUN_BATT_TYPE, //电池类型 01H,铅酸电池;02H:镍氢电池;03H:磷酸铁锂电池;04H:锰酸锂电池;05H:钴酸锂电池;
|
||||
E_BMS_PUT_DATA_GUN_BATT_RATED_C10, //整车动力蓄电池系统额定容量,数据范围0~1000A.h,精度0.1
|
||||
}E_BMS_PUT_DATA_TYPE;
|
||||
|
||||
/*------ Exported variables(变量定义) -------------------*/
|
||||
|
||||
/*------ Exported function prototypes (函数声明) -------*/
|
||||
void v_bms_add_timer(void);
|
||||
void v_delay_set_tymer_val(void);
|
||||
|
||||
U16_T u16_bms_get_sys_para(U8_T gunNo , E_BMS_GET_PARA_TYPE e_type);
|
||||
U16_T u16_bms_put_data(U8_T gunNo , E_BMS_PUT_DATA_TYPE e_type,U8_T u8_dataPara);
|
||||
void v_bms_put_vin_str(U8_T u8_gunNo,U8_T *u8_vin,U8_T u8_len);
|
||||
|
||||
void v_bms_get_rt_time(Comm_Time *time);
|
||||
U8_T u8_bms_get_cst(U8_T gunNo,U8_T *u8_data);
|
||||
void v_bms_get_pile_nun(U8_T *pilenum);
|
||||
|
||||
#if CAN_PLC_FLAG //欧标 CAN转PLC使能
|
||||
U8_T u8_bms_get_gunLink(U8_T gunNo); //can 转PLC 获取枪连接状态
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BMS_INTERFACE_H */
|
||||
+2681
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,247 @@
|
||||
#ifndef BMS_TASK_H
|
||||
#define BMS_TASK_H
|
||||
|
||||
#ifdef __cplusplus /*C++���뻷���¼���C����*/
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------ Exported includes(ͷ�ļ�) ----------------------*/
|
||||
#include "main.h"
|
||||
#include "bms/bms_interface.h"
|
||||
#include "bms/sae1939.h"
|
||||
|
||||
|
||||
/*------ Exported macro(�궨��) -------------------------*/
|
||||
// BMS����֡���� �궨��
|
||||
#define GB_BMS_ADDR 0xF4
|
||||
#define GB_CHARGER_ADDR 0x56
|
||||
|
||||
#define GB_BMS_PGN_CHM 0x002600
|
||||
#define GB_BMS_PGN_BHM 0x002700
|
||||
#define GB_BMS_PGN_CRM 0x000100
|
||||
#define GB_BMS_PGN_BRM 0x000200
|
||||
|
||||
#define GB_BMS_PGN_BCP 0x000600
|
||||
#define GB_BMS_PGN_CTS 0x000700
|
||||
#define GB_BMS_PGN_CML 0x000800
|
||||
#define GB_BMS_PGN_BRO 0x000900
|
||||
#define GB_BMS_PGN_CRO 0x000A00
|
||||
|
||||
#define GB_BMS_PGN_BCL 0x001000
|
||||
#define GB_BMS_PGN_BCS 0x001100
|
||||
#define GB_BMS_PGN_CCS 0x001200
|
||||
#define GB_BMS_PGN_BSM 0x001300
|
||||
#define GB_BMS_PGN_BMV 0x001500
|
||||
#define GB_BMS_PGN_BMT 0x001600
|
||||
#define GB_BMS_PGN_BSP 0x001700
|
||||
#define GB_BMS_PGN_BST 0x001900
|
||||
#define GB_BMS_PGN_CST 0x001A00
|
||||
|
||||
#define GB_BMS_PGN_BSD 0x001C00
|
||||
#define GB_BMS_PGN_CSD 0x001D00
|
||||
|
||||
#define GB_BMS_PGN_BEM 0x001E00
|
||||
#define GB_BMS_PGN_CEM 0x001F00
|
||||
|
||||
#define GB_BRM_TIMEOUT_FLAG 0x01 //bit0:BRM���ij�ʱ
|
||||
#define GB_BCP_TIMEOUT_FLAG 0x02 //bit1:BCP���ij�ʱ
|
||||
#define GB_BRO_TIMEOUT_FLAG 0x04 //bit2:BRO���ij�ʱ
|
||||
#define GB_BCS_TIMEOUT_FLAG 0x08 //bit3:BCS���ij�ʱ
|
||||
#define GB_BCL_TIMEOUT_FLAG 0x10 //bit4:BCL���ij�ʱ
|
||||
#define GB_BST_TIMEOUT_FLAG 0x20 //bit5:BST���ij�ʱ
|
||||
#define GB_BSD_TIMEOUT_FLAG 0x40 //bit6:BSD���ij�ʱ
|
||||
|
||||
//��ʱ��ʱ���� -- ��ʱ��ʹ�ã���������
|
||||
#define BMS_TIM_10MS (1*1)
|
||||
#define BMS_TIM_50MS (5*1+1)
|
||||
#define BMS_TIM_250MS (29*1)
|
||||
#define BMS_TIM_500MS (50*1)
|
||||
|
||||
#define BMS_TIM_1S ((100+11+29)*1) //���͵�һ��cem ����Ҫ250ms
|
||||
#define BMS_TIM_5S ((500+22+135)*1)
|
||||
#define BMS_TIM_10S ((1000+12+250)*1)
|
||||
#define BMS_TIM_60S ((6000+12+1498)*1)
|
||||
/*------ Exported struct(�ṹ�嶨��) --------------------*/
|
||||
|
||||
//BMS���ڶ�ʱ��־
|
||||
typedef struct
|
||||
{
|
||||
U8_T cnt50ms; //50ms
|
||||
U8_T cnt250ms; //250ms
|
||||
U8_T cnt500ms; //500ms
|
||||
|
||||
U16_T u16_global_timerCnt; //��ʱ��ʱ,��ʱ����,����ʱ���£����յ�Ŀ�����0
|
||||
U16_T u16_bcl_timerCnt; //����ͬʱ�ж�֡���Ľ����������ӳ�ʱ��ʱ������bsmʹ��global
|
||||
U16_T u16_bro_timerCnt; //�����Σ���global��¼bro_aa��60s��ʱ���øñ�����¼bro��5�볬ʱ
|
||||
|
||||
}T_BMS_TIM;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
cnt50ms = 0,
|
||||
cnt250ms,
|
||||
cnt500ms,
|
||||
cnt_global,
|
||||
cnt_bcl, //BSD״̬����
|
||||
cnt_bro_aa,
|
||||
}E_BMS_TIM;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GB_BMS_STOP=0, //ֹͣ���
|
||||
|
||||
GB_BMS_HANDSHAKE_TX_CHM, //���������Σ����ͳ�������CHM���ȴ����ճ�������BHM
|
||||
//GB_BMS_HANDSHAKE_RX_BHM_OK, //���������Σ����ͳ�������CHM���ѽ��ճ������ֳɹ�BHM��ϵͳ����Ե��⣬�ȴ�����ʼ���ֱ�ʶCRM������
|
||||
|
||||
GB_BMS_HANDSHAKE_TX_CRM_00, //���ֱ�ʶ�Σ�����CRM_00���ȴ�����BMS�ͳ�����ʶ����BRM
|
||||
GB_BMS_HANDSHAKE_TX_CRM_AA, //���ֱ�ʶ�Σ����յ�BMS�ͳ�����ʶ����BRM������CRM_AA���ȴ����յ�س���������BCP
|
||||
|
||||
GB_BMS_CFG_TX_CTS_CML, //���������ýΣ����յ���س���������BCP������CTS��CML���ȴ�����BMS��ɳ��������BRO
|
||||
GB_BMS_CFG_RX_BRO_AA, //���������ýΣ����յ���س���������BRO_00������CTS��CML���ȴ�����BMS��ɳ��������BRO_AA
|
||||
GB_BMS_CFG_TX_CRO_00, //���������ýΣ�����BMS��ɳ��������BRO_AA�����ͳ����������ɱ���CRO_00���ȴ�����CRO-AA����
|
||||
GB_BMS_CFG_TX_CRO_AA, //���������ýΣ�����BMS��ɳ��������BRO�����ͳ����������ɱ���CRO_AA���ȴ����յ���ܳ��״̬BCS/��س��������BCL
|
||||
|
||||
//GB_BMS_CHARGE_RX_BCL, //���Σ������յ���ܳ��״̬BCS���ȴ����յ�س��������BCL
|
||||
GB_BMS_CHARGE_STAGE, //���Σ�����CCS���ѽ��ձ���BCS��BCL������BST/BSM(����Ƿ����쳣)/��BMV/BMT/BSP(��ѡ)
|
||||
GB_BMS_CHARGE_TX_CST, //���Σ����ͳ�����ֹ��籨��CST���ȴ�����BMS��ֹ��籨��BST��BMSͳ�Ʊ���BSD
|
||||
|
||||
GB_BMS_FINISH_RX_BSD, //�������Σ����յ�BSD�����ͳ�����ֹ��籨��CSD
|
||||
|
||||
//GB_BMS_FINISH_RX_BSD_OK, //�������Σ����յ�BSD
|
||||
//GB_BMS_FINISH_TX_CSD, //�������Σ����ͳ���ͳ�Ʊ���CSD
|
||||
|
||||
GB_BMS_TX_CEM, //�������ʹ�����
|
||||
}GB_BMS_STATE_E;
|
||||
/* BMS״̬ */
|
||||
typedef enum
|
||||
{
|
||||
BMS_STATE_NONE=0, //��ͨ�ţ�BMSͳ�Ʊ������ݲ�����
|
||||
BMS_STATE_HANDSHAKE_START_OK, //�����������
|
||||
BMS_STATE_HANDSHAKE_FAIL, //��������ʧ��
|
||||
BMS_STATE_PRECHARGE, //Ԥ���
|
||||
BMS_STATE_CHARGING, //�����
|
||||
BMS_STATE_BSM_FORBID, //����У�BSM��ʾ��ֹ���
|
||||
BMS_STATE_STOP, //ֹͣ�У�����CST
|
||||
BMS_STATE_TIMEOUT, //���ij�ʱ(CEM/BEM)
|
||||
BMS_STATE_ERR, //���ݴ���
|
||||
}BMS_STATE_E;
|
||||
typedef enum
|
||||
{
|
||||
E_BMS_STOP_NULL =0,
|
||||
|
||||
E_BMS_STOP_1000 = 1000,
|
||||
E_BMS_STOP_1001 = 1001,
|
||||
E_BMS_STOP_1011 = 1011,
|
||||
|
||||
E_BMS_STOP_15000 = 15000,
|
||||
E_BMS_STOP_15001,
|
||||
E_BMS_STOP_15002,
|
||||
E_BMS_STOP_15003,
|
||||
E_BMS_STOP_15004,
|
||||
E_BMS_STOP_15005,
|
||||
E_BMS_STOP_15006,
|
||||
E_BMS_STOP_15007,
|
||||
E_BMS_STOP_15008,
|
||||
E_BMS_STOP_15009,
|
||||
|
||||
E_BMS_STOP_15010,
|
||||
E_BMS_STOP_15011,
|
||||
E_BMS_STOP_15012,
|
||||
E_BMS_STOP_15013,
|
||||
E_BMS_STOP_15014,
|
||||
E_BMS_STOP_15015,
|
||||
E_BMS_STOP_15016,
|
||||
E_BMS_STOP_15017,
|
||||
E_BMS_STOP_15018,
|
||||
E_BMS_STOP_15019,
|
||||
|
||||
E_BMS_STOP_15020,
|
||||
E_BMS_STOP_15021,
|
||||
E_BMS_STOP_15022,
|
||||
E_BMS_STOP_15023,
|
||||
E_BMS_STOP_15024,
|
||||
E_BMS_STOP_15025,
|
||||
E_BMS_STOP_15026,
|
||||
E_BMS_STOP_15027,
|
||||
E_BMS_STOP_15028,
|
||||
E_BMS_STOP_15029,
|
||||
E_BMS_STOP_15030,
|
||||
E_BMS_STOP_15031,
|
||||
}E_BMS_STOP_INFO;
|
||||
|
||||
//BMS��
|
||||
typedef enum
|
||||
{
|
||||
BMS_2011=0, //2011�����BMS��
|
||||
BMS_2015, //2015�����BMS��
|
||||
BMS_2023, //2023�����BMS��
|
||||
BMS_PLC, //CANתPLC
|
||||
}BMS_STANDARD_E;
|
||||
/* BMSʵʱ���� */
|
||||
typedef struct
|
||||
{
|
||||
GB_BMS_STATE_E e_state; //BMS״̬����
|
||||
BMS_STATE_E e_real_state; //���� bmsʵʱ״̬ //BMS״̬
|
||||
E_BMS_STOP_INFO e_stop_info; //bmsֹͣԭ��
|
||||
BMS_STANDARD_E e_bms_standard; //BMS�汾Э������ 2011 2015
|
||||
|
||||
U8_T u8_reconn_flag; //������ǣ�0Ĭ�ϣ�1��ʼ����
|
||||
|
||||
U8_T u8_cst_send_cnt; //cst���ʹ���
|
||||
U8_T u8_csd_send_cnt; //csd���ʹ���
|
||||
U8_T u8_cem_send_cnt; //cem���ʹ���
|
||||
U8_T u8_bms_rx_flag[BMS_RECV_TYPE_NUM]; //bms�����ѽ��ձ�ʶ��0��1�� //0bhm 1brm 2bcp 3bro 4bcs 5bcl 6bsm 7bmv 8bmt 9bst 10bsd 11bem
|
||||
|
||||
U16_T u16_timeout_flag; //���ձ��ij�ʱ��� �������CEM
|
||||
U16_T u16_stoptimeflag ; //SC1ֹͣ���ͱ�־
|
||||
|
||||
//=============================BMS���������ʵ����==============================
|
||||
BMS_BHM_DATA_T t_bhm_data;
|
||||
BMS_BRM_DATA_T t_brm_data;
|
||||
BMS_BCP_DATA_T t_bcp_data;
|
||||
BMS_BSD_DATA_T t_bsd_data;
|
||||
BMS_BCL_DATA_T t_bcl_data;
|
||||
BMS_BCS_DATA_T t_bcs_data;
|
||||
BMS_BSM_DATA_T t_bsm_data;
|
||||
BMS_BMV_DATA_T t_bmv_data; //����δʹ��
|
||||
BMS_BMT_DATA_T t_bmt_data; //����δʹ��
|
||||
|
||||
BMS_BEM_DATA_U t_bem_data;
|
||||
BMS_CEM_DATA_U t_cem_data;
|
||||
BMS_BST_DATA_U t_bst_data;
|
||||
BMS_CST_DATA_U t_cst_data;
|
||||
}S_BMS_RT_DATA;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CAN_DATA_T pt_msg; //���ձ��Ĵ洢����
|
||||
DLL_DATA_T pt_dll; //SAE����������̿�������
|
||||
}S_GB_BMS_CAN;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8_T u8_gunCnt; //ǹ����
|
||||
U8_T u8_gb_enable; //����ʹ��
|
||||
U8_T u8_gun_type[GUN_MAX_CNT]; //ǹ���� 0ŷ�� 1����
|
||||
|
||||
#if CAN_PLC_FLAG //ŷ�� CANתPLCʹ��
|
||||
U8_T u8_gun_linkState[GUN_MAX_CNT]; //�����ӱ�־ 0δ��ǹ 1�Ѳ�ǹ
|
||||
#endif
|
||||
|
||||
T_BMS_TIM t_bms_tim[GUN_MAX_CNT]; //bms���ڶ�ʱ��־
|
||||
S_GB_BMS_CAN s_gb_bms_can[GUN_MAX_CNT]; //BMS CAN���ͽ��սӿ�
|
||||
S_BMS_RT_DATA s_bms_rt_data[GUN_MAX_CNT]; //BMSʵʱ����
|
||||
}S_BMS_DATA;
|
||||
|
||||
|
||||
|
||||
/*------ Exported variables(��������) -------------------*/
|
||||
|
||||
/*------ Exported function prototypes ������������ -------*/
|
||||
void v_bms_task(void *arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* BMS_TASK_H */
|
||||
@@ -0,0 +1,46 @@
|
||||
# bms 模块说明
|
||||
|
||||
> 路径:`app/bms/`
|
||||
> 返回主说明:[README](../../README.md)
|
||||
|
||||
## 1. 模块职责
|
||||
|
||||
- 负责 BMS 通信报文收发与协议状态机处理;
|
||||
- 管理 BMS 充电阶段控制、超时处理与异常状态;
|
||||
- 提供与流程控制模块对接的 BMS 数据接口。
|
||||
|
||||
## 2. 关键文件
|
||||
|
||||
- `bms_task.c/h`
|
||||
- `bms_interface.c/h`
|
||||
- `sae1939.c/h`
|
||||
|
||||
## 3. 功能说明
|
||||
|
||||
- 周期接收/发送 BMS 报文并更新运行状态;
|
||||
- 维护关键定时器(超时、等待、状态切换计时);
|
||||
- 将 BMS 结果映射为流程层可用的控制/状态数据。
|
||||
|
||||
## 4. 调度与对外接口
|
||||
|
||||
该模块由 FreeRTOS 任务 `BmsComm` 周期运行(单位:ms),周期来自 `app/app_init/app_init.c`:
|
||||
|
||||
- `BmsComm`:`5ms`(任务入口:`v_bms_task(void *arg)`)
|
||||
|
||||
对外接口(来自 `bms_task.h / bms_interface.h`,列出主要用法入口):
|
||||
|
||||
- `uint16_t u16_bms_get_sys_para(U8_T gunNo, E_BMS_GET_PARA_TYPE e_type)`:读取 BMS 系统参数
|
||||
- `uint16_t u16_bms_put_data(U8_T gunNo, E_BMS_PUT_DATA_TYPE e_type, U8_T u8_dataPara)`:设置/上报 BMS 数据(按 e_type 不同)
|
||||
- `void v_bms_put_vin_str(U8_T u8_gunNo, U8_T *u8_vin, U8_T u8_len)`:写入 VIN 字符串
|
||||
- `void v_bms_get_rt_time(Comm_Time *time)`:读取 BMS/系统时间(取决于实现)
|
||||
- `U8_T u8_bms_get_cst(U8_T gunNo, U8_T *u8_data)`:读取充电阶段/状态相关值
|
||||
- `void v_bms_get_pile_nun(U8_T *pilenum)`:读取桩侧枚举/数量(命名以代码为准)
|
||||
|
||||
## 5. 维护建议
|
||||
|
||||
- 修改报文处理流程时需同步校验超时逻辑;
|
||||
- 与流程控制交互字段应保持枚举/状态码一致。
|
||||
|
||||
## 6. 关联文档
|
||||
|
||||
- 主索引:[README](../../README.md)
|
||||
@@ -0,0 +1,417 @@
|
||||
#include "bms/sae1939.h"
|
||||
|
||||
/*
|
||||
缩写 全称 翻译
|
||||
DLL data link layer 数据链路层
|
||||
*/
|
||||
|
||||
#define TIMEOUT_T1 750 //750ms
|
||||
#define TIMEOUT_T2 1250 //1250ms
|
||||
#define TIMEOUT_T3 1250 //1250ms
|
||||
#define TIMEOUT_T4 1050 //1050ms
|
||||
|
||||
#define TP_CM_PGN 0x00EC00 //CM-多包传输的连接管理
|
||||
#define TP_DT_PGN 0x00EB00 //DT-多包数据传输
|
||||
|
||||
#define TP_CM_RTS 16 //RTS-请求发送
|
||||
#define TP_CM_CTS 17 //CTS-允许发送
|
||||
#define TP_CM_ENDOFMSGACK 19 //结束应答
|
||||
#define TP_CM_ABORT 255 //放弃连接
|
||||
|
||||
static U16_T u16_timer_count = 0; //定时其计数值
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 用于上层清除底层的多包状态
|
||||
*
|
||||
* @param[in] pt_dll_data - 1393层数据
|
||||
*
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-08-12
|
||||
* ************************************************************************
|
||||
*/
|
||||
void v_sae1393_clear_multi_pacet(DLL_DATA_T *pt_dll_data)
|
||||
{
|
||||
pt_dll_data->e_msg_state = NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - SAE1393层发送函数,单包报文直接发送,多包报文此函数只传送RTS,多包传输处理在u32_sae1393_rx内进行
|
||||
* 注:27930中 不存在多包发送,此处仅考虑发送单包数据
|
||||
* @param[in] pt_dll_data - 1393层数据
|
||||
* @param[in] pt_can_data - 要送的报文
|
||||
*
|
||||
* @return U32_T - 0:发送成功,1:发送失败
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-08-12
|
||||
* ************************************************************************
|
||||
*/
|
||||
U32_T u32_sae1393_tx(DLL_DATA_T *pt_dll_data, CAN_DATA_T *pt_can_data)
|
||||
{
|
||||
CAN_DATA t_msg;
|
||||
U32_T i;
|
||||
U8_T SendCmd = ((pt_can_data->u32_pgn & 0x0000FF00) >> 8);
|
||||
|
||||
memset(&t_msg, 0, sizeof(CAN_DATA));
|
||||
|
||||
if (pt_can_data->u16_len <= 8)
|
||||
{
|
||||
//单包发送
|
||||
t_msg.ID = u32_get_can_ID(pt_can_data->u8_pri,SendCmd,pt_can_data->u8_dest_addr,pt_can_data->u8_src_addr); //组帧ID
|
||||
t_msg.Len = pt_can_data->u16_len;
|
||||
|
||||
for (i=0; i<t_msg.Len; i++)
|
||||
t_msg.Data[i] = pt_can_data->u8_data[i];
|
||||
|
||||
return pt_dll_data->u32_can_tx(&t_msg); //这样定义有助于多个can口复用
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void v_delay_set_tymer_val(void)
|
||||
{
|
||||
u16_timer_count ++;
|
||||
}
|
||||
U32_T u32_delay_get_timer_val()
|
||||
{
|
||||
return u16_timer_count;
|
||||
}
|
||||
//计算时间间隔(单位:ms) (b+MAX-a)%MAX
|
||||
U32_T u32_delay_time_elapse(U32_T tim3_cnt_start, U32_T tim3_cnt_end)
|
||||
{
|
||||
if(tim3_cnt_end >= tim3_cnt_start)
|
||||
return (tim3_cnt_end-tim3_cnt_start)*10;
|
||||
else
|
||||
return (65535-tim3_cnt_end+tim3_cnt_start-1)*10;
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - SAE1393层接收函数,接收到多包请求后 发送cts应答报文
|
||||
*
|
||||
* @param[in] ExtId - 帧ID
|
||||
* @param[in] Pgn - 多包帧pgn
|
||||
* @param[in] pack_num - 包总数
|
||||
* @param[in] pack_cnt - 请求包数
|
||||
* @param[in] t_tx_msg - 组帧报文内容
|
||||
*
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-08-13
|
||||
* ************************************************************************
|
||||
*/
|
||||
void v_sae1939_cts_send(U32_T ExtId,U32_T Pgn, U8_T pack_num , U8_T pack_cnt, CAN_DATA *t_tx_msg)
|
||||
{
|
||||
t_tx_msg->ID = (ExtId & 0xFFFF0000);
|
||||
t_tx_msg->ID |= ((ExtId & 0xFF00) >> 8 ); //帧ID目标地址 源地址转换
|
||||
t_tx_msg->ID |= ((ExtId & 0x00FF) << 8 );
|
||||
|
||||
t_tx_msg->ID = (t_tx_msg->ID & 0xFF00FFFF)|(TP_CM_PGN << 8); //将帧ID PGN赋值为0xEC
|
||||
|
||||
t_tx_msg->Len = 8;
|
||||
|
||||
t_tx_msg->Data[0] = TP_CM_CTS;
|
||||
t_tx_msg->Data[1] = pack_num;
|
||||
t_tx_msg->Data[2] = pack_cnt;
|
||||
t_tx_msg->Data[3] = 0xFF;
|
||||
t_tx_msg->Data[4] = 0xFF;
|
||||
t_tx_msg->Data[5] = ((Pgn >> 16) & 0xFF);
|
||||
t_tx_msg->Data[6] = ((Pgn >> 8 ) & 0xFF);
|
||||
t_tx_msg->Data[7] = ((Pgn ) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - sae1939 放弃连接发送
|
||||
*
|
||||
* @param[in] ExtID - 帧ID
|
||||
* @param[in] Pgn - 多包帧报文对应 PGN
|
||||
* @param[in] t_tx_msg - 发送can数据组包
|
||||
*
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-08-13
|
||||
* ************************************************************************
|
||||
*/
|
||||
void v_sae1939_abort_send(U32_T ExtID, U32_T Pgn, CAN_DATA *t_tx_msg)
|
||||
{
|
||||
t_tx_msg->ID = (ExtID & 0xFFFF0000);
|
||||
t_tx_msg->ID |= ((ExtID & 0xFF00) >> 8 ); //帧ID目标地址 源地址转换
|
||||
t_tx_msg->ID |= ((ExtID & 0x00FF) << 8 );
|
||||
|
||||
t_tx_msg->Len = 8;
|
||||
|
||||
t_tx_msg->Data[0] = TP_CM_ABORT;
|
||||
t_tx_msg->Data[1] = 0xFF;
|
||||
t_tx_msg->Data[2] = 0xFF;
|
||||
t_tx_msg->Data[3] = 0xFF;
|
||||
t_tx_msg->Data[4] = 0xFF;
|
||||
t_tx_msg->Data[5] = ((Pgn >> 16) & 0xFF);
|
||||
t_tx_msg->Data[6] = ((Pgn >> 8 ) & 0xFF);
|
||||
t_tx_msg->Data[7] = ((Pgn ) & 0xFF);
|
||||
|
||||
}
|
||||
/*************************************************************
|
||||
函数名称: v_sae1939_EndofMsgACK_send
|
||||
函数功能: SAE1393层接收函数,放弃连接函数
|
||||
输入参数: pt_dll_data 接收报文
|
||||
输出参数: t_tx_msg 发送报文
|
||||
返回值 :void
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 多包完成接收 发送结束应答帧
|
||||
*
|
||||
* @param[in] pt_dll_data - sae1939 控制数据
|
||||
* @param[in] t_tx_msg - 发送组包CAN数据
|
||||
*
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-08-13
|
||||
* ************************************************************************
|
||||
*/
|
||||
void v_sae1939_EndofMsgACK_send(DLL_DATA_T *pt_dll_data, CAN_DATA *t_tx_msg)
|
||||
{
|
||||
t_tx_msg->ID = ((U32_T)(pt_dll_data->u8_pri & 0x07) << 26);
|
||||
t_tx_msg->ID |= ((TP_CM_PGN & 0x0000FF00) << 8);
|
||||
t_tx_msg->ID |= ((pt_dll_data->u8_dest_addr & 0xFF) );
|
||||
t_tx_msg->ID |= ((pt_dll_data->u8_src_addr & 0x00FF) << 8 );
|
||||
|
||||
t_tx_msg->Len = 8;
|
||||
|
||||
t_tx_msg->Data[0] = TP_CM_ENDOFMSGACK;
|
||||
t_tx_msg->Data[1] = (U8_T)(pt_dll_data->u16_len);
|
||||
t_tx_msg->Data[2] = (U8_T)(pt_dll_data->u16_len>>8);
|
||||
t_tx_msg->Data[3] = (pt_dll_data->u16_len+6)/7;
|
||||
t_tx_msg->Data[4] = 0xFF;
|
||||
t_tx_msg->Data[5] = (U8_T)(pt_dll_data->u32_pgn);
|
||||
t_tx_msg->Data[6] = (U8_T)(pt_dll_data->u32_pgn>>8);
|
||||
t_tx_msg->Data[7] = (U8_T)(pt_dll_data->u32_pgn>>16);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************
|
||||
函数名称: u32_sae1393_rx
|
||||
函数功能: SAE1393层接收函数,此函数需要在BMS处理层主循环内调用,
|
||||
处理报文的接收和多包报文的发送,也处理1393层的超时事件
|
||||
输入参数: pt_dll_data -- 1393层数据, rxMsg -- 待解析的报文
|
||||
输出参数: pt_can_data -- 保存接收到的完整报文
|
||||
返回值 :0:接收成功,pt_can_data指向的报文可用;1:接收失败,pt_can_data指向的报文不可用
|
||||
**************************************************************/
|
||||
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - SAE1393层接收函数,此函数需要在BMS处理层主循环内调用,处理报文的接收和多包报文的发送,也处理1393层的超时事件
|
||||
*
|
||||
* @param[in] pt_dll_data - 1393层控制数据
|
||||
* @param[in] pt_can_data - CAN解析存储数据
|
||||
* @param[in] t_rx_msg - 接收CAN数据-原报文数据
|
||||
*
|
||||
* @return U32_T - 1说明接收完整帧 0未接收完整帧
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-08-13
|
||||
* ************************************************************************
|
||||
*/
|
||||
U32_T u32_sae1393_rx(DLL_DATA_T *pt_dll_data, CAN_DATA_T *pt_can_data, CAN_DATA t_rx_msg)
|
||||
{
|
||||
CAN_DATA t_tx_msg;
|
||||
U32_T u32_ret = 0;
|
||||
U32_T i, u32_pgn,u32_data;
|
||||
S32_T j;
|
||||
U8_T u8_src_addr, u8_dest_addr, u8_pri, u8_r_dp, u8_data_len;
|
||||
|
||||
u8_pri = ((t_rx_msg.ID & 0x1C000000) >> 26); //优先级
|
||||
u8_r_dp = ((t_rx_msg.ID & 0x03000000) >> 24); //0
|
||||
u32_pgn = ((t_rx_msg.ID & 0x00FF0000) >> 8); //pgn - 是分辨多包使用,而不是bms数据内的bgn
|
||||
u8_src_addr = t_rx_msg.ID & 0xFF; //源地址
|
||||
u8_dest_addr = ((t_rx_msg.ID & 0x0000FF00) >> 8); //目标
|
||||
u8_data_len = t_rx_msg.Len; //数据长度
|
||||
|
||||
(void)u8_r_dp;
|
||||
if (u32_pgn == TP_CM_PGN) //接收帧为多包连接管理帧
|
||||
{
|
||||
if(u8_data_len != 8) //管理帧帧长度都为8
|
||||
return u32_ret;
|
||||
|
||||
switch(t_rx_msg.Data[0])
|
||||
{
|
||||
case TP_CM_RTS: //接收到对方发送的请求发送报文,回复CTS(允许发送)
|
||||
if ((pt_dll_data->e_msg_state == NONE) || //一级 状态为空闲时,直接接收
|
||||
(((pt_dll_data->e_msg_state == RX_WAIT_DATA_T2) || (pt_dll_data->e_msg_state == RX_WAIT_DATA_T1)) && //一级 接收状态下 重复接收相同帧
|
||||
(pt_dll_data->u32_pgn == ((t_rx_msg.Data[7]<<16) | (t_rx_msg.Data[6]<<8) | t_rx_msg.Data[5])) && //二级 接受帧pgn与正在接受的数据相同
|
||||
(pt_dll_data->u8_src_addr == u8_src_addr) && (pt_dll_data->u8_dest_addr == u8_dest_addr))) //二级 接收帧 目标地址和发送地址相同
|
||||
{
|
||||
//回复CTS
|
||||
u32_data = (U32_T)((t_rx_msg.Data[7]<<16) | (t_rx_msg.Data[6]<<8) | t_rx_msg.Data[5]);
|
||||
v_sae1939_cts_send(t_rx_msg.ID ,u32_data, t_rx_msg.Data[3],1, &t_tx_msg);
|
||||
|
||||
if (pt_dll_data->u32_can_tx(&t_tx_msg) == 0) //发送成功
|
||||
{
|
||||
pt_dll_data->e_msg_state = RX_WAIT_DATA_T2;
|
||||
pt_dll_data->u32_time = u32_delay_get_timer_val();
|
||||
|
||||
pt_dll_data->u32_pgn = (t_rx_msg.Data[7]<<16) | (t_rx_msg.Data[6]<<8) | t_rx_msg.Data[5]; //记录接收多包报文的pgn,有多个多包时也先收此pgn
|
||||
pt_dll_data->u8_src_addr = u8_src_addr;
|
||||
pt_dll_data->u8_dest_addr = u8_dest_addr;
|
||||
pt_dll_data->u8_pri = u8_pri;
|
||||
pt_dll_data->u16_len = ((U16_T)(t_rx_msg.Data[2])<<8) | t_rx_msg.Data[1];
|
||||
pt_dll_data->u8_packet_cnt = t_rx_msg.Data[3];
|
||||
pt_dll_data->u8_retry = 0;
|
||||
|
||||
//等待接收数据,将缓存区置0xFF
|
||||
for (i=0; i<SAE1939_MULTI_PACKET_MAX_NUM; i++)
|
||||
{
|
||||
memset(pt_dll_data->t_packet[i].u8_data, 0xFF, 7);
|
||||
pt_dll_data->t_packet[i].u8_flag = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else //放弃连接
|
||||
{
|
||||
//回复Abort
|
||||
u32_data = (U32_T)((t_rx_msg.Data[7]<<16) | (t_rx_msg.Data[6]<<8) | t_rx_msg.Data[5]);
|
||||
v_sae1939_abort_send(t_rx_msg.ID , u32_data, &t_tx_msg);
|
||||
|
||||
pt_dll_data->u32_can_tx(&t_tx_msg);
|
||||
|
||||
pt_dll_data->e_msg_state = NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
case TP_CM_ABORT: //结束应答
|
||||
if ((pt_dll_data->e_msg_state == RX_WAIT_DATA_T2) ||
|
||||
(pt_dll_data->e_msg_state == RX_WAIT_DATA_T1))
|
||||
{
|
||||
if ((u8_src_addr == pt_dll_data->u8_src_addr) &&
|
||||
(pt_dll_data->u8_dest_addr == u8_dest_addr) &&
|
||||
(pt_dll_data->u32_pgn == ((t_rx_msg.Data[7]<<16) | (t_rx_msg.Data[6]<<8) | t_rx_msg.Data[5])))
|
||||
{
|
||||
pt_dll_data->e_msg_state = NONE;
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (u32_pgn == TP_DT_PGN) //接收多包数据帧
|
||||
{
|
||||
if ((t_rx_msg.Len == 8) && //长度为8
|
||||
(pt_dll_data->u8_src_addr == u8_src_addr) && (pt_dll_data->u8_dest_addr == u8_dest_addr) && //接收报文目标、发送地址与报存的一致
|
||||
((pt_dll_data->e_msg_state == RX_WAIT_DATA_T2) || (pt_dll_data->e_msg_state == RX_WAIT_DATA_T1)) && //正在接收多包数据状态下
|
||||
(t_rx_msg.Data[0] != 0)) //包序号不为0
|
||||
{
|
||||
pt_dll_data->e_msg_state = RX_WAIT_DATA_T1;
|
||||
pt_dll_data->u32_time = u32_delay_get_timer_val();
|
||||
pt_dll_data->t_packet[t_rx_msg.Data[0]-1].u8_flag = 1;
|
||||
memcpy(pt_dll_data->t_packet[t_rx_msg.Data[0]-1].u8_data, &(t_rx_msg.Data[1]), 7);
|
||||
|
||||
for (i=0; i<pt_dll_data->u8_packet_cnt; i++) //找到未接收的包,即下一个要求上送的包
|
||||
{
|
||||
if (pt_dll_data->t_packet[i].u8_flag == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
//多包数据接收完成
|
||||
if (i >= pt_dll_data->u8_packet_cnt)
|
||||
{
|
||||
pt_dll_data->e_msg_state = NONE;
|
||||
|
||||
u32_ret = 1;
|
||||
pt_can_data->u32_pgn = pt_dll_data->u32_pgn;
|
||||
pt_can_data->u8_src_addr = u8_src_addr;
|
||||
pt_can_data->u8_dest_addr = u8_dest_addr;
|
||||
pt_can_data->u8_pri = u8_pri;
|
||||
pt_can_data->u16_len = pt_dll_data->u16_len;
|
||||
|
||||
if (pt_can_data->u16_len > (SAE1939_MULTI_PACKET_MAX_NUM*7))
|
||||
pt_can_data->u16_len = (SAE1939_MULTI_PACKET_MAX_NUM*7);
|
||||
for (i=0; i<pt_can_data->u16_len; i++)
|
||||
pt_can_data->u8_data[i] = pt_dll_data->t_packet[i/7].u8_data[i%7];
|
||||
|
||||
//发送EndofMsgACK
|
||||
v_sae1939_EndofMsgACK_send(pt_dll_data,&t_tx_msg);
|
||||
pt_dll_data->u32_can_tx(&t_tx_msg);
|
||||
}
|
||||
else if (pt_dll_data->t_packet[pt_dll_data->u8_packet_cnt-1].u8_flag == 1) //有包未接收,但是最后一包接收了,说明有丢包的 则重新申请丢的包
|
||||
{
|
||||
pt_dll_data->e_msg_state = RX_WAIT_DATA_T2;
|
||||
pt_dll_data->u32_time = u32_delay_get_timer_val();
|
||||
for (j=pt_dll_data->u8_packet_cnt-1; j>=0; j--)
|
||||
{
|
||||
if (pt_dll_data->t_packet[j].u8_flag == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
//回复CTS
|
||||
u32_data = pt_dll_data->u32_pgn;
|
||||
t_rx_msg.ID = (t_rx_msg.ID & 0xFF00FFFF)|(TP_CM_PGN << 8); //将帧ID PGN赋值为0xEC
|
||||
v_sae1939_cts_send(t_rx_msg.ID ,u32_data, j-i+1,i+1, &t_tx_msg);
|
||||
|
||||
pt_dll_data->u32_can_tx(&t_tx_msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else //单包数据
|
||||
{
|
||||
u32_ret = 1; //返回解析成功
|
||||
pt_can_data->u32_pgn = u32_pgn;
|
||||
pt_can_data->u8_src_addr = u8_src_addr;
|
||||
pt_can_data->u8_dest_addr = u8_dest_addr;
|
||||
pt_can_data->u8_pri = u8_pri;
|
||||
pt_can_data->u16_len = t_rx_msg.Len;
|
||||
for (i=0; i<t_rx_msg.Len; i++)
|
||||
pt_can_data->u8_data[i] = t_rx_msg.Data[i];
|
||||
}
|
||||
|
||||
#if 1
|
||||
//超时处理
|
||||
switch (pt_dll_data->e_msg_state)
|
||||
{
|
||||
case RX_WAIT_DATA_T2:
|
||||
if (u32_delay_time_elapse(pt_dll_data->u32_time, u32_delay_get_timer_val()) > TIMEOUT_T2)
|
||||
{
|
||||
//回复Abort
|
||||
u32_data = ((U32_T)(pt_dll_data->u8_pri & 0x07) << 26);
|
||||
u32_data |= ((TP_CM_PGN & 0x0000FF00) << 8);
|
||||
u32_data |= ((U32_T)(pt_dll_data->u8_src_addr) <<8 );
|
||||
u32_data |= pt_dll_data->u8_dest_addr;
|
||||
v_sae1939_abort_send(u32_data , pt_dll_data->u32_pgn, &t_tx_msg);
|
||||
|
||||
pt_dll_data->u32_can_tx(&t_tx_msg);
|
||||
|
||||
pt_dll_data->e_msg_state = NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
case RX_WAIT_DATA_T1:
|
||||
if (u32_delay_time_elapse(pt_dll_data->u32_time, u32_delay_get_timer_val()) > TIMEOUT_T1)
|
||||
{
|
||||
//回复Abort
|
||||
u32_data = ((U32_T)(pt_dll_data->u8_pri & 0x07) << 26);
|
||||
u32_data |= ((TP_CM_PGN & 0x0000FF00) << 8);
|
||||
u32_data |= ((U32_T)(pt_dll_data->u8_src_addr) <<8 );
|
||||
u32_data |= pt_dll_data->u8_dest_addr;
|
||||
v_sae1939_abort_send(u32_data , pt_dll_data->u32_pgn, &t_tx_msg);
|
||||
|
||||
pt_dll_data->u32_can_tx(&t_tx_msg);
|
||||
|
||||
pt_dll_data->e_msg_state = NONE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return u32_ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
#ifndef SAE1939_H
|
||||
#define SAE1939_H
|
||||
|
||||
#ifdef __cplusplus /*C++编译环境下兼容C语言*/
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------ Exported includes(头文件) ----------------------*/
|
||||
#include "main.h"
|
||||
#include "bsp_include.h"
|
||||
|
||||
/*------ Exported macro(宏定义) -------------------------*/
|
||||
#define SAE1939_MULTI_PACKET_MAX_NUM 80 //80*7 -- bmv需要512字节
|
||||
|
||||
typedef U32_T (*U32_CAN_RX)(CAN_DATA *s_canData);
|
||||
typedef U32_T (*U32_CAN_TX)(CAN_DATA *s_canData);
|
||||
|
||||
/*------ Exported struct(结构体定义) --------------------*/
|
||||
typedef struct
|
||||
{
|
||||
U32_T u32_pgn; //参数组编号
|
||||
U8_T u8_src_addr; //源地址
|
||||
U8_T u8_dest_addr; //目标地址
|
||||
U8_T u8_pri; //优先级
|
||||
U16_T u16_len; //长度,不能大于SAE1939_MULTI_PACKET_MAX_NUM*7
|
||||
U8_T u8_data[SAE1939_MULTI_PACKET_MAX_NUM*7]; //数据
|
||||
}CAN_DATA_T;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NONE=0, //无多包发送和接收
|
||||
|
||||
// //作为多包发送方使用
|
||||
// TX_WAIT_CTS_T3, //己发送RTS,等待接收CTS,超时T3=1250ms
|
||||
// TX_WAIT_CTS_T4, //等待接收保持连接CTS,超时T4=1050ms
|
||||
|
||||
//作为多包接收方使用
|
||||
RX_WAIT_DATA_T2, //己发送CTS,等待接收数据,超时T2=1250ms
|
||||
RX_WAIT_DATA_T1, //接收数据阶段,等待接收下一个数据包,超时T1=750ms
|
||||
}MULTI_MSG_STATE_E;
|
||||
//此数据结构在BMS通信开始化进行初始化,初始化完成后BMS层不能再修改此结构
|
||||
typedef struct
|
||||
{
|
||||
MULTI_MSG_STATE_E e_msg_state; //多包解析流程状态
|
||||
U8_T u8_packet_cnt; //包数量
|
||||
|
||||
U8_T u8_src_addr; //源地址
|
||||
U8_T u8_dest_addr; //目标地址
|
||||
U8_T u8_pri; //优先级
|
||||
|
||||
U8_T u8_retry; //重试次数
|
||||
|
||||
U16_T u16_len; //长度,不能大于 80*7
|
||||
|
||||
U32_T u32_pgn; //参数组编号
|
||||
U32_T u32_time; //用于多包数据处理的计时
|
||||
|
||||
struct
|
||||
{
|
||||
U8_T u8_data[7]; //数据
|
||||
U8_T u8_flag; //标记,0:未接收或未发送,1:己接收或己发送
|
||||
}t_packet[SAE1939_MULTI_PACKET_MAX_NUM];
|
||||
|
||||
|
||||
U32_CAN_TX u32_can_tx; //驱动层发送函数
|
||||
U32_CAN_RX u32_can_rx; //驱动层接收函数 - 从缓冲区里读,不只接收一帧
|
||||
}DLL_DATA_T;
|
||||
|
||||
/*------ Exported variables(变量定义) -------------------*/
|
||||
|
||||
/*------ Exported function prototypes (函数声明) -------*/
|
||||
|
||||
void v_sae1393_clear_multi_pacet(DLL_DATA_T *pt_dll_data);
|
||||
U32_T u32_sae1393_tx(DLL_DATA_T *pt_dll_data, CAN_DATA_T *pt_can_data);
|
||||
U32_T u32_sae1393_rx(DLL_DATA_T *pt_dll_data, CAN_DATA_T *pt_can_data, CAN_DATA t_rx_msg);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* SAE1939_H */
|
||||
Reference in New Issue
Block a user