bs_bcu_app/app/app_sop.c

333 lines
10 KiB
C
Raw Normal View History

2024-11-10 15:22:55 +08:00
#include "kit_table.h"
#include "bms_soc.h"
#include "bms_sop.h"
#include "bms_fault.h"
#include "bms_di_do.h"
#include "bms_eeprom.h"
#include "bms_signal.h"
#include "bms_statistic.h"
#include "bms_run_status.h"
#include "table_comm.h"
typedef struct
{
bool is_chg_forbid;
bool is_dis_forbid;
uint8_t chg_tab_idx;
uint32_t chg_forbid_dly;
uint32_t dis_forbid_dly;
uint32_t chg_forbid_dly1;
uint32_t dis_forbid_dly1;
uint16_t rate_data[kSopData_End];
uint16_t sop_data[kSopData_End];
}SopItem;
SopItem sop_item;
uint16_t bms_get_sop_data(SopData idx)
{
uint16_t tmp = 0;
if(idx < kSopData_End)
{
tmp = sop_item.sop_data[idx];
}
return tmp;
}
typedef enum
{
kEndChgCurStep_Normal,
kEndChgCurStep_First,
kEndChgCurStep_Second,
kEndChgCurStep_Full,
kEndChgCurStep_Forbid,
kEndChgCurStep_End,
}EndChgCurStep;
void bms_analyse_chg_sop(uint32_t base_time)
{
static uint16_t dly = 0;
bool is_forbid_chg;
uint16_t fault_cur, end_cur, fault_power, end_power, req_volt, total_volt;
uint16_t soc, min_temp, max_temp;
int32_t min_temp_cur, max_temp_cur;
soc = bms_get_soc() / 100;
min_temp = (int32_t)bms_get_statistic_data(kStatisticData_MinTemp) /10 - 50;
max_temp = (int32_t)bms_get_statistic_data(kStatisticData_MaxTemp) /10 - 50;
total_volt = bms_get_statistic_data(kStatisticData_TotalVolt) > 300 ? bms_get_statistic_data(kStatisticData_TotalVolt):300;
if(bsp_eeprom_get_data(kEEData_ChgDisMode_HighVoltStrategy, kEepromDataType_High) == kChgMode_CP)
{
if((sop_item.chg_tab_idx > 0) && (sop_item.chg_tab_idx < kSopTab_End))
{
kit_table_bilinear_search((ThreeDTabItem*)sop_table_list[sop_item.chg_tab_idx - 1], soc, min_temp, &min_temp_cur); //功率表分辨率 0.1Kwh
kit_table_bilinear_search((ThreeDTabItem*)sop_table_list[sop_item.chg_tab_idx - 1], soc, max_temp, &max_temp_cur);
end_power = (min_temp_cur < max_temp_cur) ? min_temp_cur : max_temp_cur;
end_cur = (uint32_t)end_power * 10000/total_volt; //电流分辨率0.1A
}
else
{
end_power = sop_item.rate_data[kSopData_ChgPower];
end_cur = (uint32_t)sop_item.rate_data[kSopData_ChgPower] * 10000/total_volt;
}
}
else if(bsp_eeprom_get_data(kEEData_ChgDisMode_HighVoltStrategy, kEepromDataType_High) == kChgMode_CC)
{
if((sop_item.chg_tab_idx > 0) && (sop_item.chg_tab_idx < kSopTab_End))
{
kit_table_bilinear_search((ThreeDTabItem*)sop_table_list[sop_item.chg_tab_idx - 1], soc, min_temp, &min_temp_cur);
kit_table_bilinear_search((ThreeDTabItem*)sop_table_list[sop_item.chg_tab_idx - 1], soc, max_temp, &max_temp_cur);
//end_cur = (min_temp_cur < max_temp_cur) ? min_temp_cur : max_temp_cur;
sop_item.sop_data[kSopData_MapCur] = end_cur = (min_temp_cur < max_temp_cur) ? min_temp_cur : max_temp_cur;
end_power = (uint32_t)end_cur * total_volt/100;
}
else
{
end_cur = sop_item.rate_data[kSopData_ChgCur];
end_power = (uint32_t)end_cur * total_volt/100;
}
}
else
{
end_cur = 0;
end_power = 0;
}
req_volt = sop_item.rate_data[kSopData_ChgVolt];
fault_cur = 0;
fault_power = 0;
is_forbid_chg = false;
//故障降流
if((bms_is_chg_allow() == false)
|| (bms_get_circuit_status(kCircuitType_Chg) == kCircuitStatus_Off))
{
if(bms_is_single_full_chg() == true)
{
//有故障任要发送禁充指令
if(bms_is_chg_circuit_allow() == false)
{
is_forbid_chg = true;
}
}
else
{
is_forbid_chg = true;
}
}
else if(bms_get_soc_status() == kSocStatus_Full)
{
//满充再单簇校准模式下不上发禁充
if(bms_is_single_full_chg() == false)
{
is_forbid_chg = true;
}
}
else
{
fault_cur = (uint32_t)end_cur * bms_get_fault_cur_rate(kRunStatus_Chg) / 100;
fault_power = (uint32_t)end_power * bms_get_fault_cur_rate(kRunStatus_Chg) / 100;
}
//末端单体电压降流
if(bms_get_signal(kSignalIdx_Chg2ndCurDown) == kSignalStatus_High)
{
end_cur = (uint32_t)end_cur * bsp_eeprom_get_data(kEEData_ChgSnd_FstCurDownRate, kEepromDataType_High) / 100;
end_power = (uint32_t)end_power * bsp_eeprom_get_data(kEEData_ChgSnd_FstCurDownRate, kEepromDataType_High) / 100;
}
else if(bms_get_signal(kSignalIdx_Chg1stCurDown) == kSignalStatus_High)
{
end_cur = (uint32_t)end_cur * bsp_eeprom_get_data(kEEData_ChgSnd_FstCurDownRate, kEepromDataType_Low) / 100;
end_power = (uint32_t)end_power * bsp_eeprom_get_data(kEEData_ChgSnd_FstCurDownRate, kEepromDataType_Low) / 100;
}
if(fault_cur > end_cur)
{
fault_cur = end_cur;
}
if(fault_power > end_power)
{
fault_power = end_power;
}
sop_item.sop_data[kSopData_ChgCur] = fault_cur;
sop_item.sop_data[kSopData_ChgPower] = fault_power;
if((fault_cur == 0) && (is_forbid_chg == true))
{
dly += base_time;
if(dly >= 500)
{
dly = 500;
if(bms_get_fault_cur_rate(kRunStatus_Chg) != 0)
{
sop_item.chg_forbid_dly = bsp_eeprom_get_data(kEEData_ForbidChgRelDelay, kEepromDataType_Full) * 6000;
}
sop_item.chg_forbid_dly1 = 0;
sop_item.is_chg_forbid = true;
bms_set_signal(kSignalIdx_ForbidChg, kSignalStatus_High);
}
}
else
{
dly = 0;
}
if(sop_item.is_chg_forbid == true)
{
sop_item.chg_forbid_dly += base_time;
sop_item.chg_forbid_dly1 += base_time;
sop_item.sop_data[kSopData_ChgCur] = sop_item.sop_data[kSopData_ChgPower] = 0;
if((sop_item.chg_forbid_dly1 >= 2000) && (sop_item.chg_forbid_dly >= bsp_eeprom_get_data(kEEData_ForbidChgRelDelay, kEepromDataType_Full) * 6000))
{
sop_item.is_chg_forbid = false;
sop_item.chg_forbid_dly1 = 2000;
sop_item.chg_forbid_dly = bsp_eeprom_get_data(kEEData_ForbidChgRelDelay, kEepromDataType_Full) * 6000;
bms_set_signal(kSignalIdx_ForbidChg, kSignalStatus_Low);
}
}
sop_item.sop_data[kSopData_ChgVolt] = req_volt;
}
void bms_set_dis_forbid_status(void)
{
sop_item.dis_forbid_dly = 0;
sop_item.is_dis_forbid = true;
bms_set_signal(kSignalIdx_ForbidDis, kSignalStatus_High);
}
void bms_set_chg_forbid_status(void)
{
sop_item.chg_forbid_dly = 0;
sop_item.is_chg_forbid = true;
bms_set_signal(kSignalIdx_ForbidChg, kSignalStatus_High);
}
void bms_analyse_dis_sop(uint32_t base_time)
{
static uint16_t dly;
uint16_t fault_cur, end_cur, fault_power, end_power,total_volt;
total_volt = bms_get_statistic_data(kStatisticData_TotalVolt) > 500 ? bms_get_statistic_data(kStatisticData_TotalVolt):500;
if(bsp_eeprom_get_data(kEEData_ChgDisMode_HighVoltStrategy, kEepromDataType_High) == kChgMode_CP)
{
end_power = fault_power = sop_item.rate_data[kSopData_DisPower];
end_cur = fault_cur = (uint32_t)sop_item.rate_data[kSopData_DisPower] * 10000 /total_volt;
}
else if(bsp_eeprom_get_data(kEEData_ChgDisMode_HighVoltStrategy, kEepromDataType_High) == kChgMode_CC)
{
end_power = fault_power = (uint32_t)sop_item.rate_data[kSopData_DisCur] * total_volt /100;
end_cur = fault_cur = sop_item.rate_data[kSopData_DisCur];
}
else
{
end_power = 0;
end_cur = 0;
}
//故障降流
if((bms_is_dis_allow() == false)
|| (bms_get_soc_status() == kSocStatus_Empty)
|| (bms_get_circuit_status(kCircuitType_Dis) == kCircuitStatus_Off) )
{
fault_cur = 0;
fault_power = 0;
}
else
{
fault_cur = (uint32_t)fault_cur * bms_get_fault_cur_rate(kRunStatus_Dis) / 100;
fault_power = (uint32_t)fault_power * bms_get_fault_cur_rate(kRunStatus_Dis) / 100;
}
if(fault_cur > end_cur)
{
fault_cur = end_cur;
}
if(fault_power > end_power)
{
fault_power = end_power;
}
sop_item.sop_data[kSopData_DisCur] = fault_cur;
sop_item.sop_data[kSopData_DisPower] = fault_power;
if(fault_cur == 0)
{
dly += base_time;
if(dly >= 500)
{
dly = 500;
if(bms_get_fault_cur_rate(kRunStatus_Dis) != 0)
{
sop_item.dis_forbid_dly = bsp_eeprom_get_data(kEEData_ForbidDisRelDelay, kEepromDataType_Full) * 6000;
}
sop_item.dis_forbid_dly1 = 0;
sop_item.is_dis_forbid = true;
bms_set_signal(kSignalIdx_ForbidDis, kSignalStatus_High);
}
}
else
{
dly = 0;
}
if(sop_item.is_dis_forbid == true)
{
sop_item.dis_forbid_dly += base_time;
sop_item.dis_forbid_dly1 += base_time;
sop_item.sop_data[kSopData_DisCur] = sop_item.sop_data[kSopData_DisPower] = 0;
if((sop_item.dis_forbid_dly1 >= 2000)
&& (sop_item.dis_forbid_dly >= bsp_eeprom_get_data(kEEData_ForbidDisRelDelay, kEepromDataType_Full) * 6000))
{
sop_item.is_dis_forbid = false;
sop_item.dis_forbid_dly1 = 2000;
sop_item.dis_forbid_dly = bsp_eeprom_get_data(kEEData_ForbidDisRelDelay, kEepromDataType_Full) * 6000;
bms_set_signal(kSignalIdx_ForbidDis, kSignalStatus_Low);
}
}
}
void bms_poll_sop(uint32_t base_time)
{
bms_analyse_dis_sop(base_time);
bms_analyse_chg_sop(base_time);
}
void bms_init_sop(void)
{
sop_item.chg_tab_idx = bsp_eeprom_get_data(kEEData_Sop_OcvIndex, kEepromDataType_High);
if(bsp_eeprom_get_data(kEEData_ChgDisMode_HighVoltStrategy, kEepromDataType_High) == kChgMode_CP)
{
sop_item.rate_data[kSopData_DisPower] = bsp_eeprom_get_data(kEEData_RatedDisPower, kEepromDataType_Full);
sop_item.rate_data[kSopData_ChgPower] = bsp_eeprom_get_data(kEEData_RatedChgPower, kEepromDataType_Full);
}
else if(bsp_eeprom_get_data(kEEData_ChgDisMode_HighVoltStrategy, kEepromDataType_High) == kChgMode_CC)
{
sop_item.rate_data[kSopData_DisCur] = bsp_eeprom_get_data(kEEData_RatedDisCur, kEepromDataType_Full);
sop_item.rate_data[kSopData_ChgCur] = bsp_eeprom_get_data(kEEData_RatedChgCur, kEepromDataType_Full);
}
else
{
;
}
sop_item.rate_data[kSopData_ChgVolt] = bsp_eeprom_get_data(kEEData_ReqCghVolt, kEepromDataType_Full);
}