bs_bcu_app/app/app_soc.c

718 lines
22 KiB
C

#include "kit_time.h"
#include "drv_rtc.h"
#include "bms_bmu.h"
#include "bms_ocv.h"
#include "app_soc.h"
#include "bms_fault.h"
#include "bms_signal.h"
#include "bms_eeprom.h"
#include "bms_statistic.h"
#include "bms_run_status.h"
#include "bms_cur_hv.h"
#define SOX_CHG_KEEP_SOC (9900u)
#define SOX_DIS_KEEP_SOC (100u)
#define SOX_MAX_SOC_VALUE (10000u)
#define SOX_MIN_SOC_VALUE (0u)
#define SOX_MAX_SOH_VALUE (10000u)
#define SOX_MIN_SOH_VALUE (0u)
#define SOX_CYCLE_UP_SOC_VALUE (9000u)
#define SOX_CYCLE_DOWN_SOC_VALUE (3000u)
#define SOX_MAX_SIGNAL_INTEGRAL (20000u) //单次积分最大值(2000A*10ms)
#define SOX_SIGNAL_ACC_CAP_VALUE (360000u) //1Ams - 0.1Ah
#define SOX_SIGNAL_ACC_ENERGY_VALUE (360000u) //1kWms - 0.1kWh
typedef enum
{
kSocAdjustStep_Wait,
kSocAdjustStep_Full,
kSocAdjustStep_Empty,
}SocAdjustStep;
typedef struct
{
bool soc_keep_1;
bool soc_keep_99;
bool dis_adjust_flag;
bool chg_adjust_flag;
bool is_bsu_adjust;
SocStatus soc_st;
SocStatus soc_req_st;
SocAdjustStep adjust_step;
uint8_t cyc_flag;
uint8_t dis_adjust_rate;
uint8_t chg_adjust_rate;
uint8_t stat_day;
uint8_t soc_run_diff;
uint8_t soc_run_min;
uint16_t req_soc;
uint16_t show_soc;
uint32_t calculate_cap; //积分计算容量(单位Ams)
uint32_t rated_cap; //额定容量(单位Ams)
uint32_t soc_1_cap; //soc 1%对应容量(单位Ams)
uint32_t soc_99_cap; //soc 99%对应容量(单位Ams)
uint32_t last_tick;
uint32_t tmp_dis_cap; //存储临时放电容量 (单位Ams)
uint32_t tmp_chg_cap; //存储临时充电容量 (单位Ams)
uint32_t tmp_dis_energy;
uint32_t tmp_chg_energy;
uint16_t soc;
uint16_t soh;
uint16_t cycle;
uint32_t data[kCumulateData_End];
}SoxItem;
SoxItem sox_item;
uint16_t bms_get_show_soc(void)
{
return sox_item.show_soc;
}
uint16_t bms_get_soc(void)
{
return sox_item.soc;
}
void bms_set_soc(uint16_t value)
{
sox_item.req_soc = value;
}
uint16_t bms_get_soh(void)
{
return sox_item.soh;
}
uint16_t bms_get_cycle(void)
{
return sox_item.cycle;
}
uint16_t bms_get_cycle_flag(void)
{
return sox_item.cyc_flag;
}
uint8_t bms_get_stat_day(void)
{
return sox_item.stat_day;
}
void bms_set_cycle(uint16_t value)
{
sox_item.cycle = value;
}
SocStatus bms_get_soc_status(void)
{
return sox_item.soc_st;
}
void bms_set_soc_status(SocStatus st)
{
sox_item.soc_req_st = st;
}
uint32_t bms_get_cumulate_data(CumulateData idx)
{
uint32_t tmp = 0;
if(idx < kCumulateData_End)
{
tmp = sox_item.data[idx];
}
return tmp;
}
void bms_set_cumulate_data(CumulateData idx, uint32_t value)
{
if(idx < kCumulateData_End)
{
sox_item.data[idx] = value;
}
}
uint16_t soh_init(uint16_t cycle, uint32_t dis_cap, uint32_t charge_cap)
{
uint16_t soh_loss1 = 0; //充放电次数计算出的SOH损耗百分比
uint16_t soh_loss2 = 0; //累计放电安时计算出的SOH损耗百分比
uint32_t rated_cap = bsp_eeprom_get_data(kEEData_RatedCapacity, kEepromDataType_Full);
uint16_t cycle_70 = bsp_eeprom_get_data(kEEData_SOHSeventyCycle, kEepromDataType_Full);
if(cycle <= 10)
{
return 10000;
}
//单位0.0001/bit
//公式(0.3 / cycle_70) * cycle * 10000
soh_loss1 = (uint32_t)cycle * 3000 / cycle_70;
if (soh_loss1 >= 3000)
{
return 7000;
}
soh_loss2 = (uint16_t)((3000.0 / cycle_70)*(1.0*(dis_cap+charge_cap) / (2*rated_cap)));
if (soh_loss2 >= 3000)
{
return 7000;
}
if (soh_loss1 < soh_loss2)
{
soh_loss1 = SOX_MAX_SOH_VALUE - soh_loss1;
}
else
{
soh_loss1 = SOX_MAX_SOH_VALUE - soh_loss2;
}
return soh_loss1;
}
void cap_data_update(uint16_t base_time)
{
static uint16_t dly = 0;
static uint8_t count = 0;
static uint32_t chg_dly = 0, dis_dly = 0;
uint16_t soc;
RunStatus run_status;
int32_t year, mon, day;
int16_t cur = bms_get_current();
dly += base_time;
if(dly >= KIT_SECOND_CONVERT(1))
{
bms_set_signal(kSignalIdx_SocFull, (SignalStatus)((sox_item.soc_st & kSocStatus_Full) != 0));
bms_set_signal(kSignalIdx_SocEmpty, (SignalStatus)((sox_item.soc_st & kSocStatus_Empty) != 0));
dly -= KIT_SECOND_CONVERT(1);
run_status = bms_get_run_status();
soc = bms_check_run_ocv(KIT_SECOND_CONVERT(1), sox_item.soc);
if(soc != sox_item.soc)
{
bms_set_soc(soc);
}
//累计时间更新
if (run_status == kRunStatus_Chg)
{
chg_dly += KIT_SECOND_CONVERT(1);
if(chg_dly >= KIT_MINUTE_CONVERT(6))
{
chg_dly -= KIT_MINUTE_CONVERT(6);
sox_item.data[kCumulateData_SigChgTime]++;
sox_item.data[kCumulateData_DayChgTime]++;
sox_item.data[kCumulateData_AccChgTime]++;
}
sox_item.data[kCumulateData_SigDisTime] = 0;
}
else if(run_status == kRunStatus_Dis)
{
dis_dly += KIT_SECOND_CONVERT(1);
if(dis_dly >= KIT_MINUTE_CONVERT(6))
{
dis_dly -= KIT_MINUTE_CONVERT(6);
sox_item.data[kCumulateData_SigDisTime]++;
sox_item.data[kCumulateData_DayDisTime]++;
sox_item.data[kCumulateData_AccDisTime]++;
}
sox_item.data[kCumulateData_SigChgTime] = 0;
}
//充放电循环次数更新 <30% >90%
if ((sox_item.soc <= SOX_CYCLE_DOWN_SOC_VALUE) && (sox_item.cyc_flag == 0))
{
sox_item.cycle++;
sox_item.cyc_flag = 1;
}
else if ((sox_item.soc >= SOX_CYCLE_UP_SOC_VALUE) && (sox_item.cyc_flag != 0))
{
sox_item.cyc_flag = 0;
}
//累计容量更新 0.1Ah 更新一次
if (run_status == kRunStatus_Dis)
{
if (sox_item.tmp_dis_cap >= SOX_SIGNAL_ACC_CAP_VALUE)
{
sox_item.data[kCumulateData_SigDisCap]++;
sox_item.data[kCumulateData_AccDisCap]++;
sox_item.data[kCumulateData_DayDisCap]++;
sox_item.tmp_dis_cap -= SOX_SIGNAL_ACC_CAP_VALUE;
}
sox_item.data[kCumulateData_SigChgCap] = 0;
}
else if(run_status == kRunStatus_Chg)
{
if (sox_item.tmp_chg_cap >= SOX_SIGNAL_ACC_CAP_VALUE)
{
sox_item.data[kCumulateData_SigChgCap]++;
sox_item.data[kCumulateData_AccChgCap]++;
sox_item.data[kCumulateData_DayChgCap]++;
sox_item.tmp_chg_cap -= SOX_SIGNAL_ACC_CAP_VALUE;
}
sox_item.data[kCumulateData_SigDisCap] = 0;
}
drv_rtc_get_date(&year, &mon, &day);
if(sox_item.stat_day != day)
{
if(count++ > 5)
{
count = 0;
sox_item.stat_day = day;
sox_item.data[kCumulateData_DayDisCap] = sox_item.data[kCumulateData_DayChgCap] = 0;
sox_item.data[kCumulateData_DayDisTime] = sox_item.data[kCumulateData_DayChgTime] = 0;
sox_item.data[kCumulateData_DayDisEnergy] = sox_item.data[kCumulateData_DayChgEnergy] = 0;
}
}
else
{
count = 0;
}
if (run_status == kRunStatus_Dis)
{
//累计能量更新 0.1kWh 更新一次
while (sox_item.tmp_dis_energy >= SOX_SIGNAL_ACC_ENERGY_VALUE)
{
sox_item.data[kCumulateData_SigDisEnergy]++;
sox_item.data[kCumulateData_AccDisEnergy]++;
sox_item.data[kCumulateData_DayDisEnergy]++;
sox_item.tmp_dis_energy -= SOX_SIGNAL_ACC_ENERGY_VALUE;
}
sox_item.data[kCumulateData_SigChgEnergy] = 0;
}
else if(run_status == kRunStatus_Chg)
{
while (sox_item.tmp_chg_energy >= SOX_SIGNAL_ACC_ENERGY_VALUE)
{
sox_item.data[kCumulateData_SigChgEnergy]++;
sox_item.data[kCumulateData_AccChgEnergy]++;
sox_item.data[kCumulateData_DayChgEnergy]++;
sox_item.tmp_chg_energy -= SOX_SIGNAL_ACC_ENERGY_VALUE;
}
sox_item.data[kCumulateData_SigDisEnergy] = 0;
}
}
}
#define SOC_RUN_CALIBRATE_RATE_MAX 200
#define SOC_RUN_CALIBRATE_RATE_DEF 100
#define SOC_RUN_CALIBRATE_RATE_MIN 50
void soc_run_calibrate(int16_t current, uint16_t base_time)
{
static uint16_t dis_dly = 0;
static uint16_t chg_dly = 0;
uint8_t temp = 0;
//放电
if((current < 0) && (sox_item.dis_adjust_flag == false) &&
(bms_get_statistic_data(kStatisticData_MinVolt) <= 3000) &&
(bms_get_ex_data(kExType_CellVolt) == kExStatus_None))
{
chg_dly = 0;
dis_dly += base_time;
if(dis_dly >= KIT_SECOND_CONVERT(5))
{
sox_item.dis_adjust_flag = true;
temp = sox_item.soc * 100 / 2000;
if(temp > SOC_RUN_CALIBRATE_RATE_MAX)
temp = SOC_RUN_CALIBRATE_RATE_MAX;
else if(temp < SOC_RUN_CALIBRATE_RATE_MIN)
temp = SOC_RUN_CALIBRATE_RATE_MIN;
sox_item.dis_adjust_rate = temp;
}
}
//充电
else if((current > 0) && (sox_item.chg_adjust_flag == false) &&
(bms_get_statistic_data(kStatisticData_MaxVolt) >= 3450) &&
(bms_get_ex_data(kExType_CellVolt) == kExStatus_None))
{
dis_dly = 0;
chg_dly += base_time;
if(chg_dly >= KIT_SECOND_CONVERT(5))
{
sox_item.chg_adjust_flag = true;
temp = 8000 * 100 / sox_item.soc;
if(temp > SOC_RUN_CALIBRATE_RATE_MAX)
temp = SOC_RUN_CALIBRATE_RATE_MAX;
else if(temp < SOC_RUN_CALIBRATE_RATE_MIN)
temp = SOC_RUN_CALIBRATE_RATE_MIN;
sox_item.chg_adjust_rate = temp;
}
}
else
{
dis_dly = chg_dly = 0;
}
}
#define SOC_SMOOTH_ADJUST 0
void soc_exterme_calibrate(int16_t current, uint16_t base_time)
{
static uint16_t full_dly = 0;
static uint16_t empty_dly = 0;
uint16_t avg_volt, total_volt;
uint32_t tmp_soc = sox_item.soc;
if((bms_get_ex_data(kExType_CellVolt) != kExStatus_None)
|| (bms_get_bmu_fault_bit(kBmuFaultBit_Offline) != 0))
{
empty_dly = 0;
full_dly = 0;
return;
}
switch(sox_item.adjust_step)
{
case kSocAdjustStep_Wait:
avg_volt = bms_get_statistic_data(kStatisticData_AvgVolt);
total_volt = bms_get_statistic_data(kStatisticData_AccVolt) / 100;
if (((bms_get_statistic_data(kStatisticData_MinVolt) <= bsp_eeprom_get_data(kEEData_FullDisVolt, kEepromDataType_Full))
&& (avg_volt <= bsp_eeprom_get_data(kEEData_FullDisAvgVolt, kEepromDataType_Full))
&& (bms_get_ex_data(kExType_CellVolt) == kExStatus_None))
|| (total_volt <= bsp_eeprom_get_data(kEEData_FullDisTotalVolt, kEepromDataType_Full))
|| ((sox_item.soc_req_st == kSocStatus_Empty) && (sox_item.is_bsu_adjust == false)))
{
full_dly = 0;
empty_dly += base_time;
if (empty_dly >= KIT_SECOND_CONVERT(1))
{
empty_dly = 0;
sox_item.soc_st = kSocStatus_Empty;
sox_item.calculate_cap = 0;
sox_item.soc_keep_1 = false;
sox_item.is_bsu_adjust = true;
#if (SOC_SMOOTH_ADJUST == 1)
sox_item.adjust_step = kSocAdjustStep_Empty;
#else
tmp_soc = SOX_MIN_SOC_VALUE;
#endif
}
}
else if (((bms_get_statistic_data(kStatisticData_MaxVolt) >= bsp_eeprom_get_data(kEEData_FullChgVolt, kEepromDataType_Full))
&& (avg_volt >= bsp_eeprom_get_data(kEEData_FullChgAvgVolt, kEepromDataType_Full))
&& (bms_get_ex_data(kExType_CellVolt) == kExStatus_None))
|| (total_volt >= bsp_eeprom_get_data(kEEData_FullChgTotalVolt, kEepromDataType_Full))
|| ((sox_item.soc_req_st == kSocStatus_Full) && (sox_item.is_bsu_adjust == false)))
{
empty_dly = 0;
full_dly += base_time;
if (full_dly >= KIT_SECOND_CONVERT(1))
{
full_dly = 0;
sox_item.soc_st = kSocStatus_Full;
sox_item.calculate_cap = sox_item.rated_cap;
sox_item.soc_keep_99 = false;
sox_item.is_bsu_adjust = true;
#if (SOC_SMOOTH_ADJUST == 1)
sox_item.adjust_step = kSocAdjustStep_Full;
#else
tmp_soc = SOX_MAX_SOC_VALUE;
#endif
}
}
else
{
empty_dly = 0;
full_dly = 0;
}
break;
#if (SOC_SMOOTH_ADJUST == 1)
case kSocAdjustStep_Full:
full_dly += base_time;
if (full_dly >= 1000)
{
full_dly = 0;
tmp_soc++ ;
if(tmp_soc >= SOX_MAX_SOC_VALUE)
sox_item.adjust_step = kSocAdjustStep_Wait;
}
break;
case kSocAdjustStep_Empty:
empty_dly += base_time;
if (empty_dly >= 1000)
{
empty_dly = 0;
if(tmp_soc > SOX_MIN_SOC_VALUE)
{
tmp_soc-- ;
}
else
sox_item.adjust_step = kSocAdjustStep_Wait;
}
break;
#endif
default:
sox_item.adjust_step = kSocAdjustStep_Wait;
break;
}
sox_item.soc = tmp_soc;
}
void bms_init_soc(void)
{
uint32_t soc;
uint64_t tmp_64u;
int32_t year, mon, day;
soc = bsp_eeprom_get_data(kEEData_SOC, kEepromDataType_Full);
soc = bms_check_pwr_on_ocv(soc);
sox_item.soc_keep_99 = true;
sox_item.soc_keep_1 = true;
if (soc == 0)
{
sox_item.soc_keep_1 = false;
}
else if (soc == SOX_MAX_SOC_VALUE)
{
sox_item.soc_keep_99 = false;
}
sox_item.req_soc = 0xFFFF;
sox_item.soc_st = kSocStatus_Normal;
sox_item.adjust_step = kSocAdjustStep_Wait;
sox_item.tmp_chg_cap = sox_item.tmp_dis_cap = 0;
sox_item.tmp_chg_energy = sox_item.tmp_dis_energy = 0;
sox_item.dis_adjust_flag = sox_item.chg_adjust_flag = false;
sox_item.dis_adjust_rate = sox_item.chg_adjust_rate = SOC_RUN_CALIBRATE_RATE_DEF;
sox_item.soc = soc;
year = bsp_eeprom_get_data(kEE_SOCRunMax_Min, kEepromDataType_Low);
mon = bsp_eeprom_get_data(kEE_SOCRunMax_Min, kEepromDataType_High);
if((year < mon) && (year >= 0) && (mon <= 100))
{
sox_item.soc_run_min = year;
sox_item.soc_run_diff = mon - year;
}
else
{
sox_item.soc_run_min = 0;
sox_item.soc_run_diff = 100;
}
tmp_64u = SOX_CONVERT_AH_TO_AMS(bsp_eeprom_get_data(kEEData_RatedCapacity, kEepromDataType_Full)) * sox_item.soc_run_diff / 100;
sox_item.rated_cap = tmp_64u;
sox_item.soc_1_cap = (SOX_DIS_KEEP_SOC * tmp_64u) / SOX_MAX_SOC_VALUE;
sox_item.soc_99_cap = (SOX_CHG_KEEP_SOC * tmp_64u) / SOX_MAX_SOC_VALUE;
sox_item.calculate_cap = (soc * tmp_64u) / SOX_MAX_SOC_VALUE;
sox_item.cycle = bsp_eeprom_get_data(kEEData_CycleTimes, kEepromDataType_Full);
sox_item.cyc_flag = bsp_eeprom_get_data(kEEData_StatDay_CycleTimesFlag, kEepromDataType_Low);
sox_item.stat_day = bsp_eeprom_get_data(kEEData_StatDay_CycleTimesFlag, kEepromDataType_High);
drv_rtc_get_date(&year, &mon, &day);
if(sox_item.stat_day == day)
{
sox_item.data[kCumulateData_DayDisCap] = bsp_eeprom_get_data(kEEData_DayDisCapL, kEepromDataType_Double);
sox_item.data[kCumulateData_DayChgCap] = bsp_eeprom_get_data(kEEData_DayChgCapL, kEepromDataType_Double);
sox_item.data[kCumulateData_DayDisTime] = bsp_eeprom_get_data(kEEData_DayChg_DisTime, kEepromDataType_Low);
sox_item.data[kCumulateData_DayChgTime] = bsp_eeprom_get_data(kEEData_DayChg_DisTime, kEepromDataType_High);
sox_item.data[kCumulateData_DayChgEnergy] = bsp_eeprom_get_data(kEEData_DayChgEnergyL, kEepromDataType_Double);
sox_item.data[kCumulateData_DayDisEnergy] = bsp_eeprom_get_data(kEEData_DayDisEnergyL, kEepromDataType_Double);
}
sox_item.data[kCumulateData_AccChgCap] = bsp_eeprom_get_data(kEEData_AccChgCapL, kEepromDataType_Double);
sox_item.data[kCumulateData_AccDisCap] = bsp_eeprom_get_data(kEEData_AccDisCapL, kEepromDataType_Double);
sox_item.data[kCumulateData_AccChgTime] = bsp_eeprom_get_data(kEEData_AccChgTimeL, kEepromDataType_Double);
sox_item.data[kCumulateData_AccDisTime] = bsp_eeprom_get_data(kEEData_AccDisTimeL, kEepromDataType_Double);
sox_item.data[kCumulateData_AccChgEnergy] = bsp_eeprom_get_data(kEEData_AccChgEnergyL, kEepromDataType_Double);
sox_item.data[kCumulateData_AccDisEnergy] = bsp_eeprom_get_data(kEEData_AccDisEnergyL, kEepromDataType_Double);
sox_item.soh = soh_init(sox_item.cycle, sox_item.data[kCumulateData_AccDisCap],sox_item.data[kCumulateData_AccChgCap]);
sox_item.last_tick = kit_time_get_tick();
}
void bms_poll_soh(uint32_t base_time)
{
static uint16_t dly;
dly += base_time;
if(dly >= 5000)
{
dly = 0;
sox_item.soh = soh_init(sox_item.cycle, sox_item.data[kCumulateData_AccDisCap],sox_item.data[kCumulateData_AccChgCap]);
}
}
/*****************************************************************************
积分电流单位 0.01A/bit
******************************************************************************/
void bms_integral_soc(int32_t current, uint16_t base_time)
{
uint16_t soc = sox_item.soc;
uint16_t integral_time = 0, total_volt;
uint32_t tmp_32u = 0;
cap_data_update(base_time);
soc_exterme_calibrate(current, base_time);
if(sox_item.adjust_step != kSocAdjustStep_Wait)
return;
tmp_32u = kit_time_get_tick();
integral_time = kit_time_get_interval(sox_item.last_tick, tmp_32u);
sox_item.last_tick = tmp_32u;
total_volt = bms_get_high_volt(kHvType_Bat);
if(sox_item.soc_req_st == kSocStatus_Normal)
{
sox_item.is_bsu_adjust = false;
}
if((sox_item.soc >= 1000)
|| (bms_get_statistic_data(kStatisticData_MinVolt) >= bsp_eeprom_get_data(kEEData_ForbidDisRelVolt, kEepromDataType_Full)))
{
sox_item.soc_keep_1 = true;
sox_item.dis_adjust_flag = false;
sox_item.dis_adjust_rate = SOC_RUN_CALIBRATE_RATE_DEF;
KIT_CLR_BIT(sox_item.soc_st, 1);
}
//充电积分
if(current > 0)
{
//单位Ams
//公式 (current / 100 * integral_time) * (sox_item.chg_adjust_rate / 100)
if(current >= bsp_eeprom_get_data(kEE_SelfConsumpCurrent, kEepromDataType_Full))
{
current = current - bsp_eeprom_get_data(kEE_SelfConsumpCurrent, kEepromDataType_Full);
}
tmp_32u = current * integral_time * sox_item.chg_adjust_rate / 10000;
if (tmp_32u > SOX_MAX_SIGNAL_INTEGRAL)
tmp_32u = SOX_MAX_SIGNAL_INTEGRAL;
sox_item.tmp_chg_cap += tmp_32u;
//单位 kWms
sox_item.tmp_chg_energy += tmp_32u * total_volt / 10000;
if(sox_item.calculate_cap < sox_item.rated_cap)
{
tmp_32u += sox_item.calculate_cap;
if(tmp_32u > sox_item.soc_99_cap)
{
if (sox_item.soc_keep_99 == true)
{
sox_item.calculate_cap = sox_item.soc_99_cap;
}
else if(tmp_32u > sox_item.rated_cap)
{
sox_item.calculate_cap = sox_item.rated_cap;
}
else
{
sox_item.calculate_cap = tmp_32u;
}
}
else
{
sox_item.calculate_cap = tmp_32u;
}
}
}
if((sox_item.soc <= 9500)
|| (bms_get_statistic_data(kStatisticData_MaxVolt) <= bsp_eeprom_get_data(kEEData_ForbidChgRelVolt, kEepromDataType_Full)))
{
sox_item.soc_keep_99 = true;
sox_item.chg_adjust_flag = false;
sox_item.chg_adjust_rate = SOC_RUN_CALIBRATE_RATE_DEF;
KIT_CLR_BIT(sox_item.soc_st, 0);
}
//放电积分
if(current < 0)
{
current = KIT_ABS(current) + bsp_eeprom_get_data(kEE_SelfConsumpCurrent, kEepromDataType_Full);
tmp_32u = (current + bsp_eeprom_get_data(kEE_SelfConsumpCurrent, kEepromDataType_Full)) * integral_time * sox_item.dis_adjust_rate / 10000;
if (tmp_32u > SOX_MAX_SIGNAL_INTEGRAL)
tmp_32u = SOX_MAX_SIGNAL_INTEGRAL;
sox_item.tmp_dis_cap += tmp_32u;
//单位 kWms
sox_item.tmp_dis_energy += tmp_32u * total_volt / 10000;
if(sox_item.calculate_cap > 0)
{
if (sox_item.calculate_cap < (sox_item.soc_1_cap + tmp_32u))
{
if (sox_item.soc_keep_1 == true)
{
sox_item.calculate_cap = sox_item.soc_1_cap;
}
else if(tmp_32u >= sox_item.calculate_cap)
{
sox_item.calculate_cap = 0;
}
else
{
sox_item.calculate_cap -= tmp_32u;
}
}
else
{
sox_item.calculate_cap -= tmp_32u;
}
}
}
if (sox_item.req_soc == 0xFFFF)
{
soc = (((uint64_t)sox_item.calculate_cap * SOX_MAX_SOC_VALUE * 10 / sox_item.rated_cap + 5)/10); //四舍五入
}
else
{
if (soc != sox_item.req_soc)
{
soc = sox_item.req_soc;
sox_item.calculate_cap = ((uint64_t)soc * sox_item.rated_cap) / SOX_MAX_SOC_VALUE;
if(sox_item.req_soc == SOX_MAX_SOC_VALUE)
sox_item.soc_keep_99 = false;
else if(sox_item.req_soc == SOX_MIN_SOC_VALUE)
sox_item.soc_keep_1 = false;
}
sox_item.req_soc = 0xFFFF;
}
if (soc > SOX_MAX_SOC_VALUE)
{
soc = SOX_MAX_SOC_VALUE;
}
sox_item.soc = soc;
//计算显示soc
sox_item.show_soc = (uint32_t)sox_item.soc_run_diff * soc / 100 + sox_item.soc_run_min * 100;
}