313 lines
11 KiB
C
313 lines
11 KiB
C
#include "iso_check.h"
|
||
#include "version_manager.h"
|
||
#include "fault_manager.h"
|
||
#include "signal_manager.h"
|
||
#include "dido_manager.h"
|
||
#include "eeprom_manager.h"
|
||
#include "hv_adc_manager.h"
|
||
#include "logic_ctrl.h"
|
||
|
||
|
||
//确保在继电器断开时调用
|
||
bool logic_adhesion_check(uint32_t base_time, DoType type)
|
||
{
|
||
static uint16_t adhesion_dly = 0;
|
||
bool is_chekc = true;
|
||
uint16_t tv, hv, rate;
|
||
FaultLevel fault = kFaultLevel_Normal;
|
||
DoErrSrc do_err_src = bms_get_do_err_src(type);
|
||
|
||
//do_err_src += 1;
|
||
|
||
if(bms_get_run_status() == kRunStatus_Init)
|
||
{
|
||
return false;
|
||
}
|
||
switch(do_err_src)
|
||
{
|
||
case kDoErrSrc_HV1:
|
||
case kDoErrSrc_HV2:
|
||
//母线簇用电压检测粘连
|
||
tv = bms_get_high_volt(kHvType_Bat);
|
||
if((tv >= 300) && (bms_get_circuit_cmd_status() == kCircuitStatus_On))
|
||
{
|
||
if(bms_get_bus_bar_bcu() == bms_get_tag_data(kTagData_DevAddr))
|
||
{
|
||
hv = bms_get_high_volt((HvType)(kHvType_Hv1 + do_err_src - 1));
|
||
rate = get_eeprom_data(kEep_HV2_HV1VoltRate, (EepromDataType)(kEepromDataType_Low + do_err_src - 1));
|
||
if(hv >= ((uint32_t)tv * rate / 100))
|
||
{
|
||
fault = kFaultLevel_Third;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
is_chekc = false;
|
||
}
|
||
break;
|
||
case kDoErrSrc_DI1:
|
||
case kDoErrSrc_DI2:
|
||
case kDoErrSrc_DI3:
|
||
case kDoErrSrc_DI4:
|
||
case kDoErrSrc_DI5:
|
||
case kDoErrSrc_DI6:
|
||
case kDoErrSrc_DI7:
|
||
case kDoErrSrc_DI8:
|
||
case kDoErrSrc_DI9:
|
||
//if(bms_get_signal((SignalIdx)(do_err_src - kDoErrSrc_DI1)) == kSignalStatus_High)
|
||
if(bms_get_signal((SignalIdx)(do_err_src - kDoErrSrc_DI1)) != bms_get_di_polarity(do_err_src - kDoErrSrc_DI1))
|
||
{
|
||
fault = kFaultLevel_Third;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
//通过电流判断粘连
|
||
if((fault != kFaultLevel_Third) && (KIT_ABS(bms_get_current()) > 50))
|
||
{
|
||
fault = kFaultLevel_Third;
|
||
}
|
||
|
||
//gary 增加连续3秒粘连问题在报粘连故障
|
||
if(fault == kFaultLevel_Third && is_chekc == true)
|
||
{
|
||
adhesion_dly += base_time;
|
||
|
||
if(adhesion_dly > 3000)
|
||
{
|
||
adhesion_dly = 0;
|
||
bms_set_do_fault(type, kDoStatus_Adhesion);
|
||
bms_set_fault_level(kFaultCode_DoAdhesion, fault, kFaultHandle_CutNoRelIdx);
|
||
}
|
||
else
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
return is_chekc;
|
||
}
|
||
|
||
void logic_open_check(uint32_t base_time)
|
||
{
|
||
uint16_t tv, hv, rate;
|
||
DoErrSrc do_err_src = bms_get_do_err_src(kDoType_Chg);
|
||
FaultLevel fault = kFaultLevel_Normal;
|
||
static uint16_t dly;
|
||
|
||
switch(do_err_src)
|
||
{
|
||
case kDoErrSrc_HV1:
|
||
case kDoErrSrc_HV2:
|
||
tv = bms_get_high_volt(kHvType_Bat);
|
||
hv = bms_get_high_volt((HvType)(kHvType_Hv1 + do_err_src - 1));
|
||
rate = get_eeprom_data(kEep_HV2_HV1VoltRate, (EepromDataType)(kEepromDataType_Low + do_err_src - 1));
|
||
if((tv >= 300 && (hv + 200 <= ((uint32_t)tv * rate / 100))) || (tv<100))
|
||
{
|
||
dly += base_time;
|
||
if(dly >= 1000)
|
||
{
|
||
fault = kFaultLevel_Third;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dly = 0;
|
||
}
|
||
break;
|
||
|
||
case kDoErrSrc_DI1:
|
||
case kDoErrSrc_DI2:
|
||
case kDoErrSrc_DI3:
|
||
case kDoErrSrc_DI4:
|
||
case kDoErrSrc_DI5:
|
||
case kDoErrSrc_DI6:
|
||
case kDoErrSrc_DI7:
|
||
case kDoErrSrc_DI8:
|
||
case kDoErrSrc_DI9:
|
||
//if(bms_get_signal((SignalIdx)(do_err_src - kDoErrSrc_DI1)) == kSignalStatus_High)
|
||
if(bms_get_signal((SignalIdx)(do_err_src - kDoErrSrc_DI1)) == bms_get_di_polarity(do_err_src - kDoErrSrc_DI1))
|
||
{
|
||
fault = kFaultLevel_Third;
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
bms_set_fault_level(kFaultCode_DoOpen, fault, kFaultHandle_CutNoRelIdx);
|
||
}
|
||
|
||
|
||
void logic_same_circuit_ctrl(uint32_t base_time)
|
||
{
|
||
HvType prechg_type;
|
||
uint16_t prechg_volt = 0;
|
||
static uint16_t dly = 0;
|
||
static uint8_t prechg_cnt = 0;
|
||
static DoLogicStatus status = kDoLogicStatus_Reset;
|
||
|
||
uint16_t prechg_time = get_eeprom_data(kEep_PreChgTimeout_Count, kEepromDataType_Full);
|
||
uint8_t prechg_max_cnt = prechg_time & 0x00FF;
|
||
prechg_time = (prechg_time >> 8) * 1000;
|
||
|
||
switch(status)
|
||
{
|
||
case kDoLogicStatus_Reset:
|
||
if((get_eeprom_data(kEep_IsSoftReset, kEepromDataType_High) == 1)
|
||
&& (get_eeprom_data(kEep_IsSoftReset, kEepromDataType_Low) != 0))
|
||
{
|
||
dly += base_time;
|
||
//kEep_IsSoftReset高低只能清楚一个,否则断电下带无法保存0
|
||
if(((bms_get_run_status() != kRunStatus_Init) && (bms_get_circuit_cmd_status() == kCircuitStatus_On)) || (dly >= 10000))
|
||
{
|
||
bms_crtl_do_status(kDoType_Chg, kDoCtrlStatus_On, RELAY_CTRL_NO_DLY);
|
||
bms_crtl_do_status(kDoType_Dis, kDoCtrlStatus_On, 100);
|
||
dly = 0;
|
||
status = kDoLogicStatus_On;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
dly = 0;
|
||
status = kDoLogicStatus_Init;
|
||
}
|
||
break;
|
||
case kDoLogicStatus_Init:
|
||
//增加init状态,防止预充中反复检测粘连 建议增加多次检测
|
||
//Gary 2024-07-25 连续粘连3秒才报粘连故障
|
||
dly += base_time;
|
||
if(logic_adhesion_check(base_time, kDoType_Chg) == true)
|
||
{
|
||
dly = 0;
|
||
status = kDoLogicStatus_Off;
|
||
}
|
||
break;
|
||
case kDoLogicStatus_Off:
|
||
if ((bms_is_dis_allow() == true) && (bms_is_chg_allow() == true))
|
||
{
|
||
if (prechg_max_cnt == 0) //读取配置:不预充
|
||
{
|
||
status = kDoLogicStatus_On;
|
||
bms_crtl_do_status(kDoType_Dis, kDoCtrlStatus_On, RELAY_CTRL_NO_DLY);
|
||
bms_crtl_do_status(kDoType_Chg, kDoCtrlStatus_On, 100);
|
||
}
|
||
else //读取配置:预充
|
||
{
|
||
if (prechg_cnt++ < prechg_max_cnt) //判断预充次数
|
||
{
|
||
status = kDoLogicStatus_Prechg;
|
||
//bms_crtl_do_status(kDoType_Chg, kDoCtrlStatus_On, RELAY_CTRL_NO_DLY); //闭合总正继电器
|
||
bms_crtl_do_status(kDoType_Dis, kDoCtrlStatus_On, RELAY_CTRL_NO_DLY);
|
||
bms_crtl_do_status(kDoType_PreChg, kDoCtrlStatus_On, 100);
|
||
|
||
}
|
||
else
|
||
{
|
||
bms_crtl_do_status(kDoType_Dis, kDoCtrlStatus_Off, 100);
|
||
bms_set_fault_level(kFaultCode_PreChg, kFaultLevel_Third, kFaultHandle_CutNoRelIdx);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case kDoLogicStatus_Prechg:
|
||
dly += base_time;
|
||
if ((bms_is_dis_allow() == false) || (bms_is_chg_allow() == false))
|
||
{
|
||
prechg_cnt = 0;
|
||
status = kDoLogicStatus_Off;
|
||
bms_crtl_do_status(kDoType_PreChg, kDoCtrlStatus_Off, RELAY_CTRL_NO_DLY);
|
||
bms_crtl_do_status(kDoType_Dis, kDoCtrlStatus_Off, 100);
|
||
}
|
||
else if (dly >= prechg_time)//预充超时
|
||
{
|
||
dly = 0;
|
||
status = kDoLogicStatus_PrechgFail;
|
||
bms_crtl_do_status(kDoType_PreChg, kDoCtrlStatus_Off, RELAY_CTRL_NO_DLY);
|
||
}
|
||
else
|
||
{
|
||
prechg_volt = bms_get_high_volt(kHvType_Bat);//sfj 获取B+B-电压
|
||
if (prechg_volt >= 300)
|
||
{
|
||
prechg_type = (HvType)get_eeprom_data(kEep_PreChgVoltType_Rate,kEepromDataType_High);
|
||
prechg_volt = prechg_volt * get_eeprom_data(kEep_PreChgVoltType_Rate,kEepromDataType_Low) / 100;
|
||
if(bms_get_high_volt(prechg_type) >= prechg_volt)
|
||
{
|
||
dly = 0;
|
||
prechg_cnt = 0;
|
||
status = kDoLogicStatus_On;
|
||
bms_crtl_do_status(kDoType_Chg, kDoCtrlStatus_On, RELAY_CTRL_NO_DLY); //闭合总正继电器
|
||
bms_crtl_do_status(kDoType_PreChg, kDoCtrlStatus_Off, 500); //延时500ms断开预充继电器
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case kDoLogicStatus_PrechgFail:
|
||
dly += base_time;
|
||
if (dly >= KIT_SECOND_CONVERT(1))
|
||
{
|
||
dly = 0;
|
||
status = kDoLogicStatus_Off;
|
||
}
|
||
break;
|
||
case kDoLogicStatus_On:
|
||
dly += base_time;
|
||
if(dly >= 10000)
|
||
{
|
||
dly = 10000;
|
||
logic_open_check(base_time);
|
||
}
|
||
if((bms_is_dis_allow() == false) || (bms_is_chg_allow() == false))
|
||
{
|
||
dly = 0;
|
||
status = kDoLogicStatus_WaitOff;
|
||
}
|
||
break;
|
||
case kDoLogicStatus_WaitOff:
|
||
dly += base_time;
|
||
if ((KIT_ABS(bms_get_current() / 10) <= get_eeprom_data(kEep_CutOffCurrent, kEepromDataType_Full)) //电流阈值可配置,分辨率 1A
|
||
&& (dly >= get_eeprom_data(kEep_PwrOffDly_MinOnlineCluster, kEepromDataType_High) * 1000)) //高压下电延迟
|
||
{
|
||
dly = 0;
|
||
status = kDoLogicStatus_WaitAdhesion;
|
||
bms_crtl_do_status(kDoType_Chg, kDoCtrlStatus_Off, RELAY_CTRL_NO_DLY);
|
||
bms_crtl_do_status(kDoType_Dis, kDoCtrlStatus_Off, 100);
|
||
}
|
||
break;
|
||
case kDoLogicStatus_WaitAdhesion:
|
||
dly += base_time;
|
||
if(dly >= KIT_SECOND_CONVERT(5))
|
||
{
|
||
dly = 0;
|
||
status = kDoLogicStatus_Init;
|
||
}
|
||
break;
|
||
default:
|
||
dly = 0;
|
||
status = kDoLogicStatus_Init;
|
||
break;
|
||
}
|
||
}
|
||
|
||
void logic_same_circuit_poll(uint32_t base_time, uint8_t idx)
|
||
{
|
||
DoStatus pos_rly_st, neg_rly_st;
|
||
CircuitStatus circuit_st = kCircuitStatus_On;
|
||
|
||
logic_same_circuit_ctrl(base_time);
|
||
pos_rly_st = bms_get_do_status_by_type(kDoType_Chg);
|
||
neg_rly_st = (bms_is_do_config(kDoType_Dis) == true) ? bms_get_do_status_by_type(kDoType_Dis) : kDoStatus_On;
|
||
//neg_rly_st = kDoStatus_On;
|
||
|
||
if(((pos_rly_st != kDoStatus_On) && (pos_rly_st != kDoStatus_ForceOn))
|
||
|| ((neg_rly_st != kDoStatus_On) && (neg_rly_st != kDoStatus_ForceOn)))
|
||
{
|
||
circuit_st = kCircuitStatus_Off;
|
||
}
|
||
|
||
bms_set_circuit_status(kCircuitType_Dis, circuit_st);
|
||
bms_set_circuit_status(kCircuitType_Chg, circuit_st);
|
||
bms_set_circuit_status(kCircuitType_Main, circuit_st);
|
||
}
|