9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
2110 lines
87 KiB
C
2110 lines
87 KiB
C
#include "flowctrl/flowctrl_task.h"
|
|
|
|
#include "app_init/app_init.h"
|
|
#include "app_init/task_lock.h"
|
|
#include "mylog/mylog.h"
|
|
#include "publicdata/publicdata.h"
|
|
#include "app_rtc/app_rtc.h"
|
|
#include "wdt_task/wdt_task.h"
|
|
|
|
#define FLOWCTRL_TASK_ID (TASK_ID_FlowCtrl)
|
|
#define FLOWCTRL_SLEEP_TIME_MS() (MY_GET_SLEEP_TIME(FLOWCTRL_TASK_ID))
|
|
#define FLOWCTRL_LOCK_INIT() (u8_task_lock_ctrl(FLOWCTRL_TASK_ID, TASK_LOCK_OP_INIT))
|
|
#define FLOWCTRL_LOCK_TAKE() (u8_task_lock_ctrl(FLOWCTRL_TASK_ID, TASK_LOCK_OP_TAKE))
|
|
#define FLOWCTRL_LOCK_GIVE() (u8_task_lock_ctrl(FLOWCTRL_TASK_ID, TASK_LOCK_OP_GIVE))
|
|
#define FLOWCTRL_FEED_DOG() (v_wdt_setFlag(FLOWCTRL_TASK_ID))
|
|
|
|
const char flow_real_mag[][30] =
|
|
{
|
|
"IDLE ",
|
|
"CHG START ",
|
|
"INS START ",
|
|
"INS DONE ",
|
|
"INS MDU STOP ",
|
|
"PRECHG START ",
|
|
"PRECHG DONE ",
|
|
"CHARGING ",
|
|
"BMS TIMEOUT ",
|
|
"CHG STOP ",
|
|
"CHG STOP OK ",
|
|
};
|
|
|
|
S_FLOW_DATA s_flow_data;
|
|
|
|
#define TEST_FLOW_NO_DCU (0) //测试标志 - 无DCU测试 主要是不判断绝缘监测和采集电压
|
|
|
|
#if 1 //公共逻辑使用
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制状态 跳转
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
* @param[in] e_state - 跳转后状态
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_state_change(U8_T u8_gunNo, E_FLOW_STATE e_state)
|
|
{
|
|
S_FLOW_REAL_DATA *s_data = &s_flow_data.s_real_data[u8_gunNo];
|
|
|
|
if(s_data->e_flow_state != e_state)
|
|
{
|
|
FLOWCTRL_LOG("State chg: %d -> %d\n", s_data->e_flow_state, e_state);
|
|
|
|
s_data->e_flow_state = e_state; //状态赋值
|
|
s_data->u16_anti_shake_cnt = 0; //防抖计数清零
|
|
s_data->u16_anti_shake_cnt2 = 0; //防抖计数清零
|
|
|
|
s_data->ulong_flow_timer = get_current_seconds(); //状态跳转时间赋值
|
|
|
|
// 防止 s_over_time 初值为0/陈旧值导致首次判定直接超时
|
|
{
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo];
|
|
U32_T now_s = s_data->ulong_flow_timer;
|
|
s_ctrl_data->s_over_time.u32_trickle_limit_time = now_s;
|
|
s_ctrl_data->s_over_time.u32_dc_km_time = now_s;
|
|
s_ctrl_data->s_over_time.u32_mdu_free_time = now_s;
|
|
s_ctrl_data->s_over_time.u32_over_vol_time = now_s;
|
|
s_ctrl_data->s_over_time.u32_under_vol_time = now_s;
|
|
s_ctrl_data->s_over_time.u32_over_curr_time = now_s;
|
|
s_ctrl_data->s_over_time.u32_over_needCur_time = now_s;
|
|
s_ctrl_data->s_over_time.u32_over_needCur_max_time = now_s;
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程对外实时状态 跳转
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
* @param[in] e_state - 跳转后状态
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_real_state_change(U8_T u8_gunNo, E_FLOW_REAL_STATE e_state)
|
|
{
|
|
S_FLOW_REAL_DATA *s_data = &s_flow_data.s_real_data[u8_gunNo];
|
|
|
|
if(s_data->e_flow_real_state != e_state)
|
|
{
|
|
FLOWCTRL_LOG("Ext st chg: %d %s -> %d %s\n", s_data->e_flow_real_state,
|
|
flow_real_mag[s_data->e_flow_real_state], e_state , flow_real_mag[e_state]);
|
|
s_data->e_flow_real_state = e_state; //状态赋值
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 流程控制任务 空闲状态 枪锁动作检查
|
|
*
|
|
* @param[in] u8_gunNo - 抢号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_free_gunlock_check(U8_T u8_gunNo)
|
|
{
|
|
if (!(s_flow_data.u8_gun_type[u8_gunNo] == 0)) /* 国标枪:枪锁检查 */
|
|
{
|
|
static U8_T u8_flag = 0; //确保每个周期只执行一次
|
|
|
|
U8_T u8_gunlock_en = u16_flow_get_sys_data(0,E_FLOW_GET_DATA_GUNLOCK_EN,0); //枪锁使能 0不使能 1使能
|
|
U8_T u8_gunlock_st = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_LOCK,0); //枪锁状态 0未锁 1已锁
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo];
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
|
|
U16_T u16_batt_adc_vol;
|
|
|
|
if(u8_gunlock_en && u8_gunlock_st) //枪锁使能并且枪锁为锁的
|
|
{
|
|
if(s_ctrl_data->u8_gunlock_cnt < s_flow_data.u8_gunlock_num) //动作次数小于规定动作次数
|
|
{
|
|
u16_batt_adc_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_BATT_ADC_VOL,0); //电池外侧采集电压 精度 0.1V
|
|
if(u16_batt_adc_vol < s_flow_data.u16_insul_before_vol || //外侧电压小于60V 才做解锁
|
|
u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= 5) //状态 跳转过来大于5秒
|
|
{
|
|
if((s_flow_data.u16_timer_cnt/NUM_1000) % 4 == 0 ) //4秒一次 且取余4的为0
|
|
{
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_GUN_LOCK,1,1); //枪锁上锁
|
|
u8_flag = 1;
|
|
}
|
|
else if((s_flow_data.u16_timer_cnt/NUM_1000) % 4 == 2 ) //4秒一次 且取余4为2
|
|
{
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_GUN_LOCK,0,0); //枪锁解锁
|
|
if(u8_flag == 1)
|
|
{
|
|
u8_flag = 0;
|
|
s_ctrl_data->u8_gunlock_cnt++; //枪锁动作次数+1
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//枪锁解锁失败 做什么?
|
|
//v_set_fault_data(u8_gunNo+1,E_FAULT,E_FAULT_13011,1,*u8_cnt,0); //告警 解枪锁失败 拔枪恢复
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->u8_gunlock_cnt = 0; //解锁成功 计数清零
|
|
|
|
if(u16_flow_get_sys_data(u8_gunNo+1,E_FLOW_GET_DATA_FAULT_FLAG,E_FAULT_13011)) //获取故障内容存在标志 0不存在 1存在;需要传入 故障代码参数)
|
|
{
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_RES, E_FAULT_13011, 0, 0, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 流程控制任务 计时计数累加
|
|
*
|
|
* @param[in] u16_sleep_time - 周期值 ms
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_timer_add(U16_T u16_sleep_time)
|
|
{
|
|
U8_T i;
|
|
|
|
//周期累加计数 单位ms 注意计数为周期值累加,使用时为周期值的倍数
|
|
if(s_flow_data.u16_timer_cnt < 0xFF00)
|
|
s_flow_data.u16_timer_cnt += u16_sleep_time;
|
|
else
|
|
s_flow_data.u16_timer_cnt = 0;
|
|
|
|
|
|
for (i = 0; i < s_flow_data.u8_gunCnt; i++)
|
|
{
|
|
//防抖计数 累加
|
|
if(s_flow_data.s_real_data[i].u16_anti_shake_cnt < 0xFF00)
|
|
s_flow_data.s_real_data[i].u16_anti_shake_cnt += u16_sleep_time;
|
|
else
|
|
s_flow_data.s_real_data[i].u16_anti_shake_cnt = 0;
|
|
|
|
if(s_flow_data.s_real_data[i].u16_anti_shake_cnt2 < 0xFF00)
|
|
s_flow_data.s_real_data[i].u16_anti_shake_cnt2 += u16_sleep_time;
|
|
else
|
|
s_flow_data.s_real_data[i].u16_anti_shake_cnt2 = 0;
|
|
|
|
//故障计数倒计时 累减
|
|
if(s_flow_data.s_ctrl_data[i].s16_fault_stop_cnt >= u16_sleep_time)
|
|
s_flow_data.s_ctrl_data[i].s16_fault_stop_cnt -= u16_sleep_time;
|
|
else if(s_flow_data.s_ctrl_data[i].s16_fault_stop_cnt >= 0)
|
|
s_flow_data.s_ctrl_data[i].s16_fault_stop_cnt = 0;
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电枪限制功率检查 充电枪有功率限制时,计算当前需求功率是否超过限制功率,若超过则根据当前需求电压计算出限制电流,并更新需求电流为限制电流
|
|
*
|
|
* @param[in] u8_gunNo - 抢号 0-N
|
|
* @param[in] u16_need_vol - BMS需求电压 单位0.1V
|
|
* @param[in] u16_need_cur - BMS需求电流 单位0.1A
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2026-03-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_check_gun_power_limit(U8_T u8_gunNo,U16_T *u16_need_vol,U16_T *u16_need_cur)
|
|
{
|
|
U16_T u16_gun_power_limit = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_POWER_LIMIT,0); //充电枪的限制功率值 单位kW 0表示不限制
|
|
U16_T u16_meter_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_VOL,0); //电表采集电压 精度0.1V
|
|
|
|
if(u16_gun_power_limit != 0)
|
|
{
|
|
U32_T u32_need_power = (*u16_need_vol) * (*u16_need_cur) / 100; //计算需求功率 单位W
|
|
if(u16_meter_vol != 0 && u32_need_power > (U32_T)u16_gun_power_limit * 1000) //需求功率大于限制功率才进行限制计算
|
|
{
|
|
U32_T u32_limit_cur = (U32_T)(u16_gun_power_limit * 100000) / (u16_meter_vol); //根据限制功率和电表电压计算限制电流 单位0.1A
|
|
if(u32_limit_cur < *u16_need_cur)
|
|
{
|
|
// FLOWCTRL_LOG("Gun%d pwr limit on, limit=%d kW, reqI=%d.%d->%d.%d A\n",
|
|
// u8_gunNo,u16_gun_power_limit,*u16_need_cur/10,*u16_need_cur%10,u32_limit_cur/10,u32_limit_cur%10);
|
|
*u16_need_cur = u32_limit_cur; //更新需求电流为限制电流
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if 1 //充电订单信息管理
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电订单信息管理 充电启停时触发
|
|
*
|
|
* @param[in] u8_gunNo - 抢号
|
|
* @param[in] u8_flag - 标志 0充电停止 1充电启动 2充电中计算充电时间
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-11
|
|
* ************************************************************************
|
|
*/
|
|
void v_flow_log_info_ctrl(U8_T u8_gunNo,U8_T u8_flag)
|
|
{
|
|
S_FLOW_LOG_DATA *s_flow_log = &s_flow_data.s_log_data[u8_gunNo];
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo];
|
|
Comm_Time rel_time;
|
|
U32_T u32_time;
|
|
|
|
GetCurrentTime(&rel_time);
|
|
|
|
u32_time = xDate2Seconds(&rel_time);
|
|
|
|
if(u8_flag == 0) //停止充电
|
|
{
|
|
s_flow_log->u32_stop_time = u32_time;
|
|
s_flow_log->u_stop_res = s_real_data->e_stop_reason[0];
|
|
v_flow_set_stop_log_info(u8_gunNo , s_flow_log->u_stop_res);
|
|
}
|
|
else if(u8_flag == 1) //启动充电
|
|
{
|
|
memset(s_flow_log, 0, sizeof(S_FLOW_LOG_DATA));
|
|
s_flow_log->u32_satrt_time = u32_time;
|
|
}
|
|
else{
|
|
if(s_flow_log->u32_satrt_time != 0 &&
|
|
s_flow_log->u32_stop_time == 0)
|
|
{
|
|
// s_flow_log->u16_char_time = u32_time - s_flow_log->u32_satrt_time;
|
|
// if(s_flow_log->u16_char_time > 7200 ) //为检查充电时长跳变问题,充电时长对大于2h,打印当前时间信息
|
|
// {
|
|
// FLOWCTRL_LOG("Chg dur: %u\n",s_flow_log->u16_char_time);
|
|
// FLOWCTRL_LOG("Now: %d-%d-%d %d:%d:%d\n",rel_time.iYear,rel_time.ucMonth,rel_time.ucDay,rel_time.ucHour,rel_time.ucMin,rel_time.ucSec);
|
|
// FLOWCTRL_LOG("Start ts: %u\n",s_flow_log->u32_satrt_time);
|
|
// FLOWCTRL_LOG("Now ts: %u\n",u32_time);
|
|
// }
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if 1 //充电启停相关
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 流程控制任务 停止充电
|
|
*
|
|
* @param[in] u8_gunNo - 抢号 0-N
|
|
* @param[in] e_stop_reason - 停止原因 详看停止原因枚举
|
|
* @param[in] s16_fault_stop_cnt - 故障停止计数 - 用于直流继电器断开时间
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
void v_flow_set_stop_charge(U8_T u8_gunNo , E_FAULT_INFO e_stop_reason , S16_T s16_fault_stop_cnt)
|
|
{
|
|
U8_T i;
|
|
char mag[FAULT_GET_MAG_MAX_LEN] = {0};
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo];
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo];
|
|
|
|
if((s16_fault_stop_cnt != TIMER_SPECIAL_2) &&
|
|
(s_real_data->e_flow_state == E_FLOW_FREE ||
|
|
s_real_data->e_flow_state == E_FLOW_STOP_CHARGE || //已经停止就不再执行了
|
|
s_real_data->e_flow_state == E_FLOW_STOP_CHARGE_OK))
|
|
return;
|
|
|
|
v_flow_get_fault_mag(e_stop_reason , mag,FAULT_GET_MAG_MAX_LEN); //获取停止原因对应故障代码内容 中文
|
|
|
|
FLOWCTRL_LOG("(%d)Gun stop, reason=%d %s\n",u8_gunNo,e_stop_reason,mag);
|
|
|
|
for(i=0;i<5;i++)
|
|
{
|
|
if(s_real_data->e_stop_reason[i] == 0)
|
|
{
|
|
s_real_data->e_stop_reason[i] = e_stop_reason; //充电停止原因
|
|
break;
|
|
}
|
|
}
|
|
|
|
s_ctrl_data->s16_fault_stop_cnt = s16_fault_stop_cnt; //故障停止计数
|
|
|
|
if(s16_fault_stop_cnt == TIMER_SPECIAL_2)
|
|
{
|
|
s_real_data->log_stop_flag = 0;
|
|
}
|
|
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_STOP_CHARGE); //流程跳转到充电停止
|
|
}
|
|
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - vin鉴权失败执行 ,由于会多次用到 单独做一个函数
|
|
*
|
|
* @param[in] u8_gunNo - 抢号 0-N
|
|
* @param[in] u8_flag - 失败原因 2平台鉴权超时 3非法VIN 4车辆识别鉴权帧超时 5即插即充鉴权失败 6鉴权VIN与车辆VIN不一致
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_vin_fail_stop(U8_T u8_gunNo,U8_T u8_flag)
|
|
{
|
|
if(u8_flag != 0)
|
|
FLOWCTRL_LOG("Auth res=%d\n",u8_flag);
|
|
|
|
if(u8_flag == 2) //2平台鉴权超时
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13067, TIMER_NONE ); //停止流程
|
|
}
|
|
else if(u8_flag == 3) //3非法VIN
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13064, TIMER_NONE ); //停止流程
|
|
}
|
|
else if(u8_flag == 4) //4车辆识别鉴权帧超时
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13078, TIMER_NONE ); //停止流程
|
|
}
|
|
else if(u8_flag == 5) //5即插即充鉴权失败
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13067, TIMER_NONE ); //停止流程
|
|
}
|
|
else if(u8_flag == 6) //6鉴权VIN与车辆VIN不一致
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13057, TIMER_NONE ); //停止流程
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 停止命令检查
|
|
*
|
|
* @param[in] u8_gunNo - 抢号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_stop_cmd_check(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo];
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
|
|
if(s_real_data->e_flow_state == E_FLOW_FREE ||
|
|
s_real_data->e_flow_state == E_FLOW_STOP_CHARGE || //已经停止就不再执行了
|
|
s_real_data->e_flow_state == E_FLOW_STOP_CHARGE_OK)
|
|
return;
|
|
|
|
if(s_ctrl_data->e_stop_flag != 0)
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo , s_ctrl_data->e_stop_flag , s_ctrl_data->s16_fault_stop_cnt);
|
|
|
|
s_ctrl_data->e_stop_flag = E_FAULT_NULL; //停止动作完成后 清零
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
#if 1 //充电停止条件、故障信息检查
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电停止条件、故障信息检查
|
|
* 门禁、急停、抢连接中断、过压、过流、欠压、
|
|
* @param[in] u8_gunNo - 抢号
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
void v_flow_stop_fault_check(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo];
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_LOG_DATA *s_log_data = &s_flow_data.s_log_data[u8_gunNo];
|
|
|
|
U16_T u16_data,u16_data1,u16_data2;
|
|
U8_T u8_gunLink = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_LINK,0); //枪连接状态 0未连接 1已连接
|
|
U16_T u16_fault_info = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_FAULT_INFO,0); //获取整桩和该枪首个故障内容 0无故障 详见E_FAULT_INFO枚举内容 -整桩故障也代表本枪无法使用
|
|
|
|
//故障信息检查
|
|
if(u16_fault_info != 0)
|
|
{
|
|
//FLOWCTRL_LOG("Fault in chg=%d\n",u16_fault_info);
|
|
v_flow_set_stop_charge(u8_gunNo, (E_FAULT_INFO)u16_fault_info, TIMER_NONE ); //停止流程 函数内有判定 ,不在充电中,不会置位
|
|
}
|
|
|
|
//启动、充电中枪连接状态检查
|
|
if(s_real_data->e_flow_state > E_FLOW_FREE &&
|
|
s_real_data->e_flow_state <= E_FLOW_STOP_CHARGE)
|
|
{
|
|
//充电中枪连接断开
|
|
if(u8_gunLink == 0) //数据采集时有做防抖 所以在此直接使用;如需增加防抖时间 去采集处修改
|
|
{
|
|
FLOWCTRL_LOG("Gun link lost\n");
|
|
//互操枪连接断开、开关S断开不在此增加直流接触器断开都能过,在接地测试时过不去
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,0,0); //K1K2控制 控制k1k2断开 -- 故障停止、计时结束后立马控制k1k2断开
|
|
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13016, TIMER_0ms ); //停止流程 充电枪连接断开
|
|
}
|
|
}
|
|
|
|
//空闲时,直流输出接触器粘连故障检测
|
|
if(s_real_data->e_flow_state == E_FLOW_FREE)
|
|
{
|
|
|
|
}
|
|
//充电中故障状态检查
|
|
else if(s_real_data->e_flow_state == E_FLOW_CHARGE_RUNING) //充电
|
|
{
|
|
//充电限制条件达标检查 - 限制电量、限制SOC、限制时长等
|
|
switch (s_ctrl_data->e_sdk_chargMode)
|
|
{
|
|
case E_SDK_CHGMOD_MONEY: //限制金额,u32_limit_data 单位 0.01 元;计量为 0.0001 元
|
|
{
|
|
U32_T u32_used_money = ((U32_T)u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_METER_CHARGE, 1) << 16)
|
|
| (U32_T)u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_METER_CHARGE, 0);
|
|
U32_T u32_next_cyc = ((U32_T)u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_METER_CHARGE, 3) << 16)
|
|
| (U32_T)u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_METER_CHARGE, 2);
|
|
|
|
if (s_ctrl_data->u32_limit_data != 0
|
|
&& (U64_T)s_ctrl_data->u32_limit_data * 100u <= (U64_T)u32_used_money + (U64_T)u32_next_cyc)
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_NORMAL_1005, TIMER_0ms ); //停止流程 达到限值金额
|
|
}
|
|
break;
|
|
|
|
}
|
|
case E_SDK_CHGMOD_ELE: //限制电量
|
|
{
|
|
if(s_ctrl_data->u32_limit_data != 0
|
|
&& s_ctrl_data->u32_limit_data*1000 <= u32_flow_put_data(u8_gunNo,E_FLOW_PUT_DATA_USED_ENERGY))//已充电量大于等于限值电量
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_NORMAL_1004, TIMER_0ms ); //停止流程 达到限值电量
|
|
}
|
|
break;
|
|
}
|
|
case E_SDK_CHGMOD_SOC:
|
|
{
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_SOC,0); //获取车辆SOC
|
|
if(s_ctrl_data->u32_limit_data != 0 //SOC限值不为0
|
|
&& s_ctrl_data->u32_limit_data <= u16_data ) //车辆SOC大于等于SOC限值
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_NORMAL_1007, TIMER_0ms ); //停止流程 达到SOC阈值
|
|
}
|
|
break;
|
|
}
|
|
case E_SDK_CHGMOD_TIME:
|
|
{
|
|
if(s_ctrl_data->u32_limit_data != 0 //时间限值不为0
|
|
&& s_ctrl_data->u32_limit_data <= u32_safe_seconds_since(s_log_data->u32_satrt_time)/60)//充电时间大于限值时间
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_NORMAL_1003, TIMER_0ms ); //停止流程 达到时间限值
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
|
|
//SOC阈值达标检查-- 此检查为充电系统设置SOC限制值,和充电下发的限值判断不一样
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_SOC,0); //获取车辆SOC
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_SOC_LIMIT,0); //获取设备SOC限值
|
|
if(u16_data != 0 && u16_data1 != 0 && u16_data >= u16_data1) //车辆SOC大于等于设备SOC的限值
|
|
{
|
|
u16_data2 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_TRICKLE_LIMIT,0); //获取涓流停机阈值
|
|
if(u16_data2 != 0 && u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0) < u16_data2) //输出电流小于涓流限值
|
|
{
|
|
if(u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_trickle_limit_time) > NUM_60) //处于该阶段一分钟
|
|
{
|
|
FLOWCTRL_LOG("Trickle stop, SOC_th=%d, I_trk_th=%d\n",u16_data1,u16_data2);
|
|
v_flow_set_stop_charge(u8_gunNo, E_NORMAL_1016, TIMER_0ms ); //停止流程 达到SOC阈值,涓流充电停机
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_trickle_limit_time = get_current_seconds(); //更新计算超时起始时间
|
|
FLOWCTRL_LOG("SOC stop, SOC=%d, th=%d\n",u16_data,u16_data1);
|
|
v_flow_set_stop_charge(u8_gunNo, E_NORMAL_1007, TIMER_0ms ); //停止流程 达到SOC阈值
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_trickle_limit_time = get_current_seconds(); //更新计算超时起始时间
|
|
}
|
|
|
|
//枪锁检查(仅国标枪,u8_gun_type 0欧标 1国标)
|
|
if (s_flow_data.u8_gun_type[u8_gunNo] != 0)
|
|
{
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUNLOCK_EN,0); //枪锁使能状态
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_LOCK,0); //充电枪电子锁状态
|
|
if(u16_data == 1 && u16_data1 == 0) //枪锁使能且充电枪电子锁解锁
|
|
{
|
|
FLOWCTRL_LOG("E-lock unlock in chg\n");
|
|
v_flow_set_fault_data(u8_gunNo+1,E_FAULT,E_FAULT_13010,1,0,0);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13010, TIMER_0ms ); //停止流程 枪锁异常解锁
|
|
}
|
|
}
|
|
|
|
//充电中检测到模块运行状态为空闲 3分钟
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_VOL,0); //电表采集电压
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0); //电表采集电流
|
|
if(u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_MDU_WORK,0) == 0 //模块工作状态变为空闲
|
|
&& u16_data < 100 && u16_data1 < 100) //电表采集到的电压小于10V,电流小于10A
|
|
{
|
|
if(u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_mdu_free_time) > 3*NUM_60) //3分钟延时
|
|
{
|
|
FLOWCTRL_LOG("MDU idle in chg\n");
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_FAULT, E_FAULT_13055, 1, 0, 0);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13055, TIMER_0ms ); //停止流程 充电中检测到模块运行状态为空闲
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_mdu_free_time = get_current_seconds();
|
|
}
|
|
|
|
//直流输出过压
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_VOL,0); //电表采集电压
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MAX_VOL,0) + 100;//充电机调压上限+10V
|
|
if(u16_data > u16_data1) //输出电压大于调压上限
|
|
{
|
|
if(u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_over_vol_time) > NUM_5) //5S延时
|
|
{
|
|
FLOWCTRL_LOG("DC OVP\n");
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_FAULT, E_FAULT_13048, 1, u16_data, u16_data1);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13048, TIMER_0ms ); //停止流程 充电中检测到模块运行状态为空闲
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_over_vol_time = get_current_seconds();
|
|
}
|
|
|
|
//直流输出欠压
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_VOL,0); //电表采集电压
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_VOL,0) - 100;//充电机调压下限-10V
|
|
if(s_log_data->u16_char_time > NUM_60 //充电开始1min 后开始判定
|
|
&& u16_data < u16_data1) //输出电压大于调压上限
|
|
{
|
|
if(u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_under_vol_time) > NUM_5) //5S延时
|
|
{
|
|
FLOWCTRL_LOG("DC UVP: V=%dV, Vmin=%dV\n",u16_data,u16_data1);
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_FAULT, E_FAULT_13050, 1, u16_data, u16_data1);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13050, TIMER_0ms ); //停止流程 充电中检测到模块运行状态为空闲
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_under_vol_time = get_current_seconds();
|
|
}
|
|
//直流输出过压超过最高允许电压(互操输出电压超过车辆允许值测试,使用电表采集值和延时5S会导致K1K2及CST执行慢)
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_BUS_VOL,0); //电表采集电压(接触器内测电压)
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_MAX_VOL,0) + 100;//充电机调压上限+10V
|
|
if(u16_data > u16_data1) //输出电压大于最高允许电压
|
|
{
|
|
|
|
if(s_flow_data.u8_gb_en == 1 || u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_over_max_vol_time) > NUM_5) //5S延时
|
|
{
|
|
FLOWCTRL_LOG("DC MAX_OVP\n");
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_FAULT, E_FAULT_15037, 1, u16_data, u16_data1);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15037, TIMER_0ms ); //停止流程 充电中检测到模块运行状态为空闲
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_over_max_vol_time = get_current_seconds();
|
|
}
|
|
|
|
|
|
//直流输出过流
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0); //电表采集电流
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MAX_CUR,0) + 50;//充电机电流上限+5V
|
|
if(u32_safe_seconds_since(s_log_data->u32_satrt_time) > NUM_60 //充电开始1min 后开始判定
|
|
&& u16_data > u16_data1) //输出电压大于调压上限
|
|
{
|
|
if(u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_over_curr_time) > NUM_5) //5S防抖延时
|
|
{
|
|
FLOWCTRL_LOG("DC OCP\n");
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_FAULT, E_FAULT_13049, 1, u16_data, u16_data1);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13049, TIMER_0ms ); //停止流程 充电中检测到模块运行状态为空闲
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_over_curr_time = get_current_seconds();
|
|
}
|
|
|
|
//直流输出大于需求
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0); //电表采集电流
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_NEED_CUR,0) + 50;//车辆需求电流+5
|
|
if(u16_data1 != 0 &&u16_data > u16_data1) //采集电流大于车辆需求电流
|
|
{
|
|
if(u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_over_needCur_time) > NUM_5) //5S延时
|
|
{
|
|
FLOWCTRL_LOG("DC out > req\n");
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_FAULT, E_FAULT_13054, 1, u16_data, u16_data1);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13054, TIMER_0ms ); //停止流程 充电中检测到模块运行状态为空闲
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_over_needCur_time = get_current_seconds();
|
|
}
|
|
|
|
//直流电流输出大于需求
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0); //电表采集电流
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_NEED_CUR,0) + 50;//车辆需求电流
|
|
if(u16_data1 != 0 &&u16_data > u16_data1) //输出电压大于调压上限
|
|
{
|
|
if(u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_over_needCur_time) > NUM_5) //5S延时
|
|
{
|
|
FLOWCTRL_LOG("DC out > req\n");
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_FAULT, E_FAULT_13054, 1, u16_data, u16_data1);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13054, TIMER_0ms ); //停止流程 充电中检测到模块运行状态为空闲
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_over_needCur_time = get_current_seconds();
|
|
}
|
|
|
|
//直流输出大于最高允许充电电流
|
|
u16_data = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0); //电表采集电流
|
|
u16_data1 = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_MAX_CUR,0) + 50; //车辆最大允许充电电流
|
|
if(u16_data1 != 0 && u16_data > u16_data1) //输出流大于车辆最大允许充电电流
|
|
{
|
|
if(u32_safe_seconds_since(s_ctrl_data->s_over_time.u32_over_needCur_max_time) > NUM_5) //5S延时
|
|
{
|
|
FLOWCTRL_LOG("DC out > req\n");
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_FAULT, E_FAULT_13054, 1, u16_data, u16_data1);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13054, TIMER_0ms ); //停止流程 充电中检测到模块运行状态为空闲
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_ctrl_data->s_over_time.u32_over_needCur_max_time = get_current_seconds();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if 1 //BMS状态跳转检查
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - bms状态判断及处理
|
|
*
|
|
* @param[in] u8_gunNo - 抢号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_bms_state_cheak(U8_T u8_gunNo)
|
|
{
|
|
//BMS 获取BMS状态 0无 1握手完成 2握手失败 3开始预充 4开始充电 5禁止充电 6停止充电 7报文接收超时
|
|
U8_T u8_state = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_STATE,0);
|
|
U16_T u16_bms_stop = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_STOP_RES,0); //BMS 停止原因 详看E_FAULT_INFO枚举内容 BMS部分
|
|
U16_T u16_bms_cem_send_cnt = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_BMS_CAN_SEND_CNT,0); //BMS 报文发送次数 参数值 0代表cem 1代表csd
|
|
U16_T u16_bms_reconn_flag = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_RECONN_FLAG,0); //BMS 重连标志 0不重连 1重连
|
|
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
|
|
static U8_T u8_state_old[GUN_MAX_CNT] = {0}; //上次状态值 用于判断状态变化
|
|
|
|
if(u8_state != u8_state_old[u8_gunNo]) //状态未变化 不执行
|
|
{
|
|
FLOWCTRL_LOG("[%d] BMS st chg: %d -> %d\n",u8_gunNo,u8_state_old[u8_gunNo],u8_state);
|
|
u8_state_old[u8_gunNo] = u8_state; //更新状态值
|
|
}
|
|
|
|
if(s_real_data->e_flow_state == E_FLOW_FREE ||
|
|
s_real_data->e_flow_state == E_FLOW_STOP_CHARGE || //已经停止就不再执行了
|
|
s_real_data->e_flow_state == E_FLOW_STOP_CHARGE_OK)
|
|
return;
|
|
|
|
if(u8_state == 0xFF) //0xFF表示锁申请失败
|
|
return;
|
|
|
|
if(s_real_data->u8_bms_suspend_flag && u8_state != 5)
|
|
s_real_data->u8_bms_suspend_flag = 0;
|
|
|
|
if(u8_state == 0)
|
|
{
|
|
//流程状态为 等待预充和停止充电之间,bms状态为空闲 则停止充电
|
|
if(s_real_data->e_flow_state >= E_FLOW_WAIT_PRE_CHARGE &&
|
|
s_real_data->e_flow_state < E_FLOW_STOP_CHARGE)
|
|
{
|
|
FLOWCTRL_LOG("Start: BMS idle stop, st=%d\n",s_real_data->e_flow_state);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15002, TIMER_NONE ); //停止流程 充电中bms状态空闲
|
|
}
|
|
}
|
|
else if(u8_state == 1) //握手完成
|
|
{
|
|
s_real_data->u8_bms_chm_flag = 1;
|
|
}
|
|
else if(u8_state == 2) //握手失败
|
|
{
|
|
s_real_data->u8_bms_chm_flag = 2;
|
|
}
|
|
else if(u8_state == 3) //开始预充
|
|
{
|
|
s_real_data->u8_bms_pre_flag = 1;
|
|
//s_real_data->u8_bms_renew_cnt = 0; //bms状态更新 说明重连通讯成功,重连次数清零
|
|
}
|
|
else if(u8_state == 4) //开始充电
|
|
{
|
|
s_real_data->u8_bms_charge_flag = 1;
|
|
}
|
|
else if(u8_state == 5) //禁止充电
|
|
{
|
|
s_real_data->u8_bms_suspend_flag = 1;
|
|
}
|
|
else if(u8_state == 6) //停止充电
|
|
{
|
|
if(s_real_data->u8_bms_stop_flag == 0) //未有停机原因且bms停止 则bms异常
|
|
{
|
|
s_real_data->u8_bms_stop_flag = 1;
|
|
v_flow_set_stop_charge(u8_gunNo, (E_FAULT_INFO)u16_bms_stop, TIMER_NONE ); //停止流程
|
|
}
|
|
}
|
|
else if(u8_state == 7) //报文接收超时
|
|
{
|
|
if(u16_bms_reconn_flag == 0) //报文超时不重连,直接停止充电
|
|
{
|
|
if(s_real_data->u8_bms_stop_flag == 0)
|
|
FLOWCTRL_LOG("RX timeout no reconn, stop\n");
|
|
|
|
s_real_data->u8_bms_stop_flag = 1;
|
|
if(u16_bms_stop == E_FAULT_NULL)
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15032, TIMER_NONE ); //停止流程 BRM 报文数据项异常
|
|
else
|
|
v_flow_set_stop_charge(u8_gunNo, (E_FAULT_INFO)u16_bms_stop, TIMER_NONE ); //停止流程
|
|
}
|
|
else if(s_real_data->u8_bms_renew_cnt < 4) //重连次数 小于3次 0 1 2 //修改为4原因是测试D0.4501项,原来3只会重连2次,故修改为4
|
|
{
|
|
s_real_data->u8_bms_charge_flag = 0; //bms标志清零
|
|
s_real_data->u8_bms_pre_flag = 0;
|
|
|
|
if(s_real_data->u8_bms_renew_ctrl == 0 &&
|
|
u16_bms_cem_send_cnt > 3 ) //CEM报文发送 3条以上
|
|
{
|
|
s_real_data->u8_bms_renew_ctrl = 1;
|
|
FLOWCTRL_LOG("BMS timeout, reconn #%d\n",s_real_data->u8_bms_renew_cnt);
|
|
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_BMS_TIMEOUT); //状态跳转到通讯超时
|
|
|
|
if( s_real_data->u8_bms_renew_cnt < 5)
|
|
s_real_data->u8_bms_renew_cnt++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(s_real_data->u8_bms_renew_cnt == 3)
|
|
FLOWCTRL_LOG("Reconn fail, stop, st=%d\n",s_real_data->e_flow_state);
|
|
|
|
if(u16_bms_stop == E_FAULT_NULL)
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15000, TIMER_NONE ); //停止流程 bms通讯超时
|
|
else
|
|
v_flow_set_stop_charge(u8_gunNo, (E_FAULT_INFO)u16_bms_stop, TIMER_1s ); //停止流程
|
|
|
|
s_real_data->u8_bms_renew_cnt = 0;//三次重连后将重连计数清0
|
|
}
|
|
|
|
}
|
|
else if(u8_state == 8) //数据错误 1s断接触器
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo,E_FAULT_15020 ,TIMER_100ms );
|
|
}
|
|
else
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo,E_FAULT_15000 ,TIMER_1s );
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
#if 1 //充电流程控制
|
|
/**
|
|
* ************************************************************************
|
|
* @brief -充电流程控制执行 空闲执行
|
|
* 检查枪锁解锁状态、检查插枪标志、检查启动标志、清空对外状态
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_free(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
|
|
U8_T u8_gunLink = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_LINK,0); //枪连接状态 0未连接 1已连接
|
|
|
|
if(s_ctrl_data->e_start_flag != 0) //获取启停状态
|
|
{
|
|
if(s_ctrl_data->e_start_flag == CTR_CMD_ONCARD_START) //在线卡启动
|
|
{
|
|
if(s_ctrl_data->u8_gunlock_cnt == 0)
|
|
{
|
|
v_flow_set_plat_vin_up(u8_gunNo); //只发一次
|
|
s_ctrl_data->u8_gunlock_cnt ++;
|
|
FLOWCTRL_LOG("Send plat auth\n");
|
|
}
|
|
U8_T u8_vin_res = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BS_VIN_RES,0); //VIN 鉴权结果 0wu 1成功 2平台鉴权超时 3非法VIN 4车辆识别鉴权帧超时 5即插即充鉴权失败 6鉴权VIN与车辆VIN不一致
|
|
|
|
if(u8_vin_res == 1) //鉴权成功
|
|
{
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_START_CHECK); //状态跳转到启动前检查
|
|
|
|
FLOWCTRL_LOG("Start chg, reason=%d\n",s_ctrl_data->e_start_flag);
|
|
s_ctrl_data->e_start_flag = CTR_CMD_NONE; //启动后清零
|
|
v_flow_log_info_ctrl(u8_gunNo,1); //充电订单控制
|
|
}
|
|
else if(u8_vin_res > 1) /* 平台/本地鉴权已给出失败(如 OCPP Invalid/Blocked → txFlag_autoRwsult=2) */
|
|
{
|
|
FLOWCTRL_LOG("Plat auth fail, res=%u gun=%u\n", (unsigned)u8_vin_res, (unsigned)u8_gunNo);
|
|
s_ctrl_data->e_start_flag = 0;
|
|
s_ctrl_data->u8_gunlock_cnt = 0;
|
|
s_real_data->ulong_flow_timer = 0;
|
|
v_flow_request_ui_idle_recover();
|
|
return;
|
|
}
|
|
else //鉴权中
|
|
{
|
|
//超时判断
|
|
if(s_real_data->ulong_flow_timer == 0) //未记录过时间 则记录当前时间
|
|
s_real_data->ulong_flow_timer = get_current_seconds();
|
|
if(u8_gunLink != 1 || u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_INSULATION) //30秒超时
|
|
{
|
|
FLOWCTRL_LOG("Plat auth wait TO gun=%u link=%u\n", (unsigned)u8_gunNo, (unsigned)u8_gunLink);
|
|
s_ctrl_data->e_start_flag = 0;
|
|
s_ctrl_data->u8_gunlock_cnt = 0;
|
|
s_real_data->ulong_flow_timer = 0;
|
|
v_flow_request_ui_idle_recover();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_START_CHECK); //状态跳转到启动前检查
|
|
|
|
FLOWCTRL_LOG("Start chg, reason=%d\n",s_ctrl_data->e_start_flag);
|
|
s_ctrl_data->e_start_flag = CTR_CMD_NONE; //启动后清零
|
|
v_flow_log_info_ctrl(u8_gunNo,1); //充电订单控制
|
|
}
|
|
}
|
|
else if(u8_gunLink == 1) //已插枪
|
|
{
|
|
if(s_real_data->e_flow_real_state == E_FLOW_REAL_STOP_OK) //插枪 且对外状态不是空闲 应为充电完成未拔枪
|
|
{
|
|
//清空状态
|
|
memset(s_real_data, 0 , sizeof(S_FLOW_REAL_DATA));
|
|
s_real_data->e_flow_real_state = E_FLOW_REAL_STOP_OK;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//清空状态
|
|
memset(s_real_data, 0 , sizeof(S_FLOW_REAL_DATA));
|
|
}
|
|
|
|
v_flow_free_gunlock_check(u8_gunNo); //枪锁状态检查 解枪锁
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 充电启动前检查执行
|
|
* 检查插枪状态、控制枪锁闭合并检查、控制辅源闭合并检查
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_start_check(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
U8_T u8_gunLink = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_LINK,0); //枪连接状态 0未连接 1已连接
|
|
U8_T u8_gunlock_en = u16_flow_get_sys_data(0,E_FLOW_GET_DATA_GUNLOCK_EN,0); //枪锁使能 0不使能 1使能
|
|
U8_T u8_gunlock_st = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_LOCK,0); //枪锁状态 0未锁 1已锁
|
|
U8_T u8_auxPower_en = u16_flow_get_sys_data(0,E_FLOW_GET_DATA_AUXPOWER_EN,0); //辅源状态检测使能
|
|
U8_T u8_auxPower_st = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_AUXPOWER,0); //辅源状态 0未闭合 1闭合
|
|
|
|
if(s_real_data->e_charge_state <= e_gunLink) //检查插枪状态
|
|
{
|
|
if(u8_gunLink == 1)
|
|
{
|
|
if ((s_flow_data.u8_gun_type[u8_gunNo] == 0)) /* 欧标 */
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_bms_hand; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_START_CHECK_OK); //状态跳转到启动前检查
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_CHARGE_START); //对外状态跳转充电启动
|
|
}
|
|
else /* 国标 */
|
|
s_real_data->e_charge_state = e_gunlock; //详细状态跳转
|
|
FLOWCTRL_LOG("Gun link chk ok gun type =%d\n",s_flow_data.u8_gun_type[u8_gunNo]);
|
|
}
|
|
else
|
|
{
|
|
if(s_real_data->u16_anti_shake_cnt++ > TIMER_100ms) //100ms
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13041, TIMER_NONE ); //停止流程 枪连接失败
|
|
}
|
|
}
|
|
}
|
|
else if (!(s_flow_data.u8_gun_type[u8_gunNo] == 0) && s_real_data->e_charge_state == e_gunlock) //国标枪:检查枪锁状态
|
|
{
|
|
if(u8_gunlock_en && u8_gunlock_st == 0) //枪锁使能并且枪锁未连接
|
|
{
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) <= FLOW_TIMEOUT_GUNLOCK) //15秒内 一直尝试上锁
|
|
{
|
|
if((s_flow_data.u16_timer_cnt/NUM_1000) % 2 == 0 ) //2秒一次
|
|
{
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_GUN_LOCK,1,1); //枪锁上锁
|
|
}
|
|
else if((s_flow_data.u16_timer_cnt/NUM_1000) % 2 == 1 ) //2秒一次
|
|
{
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_GUN_LOCK,0,0); //枪锁解锁
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(s_flow_data.u8_gb_en == 1) //国标使能 枪锁失败停止充电
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo,E_FAULT_13010 ,TIMER_NONE ); //充电停止 枪锁失败
|
|
}
|
|
else //国标不使能 枪锁失败后也继续执行
|
|
{
|
|
s_real_data->e_charge_state = e_auxpower; //详细状态跳转
|
|
FLOWCTRL_LOG("GB disabled, skip gunlock\n");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_real_data->e_charge_state = e_auxpower; //详细状态跳转
|
|
FLOWCTRL_LOG("Gunlock chk ok, en[%d]\n",u8_gunlock_en);
|
|
}
|
|
}
|
|
else if(s_real_data->e_charge_state == e_auxpower) //检查辅源控制
|
|
{
|
|
//辅源动作
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_AUXPOWER,1,1); //辅源闭合
|
|
//状态判断
|
|
if(s_flow_data.u8_gb_en == 1 && //国标不使能 不判断这个
|
|
(u8_auxPower_en && (u8_auxPower_st == 0))) //辅源状态使能,并且辅源状态未动作
|
|
{
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) <= FLOW_TIMEOUT_GUNLOCK)
|
|
{
|
|
if(s_flow_data.u16_timer_cnt % 2 == 0 ) //2秒一次
|
|
{
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_AUXPOWER,1,1); //辅源闭合
|
|
}
|
|
}
|
|
else
|
|
{
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_AUXPOWER,0,0); //辅源断开
|
|
v_flow_set_stop_charge(u8_gunNo,E_FAULT_13007 ,TIMER_NONE ); //充电停止 辅源动作失败
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_bms_hand; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_START_CHECK_OK); //状态跳转到启动前检查
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_CHARGE_START); //对外状态跳转充电启动
|
|
FLOWCTRL_LOG("Aux pwr chk ok\n");
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 充电启动前检查完成执行
|
|
* 等待BHM报文接收 并获取赋值绝缘电压值、检查电池测电压小于标准范围,可进行绝缘监测
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_start_check_ok(U8_T u8_gunNo)
|
|
{
|
|
U8_T u8_bms_chm_ok = 0;
|
|
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U16_T u16_gun_max_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MAX_VOL,0); //充电枪最大数据电压值 精度 0.1V
|
|
U16_T u16_gun_min_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_VOL,0); //充电枪最小数据电压值 精度 0.1V
|
|
U16_T u16_gun_min_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_CUR,0); //充电枪最小数据电流值 精度 0.1V
|
|
U16_T u16_bms_max_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_MAX_VOL,0); //BMS 最大充电电压值 精度 0.1V
|
|
U16_T u16_batt_adc_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_BATT_ADC_VOL,0); //电池外侧采集电压 精度 0.1V
|
|
U16_T u16_bms_ver = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_GB_VER,0); //BMS 国标协议版本 0 2011版 1 2015版
|
|
U16_T u16_bus_km = u16_flow_get_sys_data(0,E_FLOW_GET_DATA_BUS_KM,0); //母联接触器状态
|
|
|
|
//BMS状态检查
|
|
if(s_real_data->u8_bms_chm_flag == 1) //bms状态准备就绪 握手成功
|
|
{
|
|
if(u16_bms_max_vol > u16_gun_max_vol) //检查bms值和充电桩最大电压值
|
|
{
|
|
//互操测试:BMS最高允许电压超出桩上限时,不允许进入充电流程
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15045, TIMER_NONE);
|
|
FLOWCTRL_LOG("15045 BMSmax>%d, bms=%d\n", u16_gun_max_vol, u16_bms_max_vol);
|
|
}
|
|
else
|
|
s_real_data->u16_need_vol = u16_bms_max_vol - NUM_50; //BMS最大允许输出电压 - 5V
|
|
|
|
s_real_data->u16_need_cur = u16_gun_min_cur; //系统最小输出电流
|
|
|
|
s_real_data->e_charge_state = e_check_bms_vol; //详细状态跳转
|
|
u8_bms_chm_ok = 1;
|
|
}
|
|
else if (!(s_flow_data.u8_gun_type[u8_gunNo] == 0) && s_real_data->u8_bms_chm_flag == 2) //国标:bms状态准备就绪 握手失败
|
|
{
|
|
s_real_data->u16_need_vol = u16_gun_max_vol - NUM_50; //充电柱最大输出电压 - 5V
|
|
s_real_data->u16_need_cur = u16_gun_min_cur; //充电桩最小输出电流
|
|
|
|
s_real_data->e_charge_state = e_check_bms_vol; //详细状态跳转
|
|
u8_bms_chm_ok = 1; //使能标志
|
|
}
|
|
|
|
//绝缘前电池电压检测
|
|
if(u8_bms_chm_ok == 1)
|
|
{
|
|
if(s_real_data->u16_need_vol >= u16_gun_min_vol) //如果车辆最高允许电压比充电桩最小输出电压大 则正常执行 否则停止充电
|
|
{
|
|
s_real_data->e_charge_state = e_battvol_check; //详细状态跳转
|
|
|
|
if(u16_batt_adc_vol > s_flow_data.u16_insul_before_vol) //外侧电池电压 大于标准
|
|
{
|
|
if(s_real_data->u16_anti_shake_cnt++ > TIMER_100ms) //100ms
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15034, TIMER_NONE ); //停止流程 电池测电压大于标准
|
|
FLOWCTRL_LOG("Batt adcV high=%d\n",u16_batt_adc_vol);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( u16_bus_km == 0 ) //母联接触器断开才运行执行以下流程,
|
|
{
|
|
if(u16_bms_ver >= 1) //2015版国标 控制闭合--非2011版本 都闭合接触器做绝缘
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,1,1); //K1K2控制 控制k1k2闭合
|
|
|
|
s_real_data->e_charge_state = e_insulmdu_check; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_INSUL_BEFORE); //状态跳转到启动前检查
|
|
|
|
FLOWCTRL_LOG("K1K2 on, INS start, Vins=%d\n",s_real_data->u16_need_vol);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15036, TIMER_NONE ); //停止流程 车辆最大电压小于充电桩最小
|
|
}
|
|
}
|
|
|
|
if ((s_flow_data.u8_gun_type[u8_gunNo] == 0)) /* 欧标:超时判断 */
|
|
{
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= 60*2) //按照欧标PLC流程 此状态下最多2分钟左右 一直到BROAA接收到
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15018, TIMER_NONE ); //停止流程 状态跳转失败 理论上不会走到这 赋值 15018 BSM 报文中动力蓄电池绝缘状态异常
|
|
}
|
|
}
|
|
else /* 国标:超时判断 */
|
|
{
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_PCM_STATE) //30秒绝缘电压还未输出稳定
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15018, TIMER_NONE ); //停止流程 状态跳转失败 理论上不会走到这 赋值 15018 BSM 报文中动力蓄电池绝缘状态异常
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 绝缘监测前执行
|
|
* 判断模块是否为运行状态、判断模块输出电压是否达到绝缘电压、30秒未达标超时判断
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_insul_before(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U16_T u16_mdu_state = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_MDU_WORK,0); //获取模块运行状态 0空闲 1工作
|
|
U16_T u16_bus_vol = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_GUN_BUS_VOL,0); //充电枪接触器内侧电压值 精度 0.1V
|
|
U16_T u16_batt_adc_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_BATT_ADC_VOL,0); //电池外侧采集电压 精度 0.1V
|
|
U16_T u16_mdu_put_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_MDU_PUT_VOL,0); //获取模块输出电压值 精度0.1V
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_INSUL_START); //对外状态跳转绝缘开始
|
|
|
|
if(u16_mdu_state == 1) //模块状态变为工作
|
|
{
|
|
s_real_data->e_charge_state = e_insulvol_check; //详细状态跳转
|
|
|
|
if((abs((int)s_real_data->u16_need_vol - u16_bus_vol) < (int)s_flow_data.u16_insul_putvol_range) || //接触器内侧采集电压 达到绝缘电压值
|
|
(abs((int)s_real_data->u16_need_vol - u16_mdu_put_vol) < (int)s_flow_data.u16_insul_putvol_range) || //模块上送输出电压 达到绝缘电压值
|
|
(abs((int)s_real_data->u16_need_vol - u16_batt_adc_vol) < (int)s_flow_data.u16_insul_putvol_range) ) //电池测采集电压 达到绝缘电压值
|
|
{
|
|
s_real_data->e_charge_state = e_insul_ing_ok; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_INSUL_RUNING); //状态跳转到启动前检查
|
|
v_flow_gun_insulation_data_ctrl(u8_gunNo,0); //闭合绝缘监测对地-- 绝缘监测前调用 -- 常规流程是闭合大地再启动解决
|
|
|
|
FLOWCTRL_LOG("INS V ok: %d(adc_in) %d(mdu) %d(adc_out)\n",u16_bus_vol,u16_mdu_put_vol,u16_batt_adc_vol);
|
|
}
|
|
else if(s_flow_data.u8_gb_en == 0 && //国标不使能 且超时时间为15秒
|
|
u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_INSULATION/2)
|
|
{
|
|
s_real_data->e_charge_state = e_insul_ing_ok; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_INSUL_RUNING); //状态跳转到启动前检查
|
|
v_flow_gun_insulation_data_ctrl(u8_gunNo,0); //闭合绝缘监测对地-- 绝缘监测前调用
|
|
|
|
FLOWCTRL_LOG("15s skip V chk: need=%d adc=%d mdu=%d\n",s_real_data->u16_need_vol,u16_bus_vol,u16_mdu_put_vol);
|
|
}
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_INSULATION *2) //30秒绝缘电压还未输出稳定 //测试主机启动太慢
|
|
{
|
|
if(u16_mdu_state == 1) //模块在工作 则是绝缘电压未检测到
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_14036, TIMER_NONE ); //停止流程 绝缘电压未输出到位
|
|
else
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_14020, TIMER_NONE ); //停止流程 模块一直未启动
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 绝缘监测中执行
|
|
* 调用绝缘监测执行函数-等待返回绝缘监测结果、30秒绝缘超时判断
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_insul_runing(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
S8_T s8_data = s8_flow_gun_insulation(u8_gunNo,&s_real_data->u32_insul_Rx,&s_real_data->u32_insul_Ry);
|
|
if(s8_data >= 0) //绝缘检测完成
|
|
{
|
|
s_real_data->e_charge_state = e_insul_mdu_stop; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_INSUL_OK); //状态跳转到绝缘检查完成
|
|
s_real_data->u8_insul_ret = (U8_T)s8_data;
|
|
|
|
FLOWCTRL_LOG("INS res=%d(0F,1OK,2WARN), R+=%d(0.1ohm), R-=%d(0.1ohm)\n",s8_data,s_real_data->u32_insul_Rx,s_real_data->u32_insul_Ry);
|
|
}
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_INSULATION) //30秒绝缘超时
|
|
{
|
|
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15019, TIMER_NONE ); //停止流程 绝缘检测失败 理论上不会走到这 赋值 15019 BSM 报文中连接器连接状态异
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 绝缘监测完成执行
|
|
* 检查模块停止 或者电压下降到标准范围内、执行泄放并检查成功结果、
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_insul_ok(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U16_T u16_mdu_state = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_MDU_WORK,0); //获取模块运行状态 0空闲 1工作
|
|
U16_T u16_bus_vol = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_GUN_BUS_VOL,0); //充电枪接触器内侧电压值 精度 0.1V
|
|
U16_T u16_batt_adc_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_BATT_ADC_VOL,0); //电池外侧采集电压 精度 0.1V
|
|
U16_T u16_mdu_put_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_MDU_PUT_VOL,0); //获取模块输出电压值 精度0.1V
|
|
U16_T u16_bms_ver = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_GB_VER,0); //BMS 国标协议版本 0 2011版 1 2015版
|
|
|
|
S8_T s8_relief_res; //泄放结果
|
|
U8_T u8_vol_down_ok = 0; //电压下降成功标志
|
|
|
|
//设置需求电压电流为0
|
|
s_real_data->u16_need_vol = 0;
|
|
s_real_data->u16_need_cur = 0;
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_INSUL_OK); //对外状态跳转绝缘计算完成
|
|
|
|
//检查模块停止状态 并投切泄放
|
|
if(u16_mdu_state == 0 && //模块状态变为空闲
|
|
(u16_bus_vol < s_flow_data.u16_insul_before_vol || u16_mdu_put_vol < s_flow_data.u16_insul_before_vol)) //模块上送电压 或者 adc采样电压小于100V
|
|
{
|
|
s_real_data->e_charge_state = e_insul_relief; //详细状态跳转
|
|
s8_relief_res = s8_flow_volt_relief_do(u8_gunNo);
|
|
if(s8_relief_res == 1)
|
|
u8_vol_down_ok = 1; //进行下一步
|
|
else if(s8_relief_res == 0)
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13047, TIMER_NONE ); //停止流程 泄放失败
|
|
}
|
|
|
|
//绝缘检测结果检查
|
|
if(u8_vol_down_ok == 1)
|
|
{
|
|
//s_real_data->u8_insul_ret = 1; //测试 屏蔽绝缘
|
|
if(s_real_data->u8_insul_ret == 0) //绝缘检查失败
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13042, TIMER_NONE ); //停止流程 绝缘检测失败
|
|
}
|
|
else
|
|
{
|
|
if(s_real_data->u8_insul_ret == 2) //绝缘告警 告警标志置一
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_WARN, E_FAULT_13043, 1, s_real_data->u32_insul_Rx, s_real_data->u32_insul_Ry); //绝缘检查告警 拔枪恢复
|
|
|
|
s_real_data->e_charge_state = e_wiat_bms_pre; //详细状态跳转
|
|
|
|
v_flow_gun_insulation_data_ctrl(u8_gunNo,1); //控制断开绝缘检测对地-绝缘监测结束后执行
|
|
if(u16_bms_ver >= 1) //2015版国标 控制断开
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,0,0); //控制k1k2断开
|
|
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_WAIT_PRE_CHARGE); //状态跳转到等待预充
|
|
}
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_PCM_STATE) //15秒 模块未停止
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_14021, TIMER_NONE ); //停止流程 绝缘检测模块停止失败
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 等待预充执行
|
|
* 等待BMS状态 变为开始预充,跳转状态 70秒超时判断
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_wait_pre_charge(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_INSUL_MDU_STOP); //对外状态跳转绝缘模块停止完成
|
|
|
|
if ((s_flow_data.u8_gun_type[u8_gunNo] == 0)) /* 欧标:不用等待预充 */
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_batt_vol; //详细状态跳转
|
|
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_PRE_CHARGE_RUNING); //状态跳转到 预充中;跳过预充前检查
|
|
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,1,1); //K1K2控制 控制k1k2闭合
|
|
}
|
|
else /* 国标 */
|
|
{
|
|
if(s_real_data->u8_bms_pre_flag == 1) //bms开始预充
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_batt_vol; //详细状态跳转
|
|
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_PRE_CHARGE_BEFORE); //状态跳转到等待预充
|
|
}
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_PRECHARGE+10) //60+10秒
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15012, TIMER_NONE ); //停止流程 等待BMS状态超时 理论上不会走到这 赋值15012 BSM 报文中单体动力蓄电池电压过高
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 预充前准备执行
|
|
* 判断电池测电压 是否输出到位,是否在充电桩输出范围内、判断电池车电压与BMS发送电压是否误差在5%以内、判断平台即插即充鉴权结果、60秒超时判断
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_pre_charge_before(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U16_T u16_bms_batt_vol = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_BMS_REAL_BATT_VOL,0); //BMS 当前电池电压值 精度 0.1V
|
|
U16_T u16_batt_adc_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_BATT_ADC_VOL,0); //电池外侧采集电压 精度 0.1V
|
|
|
|
U16_T u16_gun_max_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MAX_VOL,0); //充电枪最大数据电压值 精度 0.1V
|
|
U16_T u16_gun_min_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_VOL,0); //充电枪最小数据电压值 精度 0.1V
|
|
U16_T u16_gun_min_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_CUR,0); //充电枪最小数据电流值 精度 0.1V
|
|
|
|
U16_T u16_bms_max_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_MAX_VOL,0); //BMS 最大充电电压值 精度 0.1V
|
|
U16_T u16_bms_ver = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_GB_VER,0); //BMS 国标协议版本 0 2011版 1 2015版
|
|
|
|
U8_T u8_vol_err = 0;
|
|
|
|
if(TEST_FLOW_NO_DCU == 1) u16_batt_adc_vol = u16_bms_batt_vol; //无DCU adc采样时,电池测电压值 直接使用BMS值 模拟测试
|
|
|
|
//电池测电压与标准对比
|
|
if((u16_bms_ver >= 1) && //非2011版国标 判断
|
|
(u16_batt_adc_vol > u16_bms_max_vol || //bms最大允许充电电压)
|
|
u16_batt_adc_vol > u16_gun_max_vol || //大于充电桩最大输出电压
|
|
u16_batt_adc_vol < u16_gun_min_vol )) //小于充电桩最小输出电压
|
|
{
|
|
if(s_real_data->u16_anti_shake_cnt > TIMER_30s) //持续30秒不符合,走停止流程
|
|
{
|
|
if(u16_batt_adc_vol > u16_bms_max_vol) //bms最大允许充电电压)
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15045, TIMER_NONE ); //停止流程
|
|
FLOWCTRL_LOG("15045= %d ,%d\n",u16_batt_adc_vol,u16_bms_max_vol);
|
|
}
|
|
else if(u16_batt_adc_vol > u16_gun_max_vol ) //大于充电桩最大输出电压
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_14037, TIMER_NONE ); //停止流程
|
|
FLOWCTRL_LOG("14037= %d ,%d\n",u16_batt_adc_vol,u16_gun_max_vol);
|
|
}
|
|
else if(u16_batt_adc_vol < u16_gun_min_vol ) //小于充电桩最小输出电压
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_14038, TIMER_NONE ); //停止流程
|
|
FLOWCTRL_LOG("14038= %d ,%d\n",u16_batt_adc_vol,u16_gun_min_vol);
|
|
}
|
|
}
|
|
u8_vol_err = 1;
|
|
}
|
|
else
|
|
{
|
|
s_real_data->u16_anti_shake_cnt = 0; //计时清零
|
|
u8_vol_err = 0;
|
|
}
|
|
|
|
//电池测电压 与bms车辆当前电池电压判定
|
|
if(u8_vol_err == 0 &&
|
|
((u16_bms_ver == 0) || //一级 国标不使能,或者
|
|
(u16_bms_batt_vol != 0 && //二级 bms电池测电压不为零,并且
|
|
((F32_T)abs(u16_bms_batt_vol - u16_batt_adc_vol)) /(F32_T)u16_bms_batt_vol < 0.05f))) //二级 直流输出接触器外侧电压与通信报文电池电压相差+、—5%
|
|
{
|
|
if((s_flow_data.u8_gb_en == 0) || s_real_data->u16_anti_shake_cnt2 > TIMER_1s) //1s
|
|
{
|
|
//GBT 34657-2017 DN2007/DN2008,需要测试5S内未准备就绪报BRO-0xAA超时,此时需发送CRO_0x00
|
|
if((s_flow_data.u8_gb_en == 0) || u32_safe_seconds_since(s_real_data->ulong_flow_timer) > 6)
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_pre_mdu; //详细状态跳转
|
|
s_real_data->u16_need_vol = u16_batt_adc_vol; //电池测电压
|
|
s_real_data->u16_need_cur = u16_gun_min_cur; //最小电流
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_PRE_CHARGE_RUNING); //状态跳转到预充
|
|
|
|
FLOWCTRL_LOG("Prechk ok, prechg start: adc=%d(0.1V), bms=%d(0.1V)\n",u16_batt_adc_vol ,u16_bms_batt_vol);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s_real_data->u16_anti_shake_cnt2 = 0; //临时变量清零
|
|
}
|
|
|
|
//vin返回结果判断
|
|
if(s_real_data->e_start_reason == CtR_CMD_VIN_START) //如果是vin启动,判断鉴权失败
|
|
{
|
|
U8_T u8_vin_res = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BS_VIN_RES,0); //VIN 鉴权结果 0wu 1成功 2平台鉴权超时 3非法VIN 4车辆识别鉴权帧超时 5即插即充鉴权失败 6鉴权VIN与车辆VIN不一致
|
|
|
|
if(u8_vin_res >= 2) //鉴权失败
|
|
{
|
|
v_flow_vin_fail_stop(u8_gunNo,u8_vin_res); //vin鉴权失败执行
|
|
}
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_PRECHARGE) //60秒
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15035, TIMER_NONE ); //停止流程 接触器外侧电压
|
|
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 预充中执行
|
|
* 设置需求电压值、等待模块状态启动、判断预充电压输出是否达标、判断平台即插即充鉴权结果、60秒超时判断
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_pre_charge_runing(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U16_T u16_mdu_state = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_MDU_WORK,0); //获取模块运行状态 0空闲 1工作
|
|
U16_T u16_bms_batt_vol = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_BMS_REAL_BATT_VOL,0); //BMS 当前电池电压值 精度 0.1V
|
|
|
|
U16_T u16_batt_adc_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_BATT_ADC_VOL,0); //电池外侧采集电压 精度 0.1V
|
|
U16_T u16_bus_vol = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_GUN_BUS_VOL,0); //充电枪接触器内侧电压值 精度 0.1V
|
|
U16_T u16_mdu_put_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_MDU_PUT_VOL,0); //获取模块输出电压值 精度0.1V
|
|
|
|
U16_T u16_gun_min_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_CUR,0); //充电枪最小数据电流值 精度 0.1V
|
|
U16_T u16_bms_ver = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_GB_VER,0); //BMS 国标协议版本 0 2011版 1 2015版
|
|
|
|
if ((s_flow_data.u8_gun_type[u8_gunNo] == 0)) /* 欧标:不用等待预充 */
|
|
{
|
|
U16_T u16_bms_need_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_NEED_VOL,0); //BMS 需求电压值 精度 0.1V
|
|
|
|
//设置预充电压
|
|
s_real_data->u16_need_vol = u16_bms_need_vol; //获取BCL需求电压
|
|
s_real_data->u16_need_cur = u16_gun_min_cur; //最小电流
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_PRE_START); //对外状态跳转开始预充
|
|
|
|
//等待模块状态变为工作
|
|
if(u16_mdu_state == 1)
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_pre_vol; //详细状态跳转
|
|
if(abs(u16_bms_need_vol - u16_bus_vol) <= s_flow_data.u16_insul_putvol_range ||
|
|
abs(u16_bms_need_vol - u16_mdu_put_vol )<= s_flow_data.u16_insul_putvol_range)
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_bms_change; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_PRE_CHARGE_OK); //状态跳转到预充完成
|
|
|
|
FLOWCTRL_LOG("EB preV ok[%d], V=%d,%d\n",u16_mdu_state,u16_batt_adc_vol,u16_bus_vol);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_INSULATION) //15秒
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_14020, TIMER_NONE ); //停止流程 预充启动模块失败
|
|
}
|
|
}
|
|
|
|
}
|
|
else /* 国标 */
|
|
{
|
|
//设置预充电压
|
|
s_real_data->u16_need_vol = u16_bms_batt_vol; //获取电池当前电压 bms值
|
|
s_real_data->u16_need_cur = u16_gun_min_cur; //最小电流
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_PRE_START); //对外状态跳转开始预充
|
|
|
|
//等待模块状态变为工作
|
|
if(u16_mdu_state == 1)
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_pre_vol; //详细状态跳转
|
|
if((u16_bms_ver == 0) || //2011版国标 直接通过
|
|
abs(u16_batt_adc_vol - u16_bus_vol) <= s_flow_data.u16_insul_putvol_range ||
|
|
abs(u16_batt_adc_vol - u16_mdu_put_vol )<= s_flow_data.u16_insul_putvol_range)
|
|
{
|
|
s_real_data->e_charge_state = e_wiat_bms_change; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_PRE_CHARGE_OK); //状态跳转到预充完成
|
|
|
|
FLOWCTRL_LOG("GB preV ok[%d], V=%d,%d\n",u16_mdu_state,u16_batt_adc_vol,u16_bus_vol);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_INSULATION) //15秒
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_14020, TIMER_NONE ); //停止流程 预充启动模块失败
|
|
}
|
|
}
|
|
}
|
|
|
|
//vin返回结果判断
|
|
if(s_real_data->e_start_reason == CtR_CMD_VIN_START) //如果是vin启动,判断鉴权失败
|
|
{
|
|
U8_T u8_vin_res = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BS_VIN_RES,0); //VIN 鉴权结果 0wu 1成功 2平台鉴权超时 3非法VIN 4车辆识别鉴权帧超时 5即插即充鉴权失败 6鉴权VIN与车辆VIN不一致
|
|
|
|
if(u8_vin_res >= 2) //鉴权失败
|
|
{
|
|
v_flow_vin_fail_stop(u8_gunNo,u8_vin_res); //vin鉴权失败执行
|
|
}
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_PRECHARGE) //60秒
|
|
{
|
|
FLOWCTRL_LOG("Prechg TO: batt=%d, bus=%d\n",u16_batt_adc_vol,u16_bus_vol);
|
|
if(abs(u16_batt_adc_vol - s_real_data->u16_need_vol) > s_flow_data.u16_insul_putvol_range) //电池测电压不达标
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_15035, TIMER_NONE ); //停止流程 预充电压未启动到位
|
|
}
|
|
else //模块输出电压不达标
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13053, TIMER_NONE ); //停止流程 预充电压未启动到位
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 预充完成执行
|
|
* 判断VIN平台鉴权返回结果、等待BMS状态变为充电中、30秒超时判断
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_pre_charge_ok(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U8_T u8_vin_res_ok = 0;
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_PRE_OK); //对外状态跳转开始预充完成
|
|
|
|
//vin返回结果判断
|
|
if(s_real_data->e_start_reason == CtR_CMD_VIN_START) //如果是vin启动,判断鉴权失败
|
|
{
|
|
U8_T u8_vin_res = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BS_VIN_RES,0); //VIN 鉴权结果 0wu 1成功 2平台鉴权超时 3非法VIN 4车辆识别鉴权帧超时 5即插即充鉴权失败 6鉴权VIN与车辆VIN不一致
|
|
|
|
if(u8_vin_res >= 2) //鉴权失败
|
|
{
|
|
v_flow_vin_fail_stop(u8_gunNo,u8_vin_res); //vin鉴权失败执行
|
|
}
|
|
else if(u8_vin_res == 1)
|
|
{
|
|
u8_vin_res_ok = 1;
|
|
}
|
|
else //还未鉴权
|
|
{
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_VOLT)
|
|
{
|
|
FLOWCTRL_LOG("Prechg ok, VIN auth TO\n");
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13067, TIMER_NONE ); //停止流程 车辆失败鉴权超时
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
u8_vin_res_ok = 1;
|
|
}
|
|
|
|
|
|
//等待bms状态变为充电中
|
|
if(u8_vin_res_ok == 1 && s_real_data->u8_bms_charge_flag == 1)
|
|
{
|
|
s_real_data->e_charge_state = e_change; //详细状态跳转
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,1,1); //K1K2控制 控制k1k2闭合
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_CHARGE_RUNING); //状态跳转到充电中
|
|
|
|
FLOWCTRL_LOG("BMS ready, enter chg...\n");
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_INSULATION) //10秒
|
|
{
|
|
FLOWCTRL_LOG("13090 %d %d\n",u8_vin_res_ok,s_real_data->u8_bms_charge_flag);
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13090, TIMER_NONE ); //停止流程 等待BMS状态超时 理论上不会走到这
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 充电中执行
|
|
* 设置需求电压、需求电流值; 监听BMS暂停充电状态;周期打印实时充电数据
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_charge_runing(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U16_T u16_bms_need_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_NEED_VOL,0); //BMS 需求电压值 精度 0.1V
|
|
U16_T u16_bms_need_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_NEED_CUR,0); //BMS 需求电流值 精度 0.1V
|
|
|
|
U16_T u16_meter_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_VOL,0); //电表采集电压 精度0.1V
|
|
U16_T u16_meter_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0); //电表采集电流 精度0.1V
|
|
|
|
//设置电压电流
|
|
s_real_data->u16_need_vol = u16_bms_need_vol; //获取bms需求电压 精度0.1V
|
|
s_real_data->u16_need_cur = u16_bms_need_cur; //获取bms需求电流 精度0.1A
|
|
|
|
v_flow_check_gun_power_limit(u8_gunNo,&s_real_data->u16_need_vol,&s_real_data->u16_need_cur); //充电枪限制功率检查
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_CHARGEING); //对外状态跳转充电中
|
|
|
|
v_flow_log_info_ctrl(u8_gunNo,2); //充电中 计算充电时间
|
|
|
|
v_flow_log_info_updata(u8_gunNo); //充电中,更新log中充电电量与充电金额
|
|
|
|
//监听bms停止充电状态
|
|
if(s_real_data->u8_bms_suspend_flag == 1)
|
|
{
|
|
s_real_data->e_charge_state = e_change_suspend; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_CHARGE_SUSPEND); //状态跳转到充电暂停
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,0,0); //K1K2控制 控制k1k2断开
|
|
|
|
FLOWCTRL_LOG("Chg suspend...\n");
|
|
}
|
|
|
|
//周期打印实时充电数据
|
|
if((s_flow_data.u16_timer_cnt % TIMER_30s) == 0) //30秒打印
|
|
{
|
|
FLOWCTRL_LOG("[%d]gun need vol= %d , need cur= %d \n",u8_gunNo,u16_bms_need_vol,u16_bms_need_cur);
|
|
FLOWCTRL_LOG("out vol= %d , out cur= %d \n",u16_meter_vol,u16_meter_cur);
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 充电暂停执行
|
|
* 设置需求电压、电流值 、 监听BMS充电暂停恢复、 周期打印、10分钟超时判定
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_charge_suspend(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U16_T u16_bms_need_vol = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_BMS_NEED_VOL,0); //BMS 需求电压值 精度 0.1V
|
|
U16_T u16_gun_min_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_CUR,0); //充电枪最小数据电流值 精度 0.1V
|
|
|
|
//设置需求值
|
|
s_real_data->u16_need_vol = u16_bms_need_vol; //获取bms需求电压
|
|
s_real_data->u16_need_cur = u16_gun_min_cur; //获取bms需求电流
|
|
|
|
v_flow_log_info_ctrl(u8_gunNo,2); //充电中 计算充电时间
|
|
|
|
//监听bms停止充电恢复
|
|
if(s_real_data->u8_bms_suspend_flag == 0)
|
|
{
|
|
s_real_data->e_charge_state = e_change; //详细状态跳转
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_CHARGE_RUNING); //状态跳转到充电中
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,1,1); //K1K2控制 控制k1k2闭合
|
|
FLOWCTRL_LOG("Chg resume...\n");
|
|
}
|
|
|
|
//周期打印实时充电数据
|
|
if((s_flow_data.u16_timer_cnt % TIMER_30s) == 0) //30秒打印
|
|
{
|
|
FLOWCTRL_LOG("Suspend t=%d\n",u32_safe_seconds_since(s_real_data->ulong_flow_timer));
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_CHANGE_STOPTIME) //50*10秒
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13068, TIMER_NONE ); //停止流程 充电暂停10分钟
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 充电中BMS通信超时 重连执行
|
|
* 设置需求值为0,赋值通讯中断告警, 对外状态跳转到通信超时、等待模块空闲且电流下降到标准值或10秒后,断开k1k2跳转等待预充状态、30秒超时判断
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_ctrl_bms_timeout(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
U16_T u16_mdu_state = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_MDU_WORK,0); //获取模块运行状态 0空闲 1工作
|
|
U16_T u16_meter_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0); //电表采集电流 精度0.1V
|
|
U16_T u16_gun_min_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_CUR,0); //充电枪最小数据电流值 精度 0.1V
|
|
|
|
|
|
//设置电压电流
|
|
s_real_data->u16_need_vol = 0;
|
|
s_real_data->u16_need_cur = 0;
|
|
|
|
//通讯中断告警
|
|
if(u16_flow_get_sys_data(u8_gunNo+1,E_FLOW_GET_DATA_FAULT_FLAG,E_FAULT_15000) == 0) //获取故障内容存在标志 0不存在 1存在;需要传入 故障代码参数)
|
|
{
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_WARN, E_FAULT_15000, 1, 0, 0);
|
|
}
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_BMS_OUTTIME); //对外状态跳转bms通讯超时
|
|
|
|
//等待模块状态变为空闲 并且电流降下或者到达10秒
|
|
if(u16_mdu_state== 0 &&
|
|
(u16_meter_cur <= u16_gun_min_cur ||
|
|
u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= NUM_10 ))
|
|
{
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_WAIT_PRE_CHARGE); //状态跳转到等待预充
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,0,0); //K1K2控制 控制k1k2断开
|
|
|
|
//通讯中断告警恢复
|
|
if(u16_flow_get_sys_data(u8_gunNo+1,E_FLOW_GET_DATA_FAULT_FLAG,E_FAULT_15000) == 1) //获取故障内容存在标志 0不存在 1存在;需要传入 故障代码参数)
|
|
{
|
|
v_flow_set_fault_data((E_FAULT_SITE)(u8_gunNo + 1), E_RES, E_FAULT_15000, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_INSULATION) //15秒
|
|
{
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_14021, TIMER_NONE ); //停止流程 重连停模块失败
|
|
FLOWCTRL_LOG("TO stop mdu[%d] cur[%d]",u16_mdu_state,u16_meter_cur);
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 充电停止执行
|
|
* 清空需求值,对外状态跳转为停止充电,异常停止时计数值清零立马断开k1k2继电器,等待模块输出空闲且电流下降到标准值,投泄放、跳转状态,或者15秒超时强制跳转状态
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_set_stop_charge_runing(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
|
|
U16_T u16_mdu_state = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_MDU_WORK,0); //获取模块运行状态 0空闲 1工作
|
|
U16_T u16_meter_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_METER_CUR,0); //电表采集电流 精度0.1V
|
|
U16_T u16_gun_min_cur = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_MIN_CUR,0); //充电枪最小数据电流值 精度 0.1V
|
|
|
|
S8_T s8_relief_res;
|
|
U8_T u8_vol_down_ok = 0;
|
|
//设置电压电流
|
|
s_real_data->u16_need_vol = 0;
|
|
s_real_data->u16_need_cur = 0;
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_STOP); //对外状态跳转充电停止停止
|
|
|
|
//异常停止判断
|
|
if(s_ctrl_data->s16_fault_stop_cnt == 0) //异常停止时 故障计数赋计数值,累减至0后 断开k1k2接触器
|
|
{
|
|
s_ctrl_data->s16_fault_stop_cnt -- ;
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,0,0); //K1K2控制 控制k1k2断开 -- 故障停止、计时结束后立马控制k1k2断开
|
|
FLOWCTRL_LOG("Abn stop, K1K2 off\n");
|
|
}
|
|
|
|
//正常流程 - 等待模块输出停止后,断开k1k2 投泄放
|
|
if(u16_mdu_state == 0 && //模块状态为停止
|
|
u16_meter_cur <= u16_gun_min_cur) //输出电流降下
|
|
{
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,0,0); //K1K2控制 控制k1k2断开 --
|
|
|
|
s8_relief_res = s8_flow_volt_relief_do(u8_gunNo);
|
|
if(s8_relief_res == 1)
|
|
{
|
|
u8_vol_down_ok = 1; //进行下一步
|
|
FLOWCTRL_LOG("MDU stop, dischg ok\n");
|
|
}
|
|
else if(s8_relief_res == 0)
|
|
v_flow_set_stop_charge(u8_gunNo, E_FAULT_13047, TIMER_NONE ); //停止流程 泄放失败
|
|
}
|
|
|
|
//超时判断
|
|
if(u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_PCM_STATE) //15秒
|
|
{
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,0,0); //K1K2控制 控制k1k2断开 --
|
|
u8_vol_down_ok = 1; //进行下一步
|
|
}
|
|
|
|
//检查执行完成
|
|
if(u8_vol_down_ok == 1)
|
|
{
|
|
FLOWCTRL_LOG("Stop done\n");
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_STOP_CHARGE_OK); //状态跳转到停止充电完成
|
|
}
|
|
}
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 充电流程控制执行 充电停止完成执行
|
|
* 等待csd报文发送10帧以上后 断开辅源;断开所有控制开关 跳转到空闲状态
|
|
*
|
|
* @param[in] u8_gunNo - 枪号 0-N
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-04
|
|
* ************************************************************************
|
|
*/
|
|
static void v_flow_set_stop_charge_ok(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
|
|
U16_T u16_bms_csd_send_cnt = u16_flow_get_sys_data(u8_gunNo, E_FLOW_GET_DATA_BMS_CAN_SEND_CNT,1); //BMS 报文发送次数 参数值 0代表cem 1代表csd
|
|
|
|
U8_T u8_ctrl_ok = 0;
|
|
if( (u16_bms_csd_send_cnt > 3 || //csd发送次数超过3条
|
|
u32_safe_seconds_since(s_real_data->ulong_flow_timer) >= FLOW_TIMEOUT_PCM_STATE)) //15秒
|
|
{
|
|
//辅源动作
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_AUXPOWER,0,0); //断辅源
|
|
|
|
v_flow_real_state_change(u8_gunNo,E_FLOW_REAL_STOP_OK); //对外状态跳转停止完成
|
|
|
|
u8_ctrl_ok = 1;
|
|
}
|
|
|
|
if(u8_ctrl_ok == 1) //接枪锁 等待拔枪--直接恢复至空闲状态,不把枪也能启动
|
|
{
|
|
//空闲时检查枪锁状态
|
|
v_flow_free_gunlock_check(u8_gunNo);
|
|
|
|
//拔枪前所有控制都断一下 、 以防万一
|
|
v_flow_gun_insulation_data_ctrl(u8_gunNo,1);
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_AUXPOWER,0,0); //断辅源
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_GUN_LOCK,0,0); //断枪锁
|
|
u16_flow_put_ctrl(u8_gunNo,E_FLOW_CTRL_DATA_K1K2,0,0); //断直流接触器
|
|
v_flow_gun_volt_relief_free(u8_gunNo ,1); //关闭gunNo枪泄放电路
|
|
|
|
FLOWCTRL_LOG("Back to idle, thx!\n");
|
|
v_flow_ctrl_state_change(u8_gunNo,E_FLOW_FREE); //状态跳转到空闲
|
|
s_ctrl_data->e_start_flag = CTR_CMD_NONE; //启动后清零
|
|
v_flow_log_info_ctrl(u8_gunNo,0); //充电订单控制
|
|
}
|
|
}
|
|
void v_flow_control(U8_T u8_gunNo)
|
|
{
|
|
S_FLOW_REAL_DATA *s_real_data = &s_flow_data.s_real_data[u8_gunNo]; //实时数据指针
|
|
S_FLOW_CTRL_DATA *s_ctrl_data = &s_flow_data.s_ctrl_data[u8_gunNo]; //充电控制数据
|
|
(void)s_ctrl_data;
|
|
|
|
v_flow_stop_fault_check(u8_gunNo); //停止故障检查
|
|
v_flow_bms_state_cheak(u8_gunNo); //BMS状态检查
|
|
v_flow_stop_cmd_check(u8_gunNo); //停止命令检查
|
|
|
|
switch (s_real_data->e_flow_state)
|
|
{
|
|
case E_FLOW_FREE : //空闲
|
|
{
|
|
v_flow_ctrl_free(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_START_CHECK : //启动前检查
|
|
{
|
|
v_flow_ctrl_start_check(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_START_CHECK_OK : //启动前检查完成
|
|
{
|
|
v_flow_ctrl_start_check_ok(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_INSUL_BEFORE : //绝缘检查前准备
|
|
{
|
|
v_flow_ctrl_insul_before(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_INSUL_RUNING : //绝缘检测中
|
|
{
|
|
v_flow_ctrl_insul_runing(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_INSUL_OK : //绝缘检测完成
|
|
{
|
|
v_flow_ctrl_insul_ok(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_WAIT_PRE_CHARGE : //等待预充
|
|
{
|
|
v_flow_ctrl_wait_pre_charge(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_PRE_CHARGE_BEFORE : //预充前检查
|
|
{
|
|
v_flow_ctrl_pre_charge_before(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_PRE_CHARGE_RUNING : //预充电中
|
|
{
|
|
v_flow_ctrl_pre_charge_runing(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_PRE_CHARGE_OK : //预充完成
|
|
{
|
|
v_flow_ctrl_pre_charge_ok(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_CHARGE_RUNING : //充电中
|
|
{
|
|
v_flow_ctrl_charge_runing(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_CHARGE_SUSPEND : //充电暂停
|
|
{
|
|
v_flow_ctrl_charge_suspend(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_BMS_TIMEOUT : //BMS通讯超时
|
|
{
|
|
v_flow_ctrl_bms_timeout(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_STOP_CHARGE : //停止充电
|
|
{
|
|
v_flow_set_stop_charge_runing(u8_gunNo);
|
|
break;
|
|
}
|
|
case E_FLOW_STOP_CHARGE_OK : //停止充电完成
|
|
{
|
|
v_flow_set_stop_charge_ok(u8_gunNo);
|
|
break;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* ************************************************************************
|
|
* @brief - 流程控制任务 数据初始化
|
|
*
|
|
*
|
|
*
|
|
* @author jiankalka
|
|
* @date 2025-09-03
|
|
* ************************************************************************
|
|
*/
|
|
void v_flowctrl_data_init()
|
|
{
|
|
memset(&s_flow_data , 0 ,sizeof(S_FLOW_DATA));
|
|
|
|
s_flow_data.u8_gunCnt = u16_flow_get_sys_data(0,E_FLOW_GET_DATA_GUN_CNT,0); //获取枪号
|
|
s_flow_data.u8_gb_en = u16_flow_get_sys_data(0,E_FLOW_GET_DATA_GB_EN,0); //国标使能
|
|
memcpy(s_flow_data.u8_gun_type, g_t_share_data.t_sys_fix_cfg.u8_gun_type, GUN_MAX_CNT); //枪类型 0欧标 1国标
|
|
s_flow_data.u8_gunlock_num = 10; //空闲枪锁解锁次数
|
|
s_flow_data.u8_relief_time = 2; //泄放时间改 单位秒
|
|
|
|
// 初始化防抖/延时计时器起点,避免“首次进入判定即超时”
|
|
{
|
|
U8_T i;
|
|
U32_T now_s = get_current_seconds();
|
|
for(i = 0; i < GUN_MAX_CNT; i++)
|
|
{
|
|
s_flow_data.s_ctrl_data[i].s_over_time.u32_trickle_limit_time = now_s;
|
|
s_flow_data.s_ctrl_data[i].s_over_time.u32_dc_km_time = now_s;
|
|
s_flow_data.s_ctrl_data[i].s_over_time.u32_mdu_free_time = now_s;
|
|
s_flow_data.s_ctrl_data[i].s_over_time.u32_over_vol_time = now_s;
|
|
s_flow_data.s_ctrl_data[i].s_over_time.u32_under_vol_time = now_s;
|
|
s_flow_data.s_ctrl_data[i].s_over_time.u32_over_curr_time = now_s;
|
|
s_flow_data.s_ctrl_data[i].s_over_time.u32_over_needCur_time = now_s;
|
|
s_flow_data.s_ctrl_data[i].s_over_time.u32_over_needCur_max_time = now_s;
|
|
}
|
|
}
|
|
|
|
if(s_flow_data.u8_gb_en == 1) //国标使能
|
|
{
|
|
s_flow_data.u16_insul_before_vol = 600; //绝缘前外侧电压检测 精度 0.1V
|
|
s_flow_data.u16_insul_putvol_range = 100; //绝缘检测电压输出误差值 精度 0.1V
|
|
}
|
|
else
|
|
{
|
|
s_flow_data.u16_insul_before_vol = 1000; //绝缘前外侧电压检测 精度 0.1V
|
|
s_flow_data.u16_insul_putvol_range = 600; //绝缘检测电压输出误差值 精度 0.1V
|
|
}
|
|
}
|
|
|
|
void v_flowctrl_task(void *arg)
|
|
{
|
|
uint16_t sleep_time_ms;
|
|
uint32_t last_send_time;
|
|
uint32_t current_time;
|
|
uint8_t u8_gunNo;
|
|
|
|
(void)arg;
|
|
(void)FLOWCTRL_LOCK_INIT();
|
|
sleep_time_ms = FLOWCTRL_SLEEP_TIME_MS();
|
|
last_send_time = get_current_seconds();
|
|
|
|
v_flowctrl_data_init();
|
|
|
|
for (;;) {
|
|
FLOWCTRL_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 (FLOWCTRL_LOCK_TAKE() == 1U) {
|
|
FLOWCTRL_LOG("flowctrl task is runing, sleep time is %ums", sleep_time_ms);
|
|
(void)FLOWCTRL_LOCK_GIVE();
|
|
}
|
|
last_send_time = current_time;
|
|
}
|
|
for (u8_gunNo = 0; u8_gunNo < s_flow_data.u8_gunCnt; u8_gunNo++)
|
|
{
|
|
s_flow_data.s_ctrl_data[u8_gunNo].u8_twoGun_flag = u16_flow_get_sys_data(u8_gunNo,E_FLOW_GET_DATA_GUN_TOW_CHR,0); //获取双枪同充标志
|
|
|
|
if(s_flow_data.s_ctrl_data[u8_gunNo].u8_twoGun_flag == 0) //单枪充电
|
|
{
|
|
v_flow_control(u8_gunNo); //充电流程控制
|
|
}
|
|
else
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
v_mdu_shw_control(sleep_time_ms); //模块开关控制
|
|
v_flow_ac_fan_ctrl(sleep_time_ms); //交流接触器和开关控制
|
|
|
|
v_flow_timer_add(sleep_time_ms); //任务 周期计数值 累加
|
|
mSleep(sleep_time_ms);
|
|
}
|
|
}
|
|
|
|
|
|
|