BCU/app/stm32fxxx_app/app/statistic_manager.c

230 lines
7.2 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"
uint32_t statistic_data[kStatisticData_End];
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 bms_poll_statistic(uint32_t base_time)
{
bms_statistic_cell_volt();
bms_statistic_cell_temp();
}