#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); }