SOH.c 10 KB

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