SOH.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include "SOH.h"
  2. void SOH_Init(void)
  3. {
  4. sohd_flg_firstRun = true;
  5. }
  6. void SOH(void)
  7. {
  8. uint16_T i;
  9. uint16_T cellCapArr_Min;
  10. uint16_T cellCapArr_Max;
  11. uint16_T packCapArr_Min;
  12. uint16_T packCapArr_Max;
  13. static uint16_T sohn_V_chrgStartStatEE[cmnc_num_cellUNumMax];
  14. static uint16_T sohn_Q_cellCapArrEE[cmnc_num_cellUNumMax];
  15. static uint16_T sohn_Q_packCapArrEE[10];
  16. static uint16_T sohn_Q_chrgEE;
  17. static uint16_T sohn_tm_chrgStartStatEE;
  18. static uint16_T sohn_flg_chrgEndEE;
  19. //
  20. boolean_T sohn_flg_countEn;
  21. uint16_T soc1[cmnc_num_cellUNumMax];
  22. uint16_T soc2[cmnc_num_cellUNumMax];
  23. uint16_T deltSoc[cmnc_num_cellUNumMax];
  24. uint16_T temp[cmnc_num_cellUNumMax];
  25. uint16_T chrgCellCapArr[cmnc_num_cellUNumMax];
  26. uint16_T disChrgCellCapArr[cmnc_num_cellUNumMax];
  27. boolean_T sohn_flg_update;
  28. uint16_T chrgCap_Min;
  29. uint16_T disChrgCap_Min;
  30. uint16_T SumQ;
  31. //
  32. static uint16_T sohn_V_chrgStartStat[cmnc_num_cellUNumMax];
  33. static uint8_T sohn_st_workStat_Delay;
  34. //
  35. static real_T Ahincr;
  36. int16_T tmp_0;
  37. static boolean_T sfmn_flg_currFlt_keep;
  38. static boolean_T sohn_flg_currFlt;
  39. boolean_T DisEn;
  40. //初值
  41. if (sohd_flg_firstRun)
  42. {
  43. sohn_flg_update = true;
  44. sfmn_flg_currFlt_keep = false;
  45. sohn_flg_currFlt = false;
  46. Ahincr = 0;
  47. sohn_st_workStat_Delay = 0;
  48. if (ihd_st_reSet == 1)
  49. {
  50. memcpy(sohv_V_chrgStartStatEo, sohv_V_chrgStartStatEi, sizeof(sohv_V_chrgStartStatEo));
  51. sohd_Q_chrgEo = sohd_Q_chrgEi;
  52. sohd_flg_chrgEndEo = sohd_flg_chrgEndEi;
  53. }
  54. else
  55. {
  56. memset(sohv_V_chrgStartStatEo, 0, sizeof(sohv_V_chrgStartStatEo));
  57. sohd_Q_chrgEo = 0;
  58. sohd_flg_chrgEndEo = 0;
  59. }
  60. }
  61. if (sohd_flg_firstRun)
  62. {
  63. //=======================================================================================
  64. //--------------------------EE校验-------------------------------------------------------
  65. //=======================================================================================
  66. cellCapArr_Min = ArrMin(sohv_Q_cellCapArrEi, cmnc_num_cellUNum);
  67. cellCapArr_Max = ArrMax(sohv_Q_cellCapArrEi, cmnc_num_cellUNum);
  68. packCapArr_Min = ArrMin(sohv_Q_packCapArrEi, 10);
  69. packCapArr_Max = ArrMax(sohv_Q_packCapArrEi, 10);
  70. 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)
  71. {
  72. memset(sohn_V_chrgStartStatEE, 0, sizeof(sohn_V_chrgStartStatEE));
  73. for (i = 0; i < cmnc_num_cellUNum; i++)
  74. {
  75. sohn_Q_cellCapArrEE[i] = cmnc_Q_ratedCp;
  76. }
  77. for (i = 0; i < 10; i++)
  78. {
  79. sohn_Q_packCapArrEE[i] = cmnc_Q_ratedCp;
  80. }
  81. sohn_Q_chrgEE = 0;
  82. sohn_tm_chrgStartStatEE = 0;
  83. sohn_flg_chrgEndEE = 0;
  84. }
  85. else
  86. {
  87. memcpy(sohn_V_chrgStartStatEE, sohv_V_chrgStartStatEi, sizeof(sohv_V_chrgStartStatEi));
  88. memcpy(sohn_Q_cellCapArrEE, sohv_Q_cellCapArrEi, sizeof(sohv_Q_cellCapArrEi));
  89. memcpy(sohn_Q_packCapArrEE, sohv_Q_packCapArrEi, sizeof(sohv_Q_packCapArrEi));
  90. sohn_Q_chrgEE = sohd_Q_chrgEi;
  91. sohn_tm_chrgStartStatEE = sohd_tm_chrgStartStatEi;
  92. sohn_flg_chrgEndEE = sohd_flg_chrgEndEi;
  93. }
  94. //=======================================================================================
  95. //--------------------------计算使能-------------------------------------------------------
  96. //=======================================================================================
  97. 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)
  98. {
  99. sohn_flg_countEn = true;
  100. sohd_flg_chrgEndEo = 0;
  101. }
  102. else
  103. {
  104. sohn_flg_countEn = false;
  105. }
  106. //=======================================================================================
  107. //------------------------SOH 计算-------------------------------------------------------
  108. //=======================================================================================
  109. if (sohn_flg_countEn)
  110. {
  111. sohn_flg_update = true;
  112. for (i = 0; i < cmnc_num_cellUNum; i++)
  113. {
  114. soc2[i] = look1_u16tu16(sfmv_V_cellU[i], cmnm_V_ocv, cmnm_pct_soc, 13U);
  115. soc1[i] = look1_u16tu16(sohn_V_chrgStartStatEE[i], cmnm_V_ocv, cmnm_pct_soc, 13U);
  116. deltSoc[i] = soc2[i] - soc1[i];
  117. sohv_Q_cellCapArrEo[i] = (uint16_T)((real_T)(sohn_Q_chrgEE * 0.1) / (real_T)(deltSoc[i] * 0.1 / 100) * 10);
  118. 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)
  119. {
  120. sohn_flg_update = false;
  121. break;
  122. }
  123. }
  124. 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);
  125. //===================
  126. if (sohn_flg_update && !DisEn)
  127. {
  128. for (i = 0; i < cmnc_num_cellUNum; i++)
  129. {
  130. chrgCellCapArr[i] = (uint16_T)((uint32_T)(sohv_Q_cellCapArrEo[i] * (1000 - soc2[i])) / 1000);
  131. disChrgCellCapArr[i] = (uint16_T)((uint32_T)(sohv_Q_cellCapArrEo[i] * (soc2[i])) / 1000);
  132. }
  133. chrgCap_Min = ArrMin(chrgCellCapArr, cmnc_num_cellUNum);
  134. disChrgCap_Min = ArrMin(disChrgCellCapArr, cmnc_num_cellUNum);
  135. for (i = 0; i < 9; i++)
  136. {
  137. sohv_Q_packCapArrEo[i] = sohn_Q_packCapArrEE[i + 1];
  138. }
  139. sohv_Q_packCapArrEo[9] = chrgCap_Min + disChrgCap_Min;
  140. }
  141. else //计算但结果偏差较大
  142. {
  143. memcpy(sohv_Q_packCapArrEo, sohn_Q_packCapArrEE, sizeof(sohv_Q_packCapArrEo));
  144. memcpy(sohv_Q_cellCapArrEo, sohn_Q_cellCapArrEE, sizeof(sohv_Q_cellCapArrEo));
  145. }
  146. }
  147. else // 不计算
  148. {
  149. memcpy(sohv_Q_packCapArrEo, sohn_Q_packCapArrEE, sizeof(sohv_Q_packCapArrEo));
  150. memcpy(sohv_Q_cellCapArrEo, sohn_Q_cellCapArrEE, sizeof(sohv_Q_cellCapArrEo));
  151. }
  152. memcpy(sohv_Q_cellCap, sohv_Q_cellCapArrEo, sizeof(sohv_Q_cellCapArrEo));
  153. SumQ = 0;
  154. for (i = 0; i < 10; i++)
  155. {
  156. SumQ = SumQ + sohv_Q_packCapArrEo[i];
  157. }
  158. sohd_pct_bcuSoh = (uint16_T)(((real_T)(SumQ * 0.1) / 10.0 / (real_T)(cmnc_Q_ratedCp * 0.1) * 100) * 10);
  159. sohd_pct_bcuSoh = (sohd_pct_bcuSoh > 1000 ? 1000 : sohd_pct_bcuSoh);
  160. }
  161. //=======================================================================================
  162. //----------------------充电前信息-------------------------------------------------------
  163. //=======================================================================================
  164. if (sohd_flg_firstRun)
  165. {
  166. memcpy(sohn_V_chrgStartStat, appv_V_cellU, sizeof(appv_V_cellU));
  167. }
  168. if (sfmd_I_curr < 10 && sfmd_I_curr > -10 && !sfmd_flg_cellUInval)
  169. {
  170. memcpy(sohn_V_chrgStartStat, sfmv_V_cellU, sizeof(sfmv_V_cellU));
  171. }
  172. //
  173. if ((ihd_st_workStat == 2) && (sohn_st_workStat_Delay != 2))
  174. {
  175. memcpy(sohv_V_chrgStartStatEo, sohn_V_chrgStartStat, sizeof(sohv_V_chrgStartStatEo));
  176. }
  177. // printf("sohv_V_chrgStartStatEo[16]:%d\n",sohv_V_chrgStartStatEo[16]);
  178. //=======================================================================================
  179. //----------------------充电中信息-------------------------------------------------------
  180. //=======================================================================================
  181. if (ihd_st_workStat == 2)
  182. {
  183. Ahincr = Ahincr + (real_T)sfmd_I_curr * 0.1;
  184. tmp_0 = (int16_T)(Ahincr / 3600 * 10);
  185. sohd_Q_chrgEo = tmp_0 > 0 ? (uint16_T)tmp_0 : 0;
  186. if (sfmd_flg_currInval)
  187. {
  188. sfmn_flg_currFlt_keep = true;
  189. }
  190. sohn_flg_currFlt = sfmn_flg_currFlt_keep;
  191. }
  192. else
  193. {
  194. sfmn_flg_currFlt_keep = false;
  195. Ahincr = 0;
  196. }
  197. //=======================================================================================
  198. //----------------------充电结速信息------------------------------------------------------
  199. //=======================================================================================
  200. if ((ihd_st_workStat != 2) && (sohn_st_workStat_Delay == 2))
  201. {
  202. sohd_flg_chrgEndEo = true;
  203. }
  204. else
  205. {
  206. sohd_flg_chrgEndEo = (sfmd_I_curr < 10 && sfmd_I_curr > -10) && sohd_flg_chrgEndEo;
  207. }
  208. sohd_flg_chrgEndEo = !sohn_flg_currFlt && sohd_flg_chrgEndEo;
  209. //
  210. sohn_st_workStat_Delay = ihd_st_workStat;
  211. sohd_flg_firstRun = false;
  212. }