Browse Source

增加SOP

LAPTOP-EG88H5BE\86151 3 years ago
parent
commit
4a7a3168c2

+ 1 - 0
ARMCC/Makefile

@@ -37,6 +37,7 @@ obj-y             += PLAT/project/$(TARGET)/apps/qx_app/src/app.o \
 						PLAT/project/$(TARGET)/apps/qx_app/src/EmbeddedCoder_src/ISC.o \
 						PLAT/project/$(TARGET)/apps/qx_app/src/EmbeddedCoder_src/SOE.o \
 						PLAT/project/$(TARGET)/apps/qx_app/src/EmbeddedCoder_src/SOR.o \
+						PLAT/project/$(TARGET)/apps/qx_app/src/EmbeddedCoder_src/SOP.o \
 						PLAT/project/$(TARGET)/apps/qx_app/src/EmbeddedCoder_src/PIM.o \
 						PLAT/project/$(TARGET)/apps/qx_app/src/EmbeddedCoder_src/funlib.o \
 						PLAT/project/$(TARGET)/apps/qx_app/src/EmbeddedCoder_src/BCUCal.o \

+ 8 - 0
inc/EmbeddedCoder_inc/BCUCal.h

@@ -18,6 +18,10 @@ extern const uint16_T cmnm_V_ocv[13];                /* 电池放电参数的OCV
 extern const uint16_T cmnm_pct_soc[13];              /* 电池放电参数的SOC数组; */
 extern const uint16_T cmnc_V_chrgFul;                /* 充满电的截至电压; */
 extern const uint16_T cmnm_R_voloffset[28];          /*电压铜牌阻值补偿,单位moh*/
+extern const uint16_T cmnc_V_disChrgLim; 
+
+
+
 extern const int16_T sfmc_I_chrgCurrOverThr;         /* 充电电流阈值 */
 extern const int16_T sfmc_I_disChrgCurrOverThr;      /* 放电电流阈值 */
 extern const int16_T sfmc_T_ACPlugTOverThrFlt1;      /* 慢充插头温度过高1级故障诊断阈值 */
@@ -86,6 +90,10 @@ extern const uint16_T sohc_Q_updateDeltThr; /*                    */
 extern const uint16_T sohc_pct_low;
 extern const uint16_T sohc_pct_up;
 
+extern const int16_T sopc_I_currUp;
+extern const int16_T sopc_I_currLow;
+
+
 extern const uint16_T socc_pct_battSocLow;  /* SOC下限值; */
 extern const uint16_T socc_pct_battSocUp;   /* SOC上限值; */
 extern const int16_T socm_I_chrgCor[4];     /* 充电CCV对应的电流数据; */

+ 6 - 1
inc/EmbeddedCoder_inc/BCUDisp.h

@@ -17,6 +17,7 @@ extern boolean_T  sfmd_flg_firstRun;
 extern boolean_T  tmsd_flg_firstRun;
 extern boolean_T  cdmd_flg_firstRun;
 extern boolean_T  cmd_flg_firstRun;
+extern boolean_T sopd_flg_firstRun;
 
 extern uint16_T blcv_Q_reqCpEi[cmnc_num_cellUNumMax];                      /*均衡需求容量 读取量(数组); */
 extern uint16_T blcv_Q_reqCpEo[cmnc_num_cellUNumMax];                      /*均衡需求容量 写入量(数组); */
@@ -134,6 +135,11 @@ extern uint16_T soed_E_nowEng;
 extern uint16_T soed_pct_nowStat;
 extern uint16_T soed_E_fullEng;
 
+extern uint16_T sopd_P_chrgPMax;
+extern uint16_T sopd_P_disChrgPMax;
+extern int16_T sopd_I_chrgCurrMax;
+extern int16_T sopd_I_disChrgCurrMax;
+
 extern uint16_T sorv_ohm_cellREi[cmnc_num_cellUNumMax];
 extern uint16_T sorv_ohm_cellREo[cmnc_num_cellUNumMax];
 extern uint16_T sorv_ohm_cellR[cmnc_num_cellUNumMax];
@@ -170,5 +176,4 @@ extern uint16_T test_cellCap[cmnc_num_cellUNumMax];
 extern uint16_T test_countEn;
 
 
-
 


+ 9 - 0
inc/EmbeddedCoder_inc/SOP.h

@@ -0,0 +1,9 @@
+#include <math.h>
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+
+extern void SOP_Init(void);
+extern void SOP(void);
+extern void predSystem(real_T ocv,real_T Ro,real_T Rp,real_T RC,real_T sopn_I_currPred,real_T sopn_V_up,real_T *sopn_pct_socPred10,real_T *sopn_V_battPred10);
+

+ 1 - 0
inc/EmbeddedCoder_inc/SPM.h

@@ -8,6 +8,7 @@
 #include "SOE.h"
 #include "SOR.h"
 #include "PIM.h"
+#include "SOP.h"
 
 extern void SPM_Init(void);
 extern void SPM(void);

+ 2 - 0
inc/EmbeddedCoder_inc/funlib.h

@@ -4,6 +4,8 @@
 extern uint16_T  ArrMax(uint16_T *Data, uint16_T m);
 extern uint16_T  ArrMin(uint16_T *Data, uint16_T m);
 extern int16_T ArrMean(int16_T *Data, uint16_T n);
+extern real_T Saturation_r(real_T in,real_T LowLim,real_T UpLim);
+extern uint16_T Saturation_u(uint16_T in,uint16_T LowLim,uint16_T UpLim);
 
 extern uint16_T  DataFilt(uint16_T in, uint16_T *out, uint16_T Lim);
 extern uint8_T DataFilt8(uint8_T in, uint8_T *out, uint8_T Lim);

+ 3 - 1
src/AppTaskTcp.c

@@ -580,11 +580,13 @@ static void TcpDataInfoAssembleSend()
             sprintf((char *)rbuf, "B-%d,%d,%d,%d,%d,%d,%d,,\
                                 %d,%d,%d,%d,%d,,\
                                 %d,%d,%d,%d,%d,%d,,\
+                                %d,%d,%d,%d,,\
                                 %d,%d,%d,%d",
                     socd_pct_ahSoc, socd_pct_ekfSoc, socd_pct_battSoc, socd_pct_vcuSoc, socd_pct_cellBattSoc, sohv_Q_packCapArrEo[9], cdmv_ohm_deltR[cand_idx_cellNr - 1],
                     sfmd_I_curr, maxCellVol, minCellVol, sfmd_V_cellUAvrg, sfmv_V_cellU[1],
                     cand_idx_cellNr, cand_Q_cellCap, cand_V_chrgStartStat, ihd_tm_parkTime, sohd_Q_chrgEo, sohd_flg_chrgEndEo,
-                    pimd_V_ocv, pimd_R_ohm, pimd_R_polar, pimd_F_polar);
+                    pimd_V_ocv, pimd_R_ohm, pimd_R_polar, pimd_F_polar,
+                    sopd_I_chrgCurrMax,sopd_P_chrgPMax,sopd_I_disChrgCurrMax,sopd_P_disChrgPMax);
         }
         Debugcounter++;
         if (Debugcounter > 100)

+ 3 - 6
src/EmbeddedCoder_src/BCU.c

@@ -60,7 +60,7 @@ void BCU(void)
             sfmd_flg_iscFltEi = BcuDataInfo.sfmd_flg_iscFltE;
             ihd_tm_parkTime = BcuDataInfo.ihd_tm_parkTimeE;
             ihd_st_EOLState = AppNVMData.EOLState;
-
+            appd_st_preCyc = 1;
             PROC_BCU_STATE_SWITCH(PROCESS_STATE_WORK);
             break;
         }
@@ -92,6 +92,7 @@ void BCU(void)
                     }
                     // printf("time:%d\n",ihd_tm_parkTime);
                     //
+		
                     //数据获取
                     ihd_st_reSet = SysResetFlag;
                     ihd_I_curr = (int16_T)(-(battI - 10000));
@@ -150,11 +151,7 @@ void BCU(void)
                         memcpy(appv_V_cellU, sfmv_V_cellU, sizeof(sfmv_V_cellU));
                     }
 
-                    if (ihd_tm_parkTime >= cmnc_tm_parkTime && battI == 10000)
-                    {
-                        appd_st_preCyc = 1;
-                    }
-                    else
+                    if (ihd_tm_parkTime < cmnc_tm_parkTime || battI != 10000)
                     {
                         appd_st_preCyc = 0;
                     }

+ 5 - 2
src/EmbeddedCoder_src/BCUCal.c

@@ -15,7 +15,8 @@ const uint16_T cmnm_R_ohm[13] = {2364U, 2284U, 2234U, 2166U, 2128U, 2111U, 2090U
 const uint16_T cmnm_R_polar[13] = {4955U, 2073U, 1504U, 1197U, 1098U, 1072U, 1141U, 1700U, 1637U, 1626U, 1496U, 1486U, 1436U};            /* 电池放电参数的Rp数组; */
 const uint16_T cmnm_V_ocv[13] = {3327U, 3453U, 3487U, 3563U, 3617U, 3652U, 3700U, 3791U, 3897U, 4006U, 4129U, 4197U, 4276U};              /* 电池放电参数的OCV数组; */
 const uint16_T cmnm_pct_soc[13] = {0U, 50U, 100U, 200U, 300U, 400U, 500U, 600U, 700U, 800U, 900U, 950U, 1000U};                           /* 电池放电参数的SOC数组; */
-const uint16_T cmnc_V_chrgFul = 4200U;                                                                                                    /* 充满电的截至电压; */
+const uint16_T cmnc_V_disChrgLim = 2800U;  
+
 const uint16_T cmnm_R_voloffset[28] = {0, 0, 0, 0, 0,
                                        0, 770, 0, 0, 0,
                                        0, 0, 0, 540, 0,
@@ -94,8 +95,10 @@ const uint16_T sohc_Q_updateDeltThr = 200U; /*soh更新 偏差允许阈值*/
 const uint16_T sohc_pct_low = 0U;
 const uint16_T sohc_pct_up = 0U;
 
+const int16_T sopc_I_currUp  = 500;
+const int16_T sopc_I_currLow = -500;
+
 const uint16_T socc_pct_battSocLow = 0U;                     /* SOC下限值; */
-const uint16_T socc_pct_battSocUp = 930U;                    /* SOC上限值; */
 const int16_T socm_I_chrgCor[3] = {50, 100, 150};            /* 充电CCV对应的电流数据; */
 const int16_T socm_I_disChrgCor[3] = {-240, -160, -100};     /* 放电CCV对应的电流数据; */
 const uint16_T socm_V_chrgCor[3] = {4160U, 4175U, 4188U};    /* 充电CCV对应的电压; */

+ 8 - 0
src/EmbeddedCoder_src/BCUDisp.c

@@ -15,6 +15,8 @@ boolean_T  pimd_flg_firstRun;
 boolean_T  sfmd_flg_firstRun;
 boolean_T  tmsd_flg_firstRun;
 boolean_T  cdmd_flg_firstRun;
+boolean_T sopd_flg_firstRun;
+
 boolean_T  cmd_flg_firstRun;
 
 uint16_T blcv_Q_reqCpEi[cmnc_num_cellUNumMax];                      /*均衡需求容量 读取量(数组); */
@@ -134,6 +136,12 @@ uint16_T soed_E_nowEng;
 uint16_T soed_pct_nowStat;
 uint16_T soed_E_fullEng;
 
+uint16_T sopd_P_chrgPMax;
+uint16_T sopd_P_disChrgPMax;
+int16_T sopd_I_chrgCurrMax;
+int16_T sopd_I_disChrgCurrMax;
+
+	
 uint16_T sorv_ohm_cellREi[cmnc_num_cellUNumMax];
 uint16_T sorv_ohm_cellREo[cmnc_num_cellUNumMax];
 uint16_T sorv_ohm_cellR[cmnc_num_cellUNumMax];

+ 12 - 6
src/EmbeddedCoder_src/PIM.c

@@ -25,7 +25,6 @@ void PIM(void)
     real_T P[4][4];
     real_T A[4];
     real_T K[4];
-    real_T S[4];
     real_T temp;
 	
     //重置
@@ -42,10 +41,10 @@ void PIM(void)
         pimn_M_P[2][0] =  0; pimn_M_P[2][1] =  0;  pimn_M_P[2][2] = 10;  pimn_M_P[2][3] =  0;
         pimn_M_P[3][0] =  0; pimn_M_P[3][1] =  0;  pimn_M_P[3][2] =  0;  pimn_M_P[3][3] = 10;
         
-        pimn_V_ocv   = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_V_ocv,    13) * 0.001;
-        pimn_R_ohm   = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_R_ohm,    13) * 0.001 * 0.001;
-        pimn_R_polar = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_R_polar,  13) * 0.001 * 0.001;
-        pimn_F_polar = 5;
+        pimn_V_ocv   = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_V_ocv, 13) * 0.001;
+        pimn_R_ohm   = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_R_ohm, 13) * 0.001 * 0.001;
+        pimn_R_polar = 0.001;
+        pimn_F_polar = 0;
         pimn_N_ctn = 0;  
 		pimn_st_workStat_Delay = 0;
     }
@@ -162,7 +161,14 @@ void PIM(void)
         pimn_R_ohm   = theta[1];
         pimn_R_polar = (theta[0] * theta[1] -theta[2])/(1 -theta[0]);
         pimn_F_polar = -1/log(theta[0]);
-        
+
+        pimn_V_ocv   = Saturation_r(pimn_V_ocv,3.2, 4.4);
+		pimn_R_ohm   = Saturation_r(pimn_V_ocv,0.001, 1);
+		pimn_R_polar = Saturation_r(pimn_V_ocv,0.0002, 1);
+		pimn_F_polar = Saturation_r(pimn_V_ocv,0, 200);
+
+
+		
         pimd_V_ocv   = (uint16_T)(pimn_V_ocv   * 1000);
         pimd_R_ohm   = (uint16_T)(pimn_R_ohm   * 1000 * 1000);
         pimd_R_polar = (uint16_T)(pimn_R_polar * 1000 * 1000);

+ 7 - 51
src/EmbeddedCoder_src/SOC.c

@@ -143,7 +143,6 @@ void SOC(void)
         }
         socn_Q_cap = (uint16_T)((uint16_T)((uint32_T)sohd_pct_bcuSoh * cmnc_Q_ratedCp / 2000U) << 1);
     }
-	
     //printf("1----  battSocEi:%d,bcuSocEi:%d,battSocEE:%d,bcuSocEE:%d\n",socd_pct_battSocEi,socd_pct_bcuSocEi,socn_pct_battSocEE,socn_pct_bcuSocEE);
     //======================================================================
     ////////////////////////EKFSOC//////////////////////////////////////////
@@ -193,16 +192,7 @@ void SOC(void)
     //后验
     deltU = (real_T)sfmd_V_cellUMin * 0.001 - UL;
     soc_Min_Delay = soc1 + K[0] * deltU;
-    
-    if (soc_Min_Delay < (real_T)socc_pct_battSocLow * 0.1)
-    {
-        soc_Min_Delay = (real_T)socc_pct_battSocLow * 0.1;
-    }
-    if (soc_Min_Delay > (real_T)socc_pct_battSocUp * 0.1)
-    {
-        soc_Min_Delay = (real_T)socc_pct_battSocUp * 0.1;
-    }
-    
+    soc_Min_Delay = Saturation_r(soc_Min_Delay, (real_T)socc_pct_battSocLow * 0.1, (real_T)socc_pct_battSocUp * 0.1);
     Up_Min_Delay = Up1 + K[1] * deltU;
     //P更新
     P_Min_Delay[0] = (1 - K[0] * H[0]) * P1[0] - K[0] * P1[1];
@@ -258,15 +248,7 @@ void SOC(void)
     //后验
     deltU = (real_T)sfmd_V_cellUMax * 0.001 - UL;
     soc_Max_Delay = soc1 + K[0] * deltU;
-    
-    if (soc_Max_Delay < (real_T)socc_pct_battSocLow * 0.1)
-    {
-        soc_Max_Delay = (real_T)socc_pct_battSocLow * 0.1;
-    }
-    if (soc_Max_Delay > (real_T)socc_pct_battSocUp * 0.1)
-    {
-        soc_Max_Delay = (real_T)socc_pct_battSocUp * 0.1;
-    }
+	soc_Max_Delay = Saturation_r(soc_Max_Delay, (real_T)socc_pct_battSocLow * 0.1, (real_T)socc_pct_battSocUp * 0.1);
     Up_Max_Delay = Up1 + K[1] * deltU;
     
     //P更新
@@ -340,15 +322,7 @@ void SOC(void)
     deltU = (real_T)sfmd_V_cellUAvrg * 0.001 - UL;
     soc_Avrg_Delay = soc1 + K[0] * deltU;
     
-    if (soc_Avrg_Delay < (real_T)socc_pct_battSocLow * 0.1)
-    {
-        soc_Avrg_Delay = (real_T)socc_pct_battSocLow * 0.1;
-    }
-    if (soc_Avrg_Delay > (real_T)socc_pct_battSocUp * 0.1)
-    {
-        soc_Avrg_Delay = (real_T)socc_pct_battSocUp * 0.1;
-    }
-    
+    soc_Avrg_Delay = Saturation_r(soc_Avrg_Delay, (real_T)socc_pct_battSocLow * 0.1, (real_T)socc_pct_battSocUp * 0.1);
     Up_Avrg_Delay = Up1 + K[1] * deltU;
     //P更新
     P_avrg_Delay[0] = (1 - K[0] * H[0]) * P1[0] - K[0] * P1[1];
@@ -397,24 +371,14 @@ void SOC(void)
         ahDelay = ahDelay + battcurr / (real_T)(cmnc_Q_ratedCp * 0.1) / 36.0;//cmnc_Q_ratedCp
     }
     ahSoc = (int16_T)(ahDelay * 10);
-    if (ahSoc > socc_pct_battSocUp)
-    {
-        socd_pct_ahSoc = socc_pct_battSocUp;
-    }
-    else if (ahSoc < socc_pct_battSocLow)
-    {
-        socd_pct_ahSoc = socc_pct_battSocLow;
-    }
-    else
-    {
-        socd_pct_ahSoc = (uint16_T)ahSoc;
-    }
+	
+	socd_pct_ahSoc = Saturation_u(ahSoc < 0 ? 0 : (uint16_T)ahSoc, socc_pct_battSocLow, socc_pct_battSocUp);
 	//printf("5----ahDelay:%f,ahSoc:%d,battcurr:%f,sfmd_I_curr:%d\n",ahDelay,ahSoc,battcurr,sfmd_I_curr);
 	
     //======================================================================
     ///////////////////////estSOC//////////////////////////////////////////
     //======================================================================
-    socn_flg_ekfDisable = !JudgeTimeSystem(1,!socn_flg_ekfInvalid,&ekfInvalidCntl,20);
+    socn_flg_ekfDisable = !JudgeTimeSystem(1,!socn_flg_ekfInvalid,&ekfInvalidCntl,2);
     if (socn_flg_ekfDisable)
     {
         if (onceFlg_est)
@@ -430,16 +394,8 @@ void SOC(void)
         onceFlg_est = true;
         socd_pct_estSoc = socd_pct_ekfSoc;
     }
-    
+    socd_pct_estSoc = Saturation_u(socd_pct_estSoc, socc_pct_battSocLow, socc_pct_battSocUp);
     //
-    if (socd_pct_estSoc > socc_pct_battSocUp)
-    {
-        socd_pct_estSoc = socc_pct_battSocUp;
-    }
-    if (socd_pct_estSoc < socc_pct_battSocLow)
-    {
-        socd_pct_estSoc = socc_pct_battSocLow;
-    }
     //printf("6----ahSoc0_est:%d,ekfSoc0_est:%d,socd_pct_estSoc:%d\n",ahSoc0_est,ekfSoc0_est,socd_pct_estSoc);
 	
     //======================================================================

+ 143 - 0
src/EmbeddedCoder_src/SOP.c

@@ -0,0 +1,143 @@
+#include "SOP.h"
+
+void SOP_Init(void)
+{
+    sopd_flg_firstRun = true;
+}
+//-------------------------------------------------------------------------
+
+void SOP(void)
+{
+    static real_T sopn_V_up;
+    real_T sopn_I_currPred;
+    real_T sopn_V_battPred10;
+    real_T sopn_pct_socPred10;
+    real_T ocv;
+    real_T Ro;
+    real_T RC;
+    real_T Rp;
+    real_T ileft;
+    real_T iright;
+    real_T imid;
+    real_T sopn_V_battU;
+    if(sopd_flg_firstRun)
+    {
+        sopn_V_up = 0;
+    }
+    ocv = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_V_ocv,  13) * 0.001;
+    Ro  = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_R_ohm,  13) * 0.001 * 0.001;
+    Rp  = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_R_polar,13) * 0.001 * 0.001;
+    RC  = (real_T)look1_u16tu16(socd_pct_battSoc, cmnm_pct_soc, cmnm_F_polar,13) * 0.001;
+	//printf("%f %f  %f  %f\n",ocv,Ro,Rp,RC);
+
+    //printf("soc:%d,I:%d,up:%f\n",socd_pct_battSoc,sfmd_I_curr,sopn_V_up);
+    //充电功率
+    sopn_I_currPred = 0;
+    predSystem(ocv,Ro,Rp,RC,sopn_I_currPred,sopn_V_up,&sopn_pct_socPred10,&sopn_V_battPred10);
+
+    if(sopn_V_battPred10 > (real_T)cmnc_V_chrgFul * 0.001 || sopn_pct_socPred10 > (real_T)socc_pct_battSocUp * 0.1)
+    {
+        sopn_I_currPred = 0;
+        
+    }
+    else
+    {
+        sopn_I_currPred = (real_T)sopc_I_currUp * 0.1;
+        predSystem(ocv,Ro,Rp,RC,sopn_I_currPred,sopn_V_up,&sopn_pct_socPred10,&sopn_V_battPred10);
+        if(sopn_V_battPred10 < (real_T)cmnc_V_chrgFul * 0.001 && sopn_pct_socPred10 < (real_T)socc_pct_battSocUp * 0.1)
+        {
+            sopn_I_currPred = (real_T)sopc_I_currUp * 0.1;;
+        }
+        else
+        {
+            iright = (real_T) sopc_I_currUp * 0.1;
+            ileft = 0;
+            imid = (iright + ileft)/2;
+            while(iright - ileft > 0.1)
+            {
+                predSystem(ocv,Ro,Rp,RC,imid,sopn_V_up,&sopn_pct_socPred10,&sopn_V_battPred10);
+                
+                if(sopn_V_battPred10 > (real_T)cmnc_V_chrgFul * 0.001 || sopn_pct_socPred10 > (real_T)socc_pct_battSocUp * 0.1)
+                {
+                    iright =  imid;
+                }
+                else
+                {
+                    ileft =  imid;
+                }
+                imid = (iright + ileft)/2;
+            }
+			sopn_I_currPred = ileft;
+        }
+    }
+    sopn_V_battU = (ocv +  sopn_I_currPred * Ro + sopn_V_up) * cmnc_num_cellUNum;
+	sopd_I_chrgCurrMax = (int16_T)(sopn_I_currPred * 10);
+    sopd_P_chrgPMax = (uint16_T)(sopn_V_battU * sopn_I_currPred * 1000);
+	predSystem(ocv,Ro,Rp,RC,sopn_I_currPred,sopn_V_up,&sopn_pct_socPred10,&sopn_V_battPred10);
+    //printf("%f,  %f, %f\n\n",sopn_I_currPred,sopn_pct_socPred10,sopn_V_battPred10);
+
+	
+    //放电功率
+    
+    sopn_I_currPred = 0;
+    predSystem(ocv,Ro,Rp,RC,sopn_I_currPred,sopn_V_up,&sopn_pct_socPred10,&sopn_V_battPred10);
+    if(sopn_V_battPred10 < (real_T)cmnc_V_disChrgLim * 0.001 || sopn_pct_socPred10 < (real_T)socc_pct_battSocLow * 0.1)
+    {
+        sopn_I_currPred = 0;
+    }
+    else
+    {
+        sopn_I_currPred = (real_T)sopc_I_currLow * 0.1;
+        predSystem(ocv,Ro,Rp,RC,sopn_I_currPred,sopn_V_up,&sopn_pct_socPred10,&sopn_V_battPred10);
+        if(sopn_V_battPred10 > (real_T)cmnc_V_disChrgLim * 0.001 && sopn_pct_socPred10 > (real_T)socc_pct_battSocLow * 0.1)
+        {
+            sopn_I_currPred = (real_T)sopc_I_currLow * 0.1;;
+        }
+        else
+        {
+            iright = 0;
+            ileft = (real_T) sopc_I_currLow * 0.1;
+            imid = (iright + ileft)/2;
+            while(iright - ileft > 0.1)
+            {
+                predSystem(ocv,Ro,Rp,RC,imid,sopn_V_up,&sopn_pct_socPred10,&sopn_V_battPred10);
+                if(sopn_V_battPred10 > (real_T)cmnc_V_disChrgLim * 0.001 && sopn_pct_socPred10 > (real_T)socc_pct_battSocLow * 0.1)
+                {
+                    iright =  imid;
+                }
+                else
+                {
+                    ileft =  imid;
+                }
+                imid = (iright + ileft)/2;
+            }
+            sopn_I_currPred = iright;
+        }
+    }
+    sopn_V_battU = sopn_V_battPred10 * cmnc_num_cellUNum;
+	sopd_I_disChrgCurrMax = (int16_T)(sopn_I_currPred * 10);
+    sopd_P_disChrgPMax = (uint16_T)(- sopn_V_battU * sopn_I_currPred * 1000);
+    
+    
+    sopn_V_up = sopn_V_up * exp(-1/RC) + Rp * (1 - exp(-1/RC)) * sfmd_I_curr;
+    sopd_flg_firstRun = false;
+}
+
+void predSystem(real_T ocv,real_T Ro,real_T Rp,real_T RC,real_T sopn_I_currPred,real_T sopn_V_up,real_T *sopn_pct_socPred10,real_T *sopn_V_battPred10)
+{
+    uint8_T i;
+    real_T sopn_V_upPred;
+    real_T sopn_pct_socPred;
+    real_T sopn_Q_cellCap;
+    sopn_Q_cellCap = (real_T)sohd_pct_bcuSoh * cmnc_Q_ratedCp * 0.0001;
+    sopn_pct_socPred = (real_T) socd_pct_battSoc * 0.1;
+    sopn_V_upPred = sopn_V_up;
+    for(i = 0;i < 10;i++)
+    {
+        sopn_V_upPred = sopn_V_upPred * exp(-1/RC) + Rp * (1 - exp(-1/RC)) * sopn_I_currPred;
+        sopn_pct_socPred = sopn_pct_socPred + sopn_I_currPred/sopn_Q_cellCap/36;
+    }
+    *sopn_pct_socPred10 = sopn_pct_socPred;
+    *sopn_V_battPred10 = ocv +  sopn_I_currPred * Ro + sopn_V_upPred;
+}
+

+ 2 - 0
src/EmbeddedCoder_src/SPM.c

@@ -9,6 +9,7 @@ void SPM_Init(void)
   PIM_Init();
   SOE_Init();
   SOR_Init();
+  SOP_Init();
   spmd_flg_firstRun = true;
 }
 
@@ -44,6 +45,7 @@ void SPM(void)
 	  PIM();
 	  SOE();
 	  SOR();
+	  SOP();
   }
   // 循环发送数组
   cand_Q_cellCap = sohv_Q_cellCapArrEo[cand_idx_cellNr-1];

+ 21 - 0
src/EmbeddedCoder_src/funlib.c

@@ -50,6 +50,27 @@ int16_T ArrMean(int16_T *Data, uint16_T n)
     return DataMean;
 }
 
+//-----------------real_T 限幅函数
+real_T Saturation_r(real_T in,real_T LowLim,real_T UpLim)
+{
+   real_T out;
+
+   out = in > LowLim ? in : LowLim;
+   out = out > UpLim ? UpLim : out;
+   return out;
+}
+
+//-----------------uint16 限幅函数
+
+uint16_T Saturation_u(uint16_T in,uint16_T LowLim,uint16_T UpLim)
+{
+   uint16_T out;
+
+   out = in > LowLim ? in : LowLim;
+   out = out > UpLim ? UpLim : out;
+   return out;
+}
+
 
 // ---------------------滤波控制变动速率-------------------------------------- 
 uint16_T DataFilt(uint16_T in, uint16_T *out, uint16_T Lim)