forked from gary/BCU
2
0
Fork 0
BCU/app/stm32fxxx_app/app/statistic_manager.c

272 lines
8.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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