272 lines
8.3 KiB
C
272 lines
8.3 KiB
C
#include "kit_data.h"
|
||
#include "bmu_manager.h"
|
||
#include "fault_manager.h"
|
||
#include "eeprom_manager.h"
|
||
#include "statistic_manager.h"
|
||
#include "table_comm.h"
|
||
#include "kit_time.h"
|
||
#include "hv_adc_manager.h"
|
||
|
||
uint32_t statistic_data[kStatisticData_End];
|
||
|
||
typedef struct {
|
||
uint8_t bmu_num;
|
||
uint16_t min_voltage;
|
||
uint16_t max_voltage;
|
||
} voltage_range_t;
|
||
|
||
// 高压堆叠范围对照表(所有电压值已×10)
|
||
const voltage_range_t voltage_ranges[] = {
|
||
{1, 490, 550},
|
||
{2, 980, 1100},
|
||
{3, 1470, 1650},
|
||
{4, 1960, 2200},
|
||
{5, 2450, 2750},
|
||
{6, 2940, 3300},
|
||
{7, 3430, 3850},
|
||
{8, 3920, 4400}
|
||
};
|
||
|
||
uint32_t bms_get_statistic_data(StatisticData idx)
|
||
{
|
||
uint32_t tmp = 0;
|
||
|
||
if(idx < kStatisticData_End)
|
||
{
|
||
tmp = statistic_data[idx];
|
||
}
|
||
return tmp;
|
||
}
|
||
|
||
|
||
static void bms_statistic_cell_volt(void)
|
||
{
|
||
uint32_t i, pack_volt, sum_value = 0, valid_num = 0, max_bmu_idx = 0, min_bmu_idx = 0;
|
||
uint16_t value, max_value = 0, min_value = UINT16_MAX, max_idx = 0, min_idx = 0;
|
||
uint16_t max_pack_volt = 0, min_pack_volt = UINT16_MAX, max_pack_volt_idx = 0, min_pack_volt_idx = 0;
|
||
|
||
|
||
for (i = 0; i < bms_get_bmu_num(); i++) //最高、最低温度
|
||
{
|
||
// if(bms_is_bmu_online(i) == true)
|
||
// {
|
||
valid_num += bms_get_bmu_data(i, kBmuData_CellNum);
|
||
//单位 mV
|
||
pack_volt = bms_get_bmu_statistic_data(i, kBmuStatistic_TotalVolt);
|
||
sum_value += pack_volt;
|
||
pack_volt /= 100;
|
||
|
||
if(pack_volt > max_pack_volt)
|
||
{
|
||
max_pack_volt = pack_volt;
|
||
max_pack_volt_idx = i;
|
||
}
|
||
|
||
if(pack_volt < min_pack_volt)
|
||
{
|
||
min_pack_volt = pack_volt;
|
||
min_pack_volt_idx = i;
|
||
}
|
||
|
||
value = bms_get_bmu_statistic_data(i, kBmuStatistic_MaxVolt);
|
||
if(value > max_value)
|
||
{
|
||
max_bmu_idx = i;
|
||
max_value = value;
|
||
max_idx = bms_get_bmu_statistic_data(i, kBmuStatistic_MaxVoltIdx);
|
||
}
|
||
|
||
|
||
value = bms_get_bmu_statistic_data(i, kBmuStatistic_MinVolt);
|
||
if(value < min_value)
|
||
{
|
||
min_bmu_idx = i;
|
||
min_value = value;
|
||
min_idx = bms_get_bmu_statistic_data(i, kBmuStatistic_MinVoltIdx);
|
||
}
|
||
|
||
// }
|
||
}
|
||
|
||
statistic_data[kStatisticData_AccVolt] = sum_value;
|
||
statistic_data[kStatisticData_TotalVolt] = (sum_value + 50) / 100;
|
||
if(valid_num > 0)
|
||
{
|
||
sum_value /= valid_num;
|
||
}
|
||
|
||
statistic_data[kStatisticData_AvgVolt] = sum_value;
|
||
statistic_data[kStatisticData_MaxVolt] = max_value;
|
||
statistic_data[kStatisticData_MaxVoltIdx] = max_idx;
|
||
statistic_data[kStatisticData_MaxVoltBmuIdx] = max_bmu_idx;
|
||
statistic_data[kStatisticData_MinVolt] = min_value;
|
||
statistic_data[kStatisticData_MinVoltIdx] = min_idx;
|
||
statistic_data[kStatisticData_MinVoltBmuIdx] = min_bmu_idx;
|
||
|
||
statistic_data[kStatisticData_OnlineCellNum] = valid_num;
|
||
statistic_data[kStatisticData_VoltDiff] = max_value - min_value;
|
||
|
||
statistic_data[kStatisticData_MaxPackVolt] = max_pack_volt;
|
||
statistic_data[kStatisticData_MaxPackVoltBmuIdx] = max_pack_volt_idx;
|
||
statistic_data[kStatisticData_MinPackVolt] = min_pack_volt;
|
||
statistic_data[kStatisticData_MinPackVoltBmuIdx] = min_pack_volt_idx;
|
||
}
|
||
|
||
bool bms_is_cell_temp_valid(uint16_t value)
|
||
{
|
||
bool res = true;
|
||
if ((value >= KIT_NTC_TEMP_SHORT_VALUE) || (value <= KIT_NTC_TEMP_OPEN_VALUE))
|
||
{
|
||
res = false;
|
||
}
|
||
return res;
|
||
}
|
||
|
||
typedef struct
|
||
{
|
||
uint8_t dly[BMU_MAX_TEMP_NUM];
|
||
uint16_t last_temp[BMU_MAX_TEMP_NUM];
|
||
uint8_t temp_rise_rate[BMU_MAX_TEMP_NUM];
|
||
}TempRiseItem;
|
||
|
||
TempRiseItem temp_rise;
|
||
|
||
static void bms_statistic_cell_temp(void)
|
||
{
|
||
uint32_t i, sum_value = 0, valid_num = 0, max_bmu_idx = 0, min_bmu_idx = 0;
|
||
uint16_t value, max_value = 0, min_value = 0xFFFF, max_idx = 0, min_idx = 0;
|
||
uint16_t max_pole_value = 0, max_pole_bmu_idx = 0;
|
||
|
||
ExStatus temp_rise_ex = kExStatus_None;
|
||
uint16_t fan_on_temp, fan_off_temp, has_open = false;
|
||
|
||
fan_on_temp = get_eeprom_data(kEep_CoolOn_OffTemp, kEepromDataType_High) * 10;
|
||
fan_off_temp = get_eeprom_data(kEep_CoolOn_OffTemp, kEepromDataType_Low) * 10;
|
||
for (i = 0; i < bms_get_bmu_num(); i++) //最高、最低温度
|
||
{
|
||
// if(bms_is_bmu_online(i) == true)
|
||
// {
|
||
valid_num += bms_get_bmu_data(i, kBmuData_TempNum);
|
||
sum_value += bms_get_bmu_statistic_data(i, kBmuStatistic_TotalTemp);
|
||
|
||
value = bms_get_bmu_statistic_data(i, kBmuStatistic_MaxTemp);
|
||
|
||
if((temp_rise.last_temp[i] < value) && ((value - temp_rise.last_temp[i]) >= 2))
|
||
{
|
||
temp_rise.dly[i]++;
|
||
temp_rise.last_temp[i] = value;
|
||
if(temp_rise.dly[i] > 20)
|
||
{
|
||
temp_rise_ex = kExStatus_Err;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
temp_rise.dly[i] = 0;
|
||
}
|
||
|
||
if(value > max_value)
|
||
{
|
||
max_bmu_idx = i;
|
||
max_value = value;
|
||
max_idx = bms_get_bmu_statistic_data(i, kBmuStatistic_MaxTempIdx);
|
||
}
|
||
|
||
if((value <= fan_off_temp)
|
||
|| (bms_get_fault_level(kFaultCode_Fire) >= kFaultLevel_Second)
|
||
|| (bms_get_fault_level(kFaultCode_AirCondition) >= kFaultLevel_Second))
|
||
{
|
||
bms_set_fan_status(i, false);
|
||
}
|
||
else if((value >= fan_on_temp) && (bms_is_fan_open(i) == false)
|
||
&& (bms_get_fault_level(kFaultCode_Fire) < kFaultLevel_Second)
|
||
&& (bms_get_fault_level(kFaultCode_AirCondition) < kFaultLevel_Second))
|
||
{
|
||
//每次轮询只开一个风扇
|
||
if(has_open == false)
|
||
{
|
||
has_open = true;
|
||
bms_set_fan_status(i, true);
|
||
}
|
||
}
|
||
|
||
|
||
value = bms_get_bmu_statistic_data(i, kBmuStatistic_MinTemp);
|
||
if(value < min_value)
|
||
{
|
||
min_bmu_idx = i;
|
||
min_value = value;
|
||
min_idx = bms_get_bmu_statistic_data(i, kBmuStatistic_MinTempIdx);
|
||
}
|
||
|
||
//极柱温度统计
|
||
value = bms_get_pole_temp_by_bmu(i, 0);
|
||
if(max_pole_value < value)
|
||
{
|
||
max_pole_value = value;
|
||
max_pole_bmu_idx = i;
|
||
}
|
||
|
||
value = bms_get_pole_temp_by_bmu(i, 1);
|
||
if(max_pole_value < value)
|
||
{
|
||
max_pole_value = value;
|
||
max_pole_bmu_idx = i;
|
||
}
|
||
// }
|
||
|
||
}
|
||
|
||
|
||
statistic_data[kStatisticData_AccTemp] = sum_value;
|
||
if(valid_num > 0)
|
||
{
|
||
sum_value /= valid_num;
|
||
}
|
||
bms_set_ex_data(kExType_TempRise, temp_rise_ex);
|
||
statistic_data[kStatisticData_AvgTemp] = sum_value;
|
||
statistic_data[kStatisticData_MaxTemp] = max_value;
|
||
statistic_data[kStatisticData_MaxTempIdx] = max_idx;
|
||
statistic_data[kStatisticData_MaxTempBmuIdx] = max_bmu_idx;
|
||
statistic_data[kStatisticData_MinTemp] = min_value;
|
||
statistic_data[kStatisticData_MinTempIdx] = min_idx;
|
||
statistic_data[kStatisticData_OnlineTempNum] = valid_num;
|
||
statistic_data[kStatisticData_MinTempBmuIdx] = min_bmu_idx;
|
||
statistic_data[kStatisticData_TempDiff] = max_value - min_value;
|
||
statistic_data[kStatisticData_MaxPoleTemp] = max_pole_value;
|
||
statistic_data[kStatisticData_MaxPoleTempBmuIdx] = max_pole_bmu_idx;
|
||
kit_time_dly_ms(2);
|
||
}
|
||
|
||
void update_bmu_number()
|
||
{
|
||
if (bms_get_bmu_num() <= 8)
|
||
{
|
||
uint16_t acc_volt = bms_get_high_volt(kHvType_Bat);
|
||
|
||
for (uint8_t i = 0; i < sizeof(voltage_ranges)/sizeof(voltage_ranges[0]); i++)
|
||
{
|
||
if (acc_volt >= voltage_ranges[i].min_voltage && acc_volt <= voltage_ranges[i].max_voltage)
|
||
{
|
||
if (bms_get_bmu_num() != voltage_ranges[i].bmu_num)
|
||
{
|
||
bms_set_bmu_num(voltage_ranges[i].bmu_num);
|
||
bms_set_bmu_volt_num(voltage_ranges[i].bmu_num);
|
||
bms_set_bmu_temp_num(voltage_ranges[i].bmu_num);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void bms_poll_statistic(uint32_t base_time)
|
||
{
|
||
bms_statistic_cell_volt();
|
||
bms_statistic_cell_temp();
|
||
update_bmu_number();
|
||
}
|
||
|
||
|
||
|