#include "SOH.h" void SOH_Init(void) { sohd_flg_firstRun = true; } void SOH(void) { uint16_T i; uint16_T cellCapArr_Min; uint16_T cellCapArr_Max; uint16_T packCapArr_Min; uint16_T packCapArr_Max; static uint16_T sohn_V_chrgStartStatEE[cmnc_num_cellUNumMax]; static uint16_T sohn_Q_cellCapArrEE[cmnc_num_cellUNumMax]; static uint16_T sohn_Q_packCapArrEE[10]; static uint16_T sohn_Q_chrgEE; static uint16_T sohn_tm_chrgStartStatEE; static uint16_T sohn_flg_chrgEndEE; // boolean_T sohn_flg_countEn; uint16_T soc1[cmnc_num_cellUNumMax]; uint16_T soc2[cmnc_num_cellUNumMax]; uint16_T deltSoc[cmnc_num_cellUNumMax]; uint16_T temp[cmnc_num_cellUNumMax]; uint16_T chrgCellCapArr[cmnc_num_cellUNumMax]; uint16_T disChrgCellCapArr[cmnc_num_cellUNumMax]; boolean_T sohn_flg_update; uint16_T chrgCap_Min; uint16_T disChrgCap_Min; uint16_T SumQ; // static uint16_T sohn_V_chrgStartStat[cmnc_num_cellUNumMax]; static uint8_T sohn_st_workStat_Delay; // static real_T Ahincr; int16_T tmp_0; static boolean_T sfmn_flg_currFlt_keep; static boolean_T sohn_flg_currFlt; boolean_T DisEn; //初值 if (sohd_flg_firstRun) { sohn_flg_update = true; sfmn_flg_currFlt_keep = false; sohn_flg_currFlt = false; Ahincr = 0; sohn_st_workStat_Delay = 0; if (ihd_st_reSet == 1) { memcpy(sohv_V_chrgStartStatEo, sohv_V_chrgStartStatEi, sizeof(sohv_V_chrgStartStatEo)); sohd_Q_chrgEo = sohd_Q_chrgEi; sohd_flg_chrgEndEo = sohd_flg_chrgEndEi; } else { memset(sohv_V_chrgStartStatEo, 0, sizeof(sohv_V_chrgStartStatEo)); sohd_Q_chrgEo = 0; sohd_flg_chrgEndEo = 0; } } if (sohd_flg_firstRun) { //======================================================================================= //--------------------------EE校验------------------------------------------------------- //======================================================================================= cellCapArr_Min = ArrMin(sohv_Q_cellCapArrEi, cmnc_num_cellUNum); cellCapArr_Max = ArrMax(sohv_Q_cellCapArrEi, cmnc_num_cellUNum); packCapArr_Min = ArrMin(sohv_Q_packCapArrEi, 10); packCapArr_Max = ArrMax(sohv_Q_packCapArrEi, 10); if (sohd_Q_chrgEi > cmnc_Q_ratedCp || cellCapArr_Min < 10 || cellCapArr_Max > cmnc_Q_ratedCp + 100 || packCapArr_Min < 10 || packCapArr_Max > cmnc_Q_ratedCp + 100) { memset(sohn_V_chrgStartStatEE, 0, sizeof(sohn_V_chrgStartStatEE)); for (i = 0; i < cmnc_num_cellUNum; i++) { sohn_Q_cellCapArrEE[i] = cmnc_Q_ratedCp; } for (i = 0; i < 10; i++) { sohn_Q_packCapArrEE[i] = cmnc_Q_ratedCp; } sohn_Q_chrgEE = 0; sohn_tm_chrgStartStatEE = 0; sohn_flg_chrgEndEE = 0; } else { memcpy(sohn_V_chrgStartStatEE, sohv_V_chrgStartStatEi, sizeof(sohv_V_chrgStartStatEi)); memcpy(sohn_Q_cellCapArrEE, sohv_Q_cellCapArrEi, sizeof(sohv_Q_cellCapArrEi)); memcpy(sohn_Q_packCapArrEE, sohv_Q_packCapArrEi, sizeof(sohv_Q_packCapArrEi)); sohn_Q_chrgEE = sohd_Q_chrgEi; sohn_tm_chrgStartStatEE = sohd_tm_chrgStartStatEi; sohn_flg_chrgEndEE = sohd_flg_chrgEndEi; } //======================================================================================= //--------------------------计算使能------------------------------------------------------- //======================================================================================= if (ihd_tm_parkTime >= cmnc_tm_parkTime && sohn_flg_chrgEndEE && sohn_Q_chrgEE > sohc_Q_countThr && !sfmd_flg_cellUInval && sfmd_I_curr < 10 && sfmd_I_curr > -10 && ArrMin(sohn_V_chrgStartStatEE, cmnc_num_cellUNum) > 3300) { sohn_flg_countEn = true; sohd_flg_chrgEndEo = 0; } else { sohn_flg_countEn = false; } //======================================================================================= //------------------------SOH 计算------------------------------------------------------- //======================================================================================= if (sohn_flg_countEn) { sohn_flg_update = true; for (i = 0; i < cmnc_num_cellUNum; i++) { soc2[i] = look1_u16tu16(sfmv_V_cellU[i], cmnm_V_ocv, cmnm_pct_soc, 13U); soc1[i] = look1_u16tu16(sohn_V_chrgStartStatEE[i], cmnm_V_ocv, cmnm_pct_soc, 13U); deltSoc[i] = soc2[i] - soc1[i]; sohv_Q_cellCapArrEo[i] = (uint16_T)((real_T)(sohn_Q_chrgEE * 0.1) / (real_T)(deltSoc[i] * 0.1 / 100) * 10); if ((int16_T)(sohv_Q_cellCapArrEo[i]) - sohn_Q_cellCapArrEE[i] > sohc_Q_updateDeltThr || (int16_T)(sohv_Q_cellCapArrEo[i]) - sohn_Q_cellCapArrEE[i] < -sohc_Q_updateDeltThr) { sohn_flg_update = false; break; } } DisEn = (ArrMin(soc2, cmnc_num_cellUNum) > sohc_pct_low && ArrMin(soc2, cmnc_num_cellUNum) < sohc_pct_up) || (ArrMax(soc2, cmnc_num_cellUNum) > sohc_pct_low && ArrMax(soc2, cmnc_num_cellUNum) < sohc_pct_up) || (ArrMin(soc1, cmnc_num_cellUNum) > sohc_pct_low && ArrMin(soc1, cmnc_num_cellUNum) < sohc_pct_up) || (ArrMax(soc1, cmnc_num_cellUNum) > sohc_pct_low && ArrMax(soc1, cmnc_num_cellUNum) < sohc_pct_up); //=================== if (sohn_flg_update && !DisEn) { for (i = 0; i < cmnc_num_cellUNum; i++) { chrgCellCapArr[i] = (uint16_T)((uint32_T)(sohv_Q_cellCapArrEo[i] * (1000 - soc2[i])) / 1000); disChrgCellCapArr[i] = (uint16_T)((uint32_T)(sohv_Q_cellCapArrEo[i] * (soc2[i])) / 1000); } chrgCap_Min = ArrMin(chrgCellCapArr, cmnc_num_cellUNum); disChrgCap_Min = ArrMin(disChrgCellCapArr, cmnc_num_cellUNum); for (i = 0; i < 9; i++) { sohv_Q_packCapArrEo[i] = sohn_Q_packCapArrEE[i + 1]; } sohv_Q_packCapArrEo[9] = chrgCap_Min + disChrgCap_Min; } else //计算但结果偏差较大 { memcpy(sohv_Q_packCapArrEo, sohn_Q_packCapArrEE, sizeof(sohv_Q_packCapArrEo)); memcpy(sohv_Q_cellCapArrEo, sohn_Q_cellCapArrEE, sizeof(sohv_Q_cellCapArrEo)); } } else // 不计算 { memcpy(sohv_Q_packCapArrEo, sohn_Q_packCapArrEE, sizeof(sohv_Q_packCapArrEo)); memcpy(sohv_Q_cellCapArrEo, sohn_Q_cellCapArrEE, sizeof(sohv_Q_cellCapArrEo)); } memcpy(sohv_Q_cellCap, sohv_Q_cellCapArrEo, sizeof(sohv_Q_cellCapArrEo)); SumQ = 0; for (i = 0; i < 10; i++) { SumQ = SumQ + sohv_Q_packCapArrEo[i]; } sohd_pct_bcuSoh = (uint16_T)(((real_T)(SumQ * 0.1) / 10.0 / (real_T)(cmnc_Q_ratedCp * 0.1) * 100) * 10); sohd_pct_bcuSoh = (sohd_pct_bcuSoh > 1000 ? 1000 : sohd_pct_bcuSoh); } //======================================================================================= //----------------------充电前信息------------------------------------------------------- //======================================================================================= if (sohd_flg_firstRun) { memcpy(sohn_V_chrgStartStat, appv_V_cellU, sizeof(appv_V_cellU)); } if (sfmd_I_curr < 10 && sfmd_I_curr > -10 && !sfmd_flg_cellUInval) { memcpy(sohn_V_chrgStartStat, sfmv_V_cellU, sizeof(sfmv_V_cellU)); } // if ((ihd_st_workStat == 2) && (sohn_st_workStat_Delay != 2)) { memcpy(sohv_V_chrgStartStatEo, sohn_V_chrgStartStat, sizeof(sohv_V_chrgStartStatEo)); } // printf("sohv_V_chrgStartStatEo[16]:%d\n",sohv_V_chrgStartStatEo[16]); //======================================================================================= //----------------------充电中信息------------------------------------------------------- //======================================================================================= if (ihd_st_workStat == 2) { Ahincr = Ahincr + (real_T)sfmd_I_curr * 0.1; tmp_0 = (int16_T)(Ahincr / 3600 * 10); sohd_Q_chrgEo = tmp_0 > 0 ? (uint16_T)tmp_0 : 0; if (sfmd_flg_currInval) { sfmn_flg_currFlt_keep = true; } sohn_flg_currFlt = sfmn_flg_currFlt_keep; } else { sfmn_flg_currFlt_keep = false; Ahincr = 0; } //======================================================================================= //----------------------充电结速信息------------------------------------------------------ //======================================================================================= if ((ihd_st_workStat != 2) && (sohn_st_workStat_Delay == 2)) { sohd_flg_chrgEndEo = true; } else { sohd_flg_chrgEndEo = (sfmd_I_curr < 10 && sfmd_I_curr > -10) && sohd_flg_chrgEndEo; } sohd_flg_chrgEndEo = !sohn_flg_currFlt && sohd_flg_chrgEndEo; // sohn_st_workStat_Delay = ihd_st_workStat; sohd_flg_firstRun = false; }