Kaynağa Gözat

BMS算法移植测试

LAPTOP-KB7QFH2U\ChenJie-PC 1 yıl önce
ebeveyn
işleme
b65d107d78

+ 1 - 0
.cproject

@@ -39,6 +39,7 @@
 								<option id="com.nxp.s32ds.cle.arm.mbs.arm32.bare.tool.c.compiler.option.target.sysroot.2141010934" name="Sysroot" superClass="com.nxp.s32ds.cle.arm.mbs.arm32.bare.tool.c.compiler.option.target.sysroot" useByScannerDiscovery="false" value="--sysroot=&quot;${S32DS_ARM32_NEWLIB_DIR}&quot;" valueType="string"/>
 								<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="gnu.c.compiler.option.include.paths.203066772" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" useByScannerDiscovery="false" valueType="includePath">
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/code}&quot;"/>
+									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/code/app/bms}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/code/app/lib}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/code/debug/SEGGER}&quot;"/>
 									<listOptionValue builtIn="false" value="&quot;${workspace_loc:/${ProjName}/code/debug/cm_backtrace}&quot;"/>

+ 3 - 3
FreeRTOS/Source/include/FreeRTOSConfig.h

@@ -29,7 +29,7 @@
 #ifndef FREERTOS_CONFIG_H
 #define FREERTOS_CONFIG_H
 //#define SEGGER_SYSTEMVIEW //选择SYSTEM查看
-//#define SEGGER_RTT_PRINTF 	//选择RTT打印
+#define SEGGER_RTT_PRINTF 	//选择RTT打印
 #ifdef SEGGER_SYSTEMVIEW
 	#include "SEGGER_SYSVIEW_FreeRTOS.h"
 #endif
@@ -62,7 +62,7 @@
 #define configENABLE_BACKWARD_COMPATIBILITY         1
 #define configUSE_POSIX_ERRNO                       0
 #define configUSE_APPLICATION_TASK_TAG              0
-#define configRECORD_STACK_HIGH_ADDRESS             0
+#define configRECORD_STACK_HIGH_ADDRESS             1
 
 /* Definition assert() function. */
 #define configASSERT(x)                             if((x)==0) { taskDISABLE_INTERRUPTS(); for( ;; ); }
@@ -87,7 +87,7 @@ PRIORITY THAN THIS! (higher priorities are lower numeric values. */
 #define configUSE_DAEMON_TASK_STARTUP_HOOK          0
 
 /* Run time and task stats gathering related definitions. */
-#define configGENERATE_RUN_TIME_STATS               0
+#define configGENERATE_RUN_TIME_STATS               1
 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()    
 #define portGET_RUN_TIME_COUNTER_VALUE()            xTaskGetTickCount()
 #define configUSE_TRACE_FACILITY                    1

+ 3 - 2
code/app/AppGlobalVar.c

@@ -17,7 +17,7 @@
 #include "AppGlobalVar.h"
 
 #define defaultSn "GYTEST00000000001"
-
+/*存储空间*/
 #define EEP_START_SEC_VAR_INIT_8_NO_CACHEABLE
 #include "Eep_MemMap.h"
 AppConfigBody AppConfigInfo = {false, false, {defaultSn}, {0}};
@@ -62,7 +62,8 @@ QueueHandle_t CanRecvQueueHandle0;
 QueueHandle_t CanRecvQueueHandle1;
 QueueHandle_t CanRecvQueueHandle2;
 
-TaskHandle_t Uart_Hal_RecvTask_Handle, Uart_Hal_SendTask_Handle, MainTask_Handle, Uart0Task_Handle, CanTask_Handle, GpsTask_Handle, Uart_4G_Task_Handle;
+TaskHandle_t Uart_Hal_RecvTask_Handle, Uart_Hal_SendTask_Handle, MainTask_Handle, Uart0Task_Handle,
+CanTask_Handle, GpsTask_Handle, Uart_4G_Task_Handle,BcuTask_Handle;
 SemaphoreHandle_t sleep_mutex = NULL;
 
 bool TcpSysReboot = 0;

+ 27 - 1
code/app/AppGlobalVar.h

@@ -64,7 +64,8 @@ extern QueueHandle_t CanRecvQueueHandle0;
 extern QueueHandle_t CanRecvQueueHandle1;
 extern QueueHandle_t CanRecvQueueHandle2;
 
-extern TaskHandle_t Uart_Hal_RecvTask_Handle, Uart_Hal_SendTask_Handle, MainTask_Handle, Uart0Task_Handle, CanTask_Handle, GpsTask_Handle, Uart_4G_Task_Handle;
+extern TaskHandle_t Uart_Hal_RecvTask_Handle, Uart_Hal_SendTask_Handle, MainTask_Handle, Uart0Task_Handle,
+CanTask_Handle, GpsTask_Handle, Uart_4G_Task_Handle,BcuTask_Handle;
 extern SemaphoreHandle_t sleep_mutex;
 
 extern uint8 CSQValue;
@@ -83,12 +84,37 @@ typedef struct _AppEppType
     uint16 battCycleTimes;
     uint32 AccMileage;
 } AppEppBody;
+/*BMS算法部分*/
+typedef struct _AppAlgorithmType
+{
+    BOOL appDataModify;               //数据更改标志位
+    UINT32 blcv_Q_totalCpE[BMS_CELL_MAX_NUM];       //累计均衡容量 读取量 数组最大28
+    UINT16 blcv_Q_reqCpE[BMS_CELL_MAX_NUM];         //均衡需求容量 读取量 数组最大28
+    UINT16 socd_pct_bcuSocE;          //电池显示SOC 读取量;
+    UINT16 socd_pct_battSocE;         //电池真实SOC 读取量;
+    UINT16 sohd_tm_chrgStartStatE;    //充电前静置时间读取量;
+    BOOL sohd_flg_chrgEndE;           //充电结束标志位读取量;
+    UINT16 sohv_V_chrgStartStatE[BMS_CELL_MAX_NUM]; //充电开始时刻的单体电压(数组)读取量;
+    UINT16 sohd_Q_chrgE;              //充入容量读取量;
+    UINT16 sohv_Q_packCapArrE[10];    // 10次整包容量(数组)读取量;
+    UINT16 sohv_Q_cellCapArrE[BMS_CELL_MAX_NUM];    //
+    UINT16 iscv_Q_remainCpE[BMS_CELL_MAX_NUM];
+    UINT32 iscd_tm_totalE;
+    BOOL sfmd_flg_iscFltE;
+    BOOL sfmd_flg_mainCirClosFltE;
+    BOOL sfmd_flg_heatCirClosFltE;
+    BOOL sfmd_flg_heatCirOpenFltE;
+    BOOL sfmd_flg_heatRunFltE;
+    UINT16 ihd_tm_parkTimeE;
+    UINT16 sorv_ohm_cellRE[BMS_CELL_MAX_NUM];
+} AppAlgorithmData;
 typedef struct _AppConfigType
 {
     bool appSaveFlg;
     bool eolFlg;
     uint8 deviceSn[17];
     AppEppBody AppDataInfo;
+    AppAlgorithmData BcuDataInfo;
     uint8 re[20];
 } AppConfigBody;
 extern AppConfigBody AppConfigInfo;

+ 12 - 0
code/app/AppTaskGps.c

@@ -49,6 +49,18 @@ void GpsTask(void *pvParameters)
 		/*LED控制*/
 		if((timerCounterGetdata - ledCounterTmp) > 200)
 		{
+			/*测试*/
+#ifdef SEGGER_RTT_PRINTF//以下代码为测试 线程堆栈使用情况,保留不删除
+			UBaseType_t iStack;
+			TaskHandle_t TaskList[6]={Uart_Hal_RecvTask_Handle,Uart_Hal_SendTask_Handle,MainTask_Handle,CanTask_Handle,GpsTask_Handle,Uart_4G_Task_Handle};
+			for(uint8 i=0;i<6;i++)
+			{
+				iStack = uxTaskGetStackHighWaterMark(TaskList[i]);
+				SEGGER_RTT_printf("%d iStack = %d,%X\n",i,iStack,TaskList[i]);
+			}
+			SEGGER_RTT_printf("\r\n");
+#endif
+
 			Dio_WriteChannel(DioConf_DioChannel_PTE0_GPIO_OUT_MCU_LED1, STD_OFF);
 			ledCounterTmp = timerCounterGetdata;
 			if(SocketId>=0)//网络连接成功

+ 220 - 0
code/app/bms/BCU.c

@@ -0,0 +1,220 @@
+
+#include "BCU.h"
+
+static process_Bcu gProcess_Bcu_Task;
+#define PROC_BCU_STATE_SWITCH(a) (gProcess_Bcu_Task = a)
+
+//=========================================================================
+//=========================================================================
+//=========================================================================
+void BCU(void)
+{
+    uint16_T i;
+    uint16_T RecvCounter = 0;
+	static boolean_T Flg;
+	//启动延迟没做
+    PROC_BCU_STATE_SWITCH(PROCESS_STATE_INIT);
+    while (TRUE)
+    {
+        switch (gProcess_Bcu_Task)
+        {
+        //=========================初始化===============================
+        case PROCESS_STATE_INIT:
+        {
+            BCU_Init();
+			Flg = 1;
+//            cmnc_num_cellUNum = AppDataInfo.BattCellCount; /* 电压采样点实际个数; */
+//            cmnc_num_modTNum = AppDataInfo.BattTempCount;  /* 温度采样点实际个数; */
+//			ihd_st_EOLState = AppNVMData.EOLState;
+//            memcpy(blcv_Q_totalCpEi, BcuDataInfo.blcv_Q_totalCpE, sizeof(blcv_Q_totalCpEi));
+//            memcpy(blcv_Q_reqCpEi, BcuDataInfo.blcv_Q_reqCpE, sizeof(blcv_Q_reqCpEi));
+//            socd_pct_bcuSocEi = BcuDataInfo.socd_pct_bcuSocE;
+//            socd_pct_battSocEi = BcuDataInfo.socd_pct_battSocE;
+//            sohd_tm_chrgStartStatEi = BcuDataInfo.sohd_tm_chrgStartStatE;
+//            sohd_flg_chrgEndEi = BcuDataInfo.sohd_flg_chrgEndE;
+//            memcpy(sohv_V_chrgStartStatEi, BcuDataInfo.sohv_V_chrgStartStatE, sizeof(sohv_V_chrgStartStatEi));
+//            sohd_Q_chrgEi = BcuDataInfo.sohd_Q_chrgE;
+//            memcpy(sohv_Q_packCapArrEi, BcuDataInfo.sohv_Q_packCapArrE, sizeof(sohv_Q_packCapArrEi));
+//            memcpy(sohv_Q_cellCapArrEi, BcuDataInfo.sohv_Q_cellCapArrE, sizeof(sohv_Q_cellCapArrEi));
+//            memcpy(iscv_Q_remainCpEi, BcuDataInfo.iscv_Q_remainCpE, sizeof(iscv_Q_remainCpEi));
+//            memcpy(sorv_R_cellEi, BcuDataInfo.sorv_ohm_cellRE, sizeof(sorv_R_cell));
+//            iscd_tm_totalEi = BcuDataInfo.iscd_tm_totalE;
+//            sfmd_flg_mainCirClosFltEi = BcuDataInfo.sfmd_flg_mainCirClosFltE;
+//            sfmd_flg_heatCirClosFltEi = BcuDataInfo.sfmd_flg_heatCirClosFltE;
+//            sfmd_flg_heatCirOpenFltEi = BcuDataInfo.sfmd_flg_heatCirOpenFltE;
+//            sfmd_flg_heatRunFltEi = BcuDataInfo.sfmd_flg_heatRunFltE;
+//            sfmd_flg_iscFltEi = BcuDataInfo.sfmd_flg_iscFltE;
+//            ihd_tm_parkTime = BcuDataInfo.ihd_tm_parkTimeE;
+            PROC_BCU_STATE_SWITCH(PROCESS_STATE_WORK);
+            break;
+        }
+        //============================工作模式==========================
+        case PROCESS_STATE_WORK:
+        {
+        	//数据得到之后再运行没做
+            while (TRUE)
+            {
+                if (TimerCounter % 10 == 0)
+                {
+//                    if (gProcess_app == LISTEN)
+//                    {
+//                        PROC_BCU_STATE_SWITCH(PROCESS_STATE_SLEEP);
+//                        break;
+//                    }
+
+                    //数据获取
+//                    ihd_st_reSet = SysResetFlag;
+//                    ihd_I_curr = (int16_T)(-(battI - 10000));
+//                    memcpy(ihv_V_cellU, battCellU, sizeof(battCellU));
+//                    for (i = 0; i < cmnc_num_modTNum; i++)
+//                    {
+//                        ihv_T_modT[i] = battCellTemp[i];
+//                    }
+//                    ihd_T_mosT = MOSTemp;
+//                    ihd_T_DCPlugT = fastChargeTemp;
+//                    ihd_T_ACPlugT = normalChargeTemp;
+//                    ihd_T_heatPanT1 = heatTemp1;
+//                    ihd_T_heatPanT2 = heatTemp2;
+//                    ihd_pct_soc = battSOC * 10;
+//                    ihd_pct_soh = battSOH * 10;
+//                    ihd_flg_HVILFlt = Lockstatus;
+//                    ihd_st_workStat = BattWorkStateDelay;
+//                    ihd_flg_urtRecFlt = UartErrorFlag;
+//                    ihd_flg_urtRecFlg = UartRecvFlag;
+//                    ihd_st_chrgConnect = chargerConnectState;
+//                    ihd_flg_cellULowFlt = (getbit(battProtectState, 8)) == 1;
+//                    ihd_flg_battULowFlt = (getbit(battProtectState, 9)) == 1;
+//                    ihd_flg_cellUOverFlt = (getbit(battProtectState, 24)) == 1;
+//                    ihd_flg_battUOverFlt = (getbit(battProtectState, 25)) == 1;
+//                    ihd_flg_disChrgCurrOverFlt = (getbit(battProtectState, 1)) == 1;
+//                    ihd_flg_chrgCurrOverFlt = (getbit(battProtectState, 2)) == 1;
+//                    ihd_flg_disChrgModTOverFlt = (getbit(battProtectState, 20)) == 1;
+//                    ihd_flg_chrgModTOverFlt = (getbit(battProtectState, 16)) == 1;
+//                    ihd_flg_chrgMosTOverFlt = (getbit(battProtectState, 18)) == 1;
+//                    ihd_flg_disChrgMosClosFlt = ((battWarningState >> 18) & 0x01) == 1;
+//                    ihd_flg_chrgMosClosFlt = ((battWarningState >> 19) & 0x01) == 1;
+//                    ihd_flg_disChrgModTLowFlt = (getbit(battProtectState, 21)) == 1;
+//                    ihd_flg_chrgModTLowFlt = (getbit(battProtectState, 17)) == 1;
+//                    ihd_flg_currOpenFlt = 0;
+//                    ihd_st_heatForceControl = HeatForceControl;
+//                    ihd_st_chrgMosControl = ChargeForbiddenControl == 0;
+//                    ihd_st_disChrgMosControl = DisChargeForbiddenControl == 0;
+//                    ihd_st_relayControl = RelayForbiddenControl == 0;
+//                    ihd_st_heatStat = battHeatEnableState;
+
+                    //调用算法
+                    SFM();
+                    TMS();
+                    CSM();
+                    SPM();
+                    ISC();
+                    //实时存储
+                    if (socd_flg_EEsave == 1 || ihd_flg_DTCClear)
+                    {
+                        BCUEEDataSave();
+                        ihd_flg_DTCClear = false;
+                    }
+
+                    if (ihd_st_workStat == 0)
+                    {
+                        memcpy(appv_V_cellU, sfmv_V_cellU, sizeof(sfmv_V_cellU));
+                    }
+                   
+                    if(Flg == 1 && ihd_st_workStat != 0)
+                    {
+                    	AppConfigInfo.BcuDataInfo.ihd_tm_parkTimeE = 0;
+                    	AppConfigInfo.appSaveFlg = TRUE;
+					    Flg = 0;
+                    }
+                    if (ihd_st_wakeUpStat == 8)
+                    {
+						if(bcud_flg_firstRun)
+						{
+                           appd_st_preCyc = 1;
+						}
+						if(ihd_st_workStat != 0)
+						{
+						   appd_st_preCyc = 0;
+                        }
+                    }
+					bcud_flg_firstRun = false;
+                }
+                vTaskDelay(100);
+            }
+            break;
+        }
+        //======================休眠模式===============================
+//        case PROCESS_STATE_SLEEP:
+//        {
+//            BCUEEDataSave();
+//            ihd_tm_parkTime = 0;
+//            while (TRUE)
+//            {
+//                if (TimerCounter % 10 == 0)
+//                {
+//                    ihd_tm_parkTime++;
+//                }
+//                if (TimeCounter % 1000 == 0)
+//                {
+//                    BcuDataInfo.ihd_tm_parkTimeE = ihd_tm_parkTime;
+//                    BcuDataInfo.appDataModify = TRUE;
+//                }
+//                if (gProcess_app == WORK)
+//                {
+//                    BcuDataInfo.ihd_tm_parkTimeE = ihd_tm_parkTime;
+//                    BcuDataInfo.appDataModify = TRUE;
+//                    PROC_BCU_STATE_SWITCH(PROCESS_STATE_INIT);
+//                    break;
+//                }
+//                vTaskDelay(100);
+//            }
+//            break;
+//        }
+        default:
+        {
+            PROC_BCU_STATE_SWITCH(PROCESS_STATE_INIT);
+            break;
+        }
+        }
+    }
+}
+
+//========================算法初始化========================================
+void BCU_Init(void)
+{
+    bcud_flg_firstRun = true;
+    SFM_Init();
+    TMS_Init();
+    CSM_Init();
+    SPM_Init();
+    ISC_Init();
+}
+
+//==========================主线程调用======================================
+void AppTaskBcuInit(void *arg)
+{
+
+}
+//=========================数据存储========================================
+void BCUEEDataSave(void)
+{
+    memcpy(AppConfigInfo.BcuDataInfo.blcv_Q_totalCpE, blcv_Q_totalCpEo, sizeof(blcv_Q_totalCpEo));
+    memcpy(AppConfigInfo.BcuDataInfo.blcv_Q_reqCpE, blcv_Q_reqCpEo, sizeof(blcv_Q_reqCpEo));
+    AppConfigInfo.BcuDataInfo.socd_pct_bcuSocE = socd_pct_bcuSocEo;
+    AppConfigInfo.BcuDataInfo.socd_pct_battSocE = socd_pct_battSocEo;
+    AppConfigInfo.BcuDataInfo.sohd_tm_chrgStartStatE = sohd_tm_chrgStartStatEo;
+    AppConfigInfo.BcuDataInfo.sohd_flg_chrgEndE = sohd_flg_chrgEndEo;
+    memcpy(AppConfigInfo.BcuDataInfo.sohv_V_chrgStartStatE, sohv_V_chrgStartStatEo, sizeof(sohv_V_chrgStartStatEo));
+    AppConfigInfo.BcuDataInfo.sohd_Q_chrgE = sohd_Q_chrgEo;
+    memcpy(AppConfigInfo.BcuDataInfo.sohv_Q_packCapArrE, sohv_Q_packCapArrEo, sizeof(sohv_Q_packCapArrEo));
+    memcpy(AppConfigInfo.BcuDataInfo.sohv_Q_cellCapArrE, sohv_Q_cellCapArrEo, sizeof(sohv_Q_cellCapArrEo));
+    memcpy(AppConfigInfo.BcuDataInfo.iscv_Q_remainCpE, iscv_Q_remainCpEo, sizeof(iscv_Q_remainCpEo));
+    memcpy(AppConfigInfo.BcuDataInfo.sorv_ohm_cellRE, sorv_R_cellEo, sizeof(sorv_R_cellEo));
+    AppConfigInfo.BcuDataInfo.iscd_tm_totalE = iscd_tm_totalEo;
+    AppConfigInfo.BcuDataInfo.sfmd_flg_mainCirClosFltE = sfmd_flg_mainCirClosFltEo;
+    AppConfigInfo.BcuDataInfo.sfmd_flg_heatCirClosFltE = sfmd_flg_heatCirClosFltEo;
+    AppConfigInfo.BcuDataInfo.sfmd_flg_heatCirOpenFltE = sfmd_flg_heatCirOpenFltEo;
+    AppConfigInfo.BcuDataInfo.sfmd_flg_heatRunFltE = sfmd_flg_heatRunFltEo;
+    AppConfigInfo.BcuDataInfo.sfmd_flg_iscFltE = sfmd_flg_iscFltEo;
+    AppConfigInfo.appSaveFlg = TRUE;
+}

+ 22 - 0
code/app/bms/BCU.h

@@ -0,0 +1,22 @@
+#include "rtwtypes.h"
+#include "AppGlobalVar.h"
+#include "SFM.h"
+#include "SPM.h"
+#include "CSM.h"
+#include "ISC.h"
+#include "TMS.h"
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#define PROC_BCU_TASK_STACK_SIZE           (2048)
+typedef enum
+{
+    PROCESS_STATE_INIT = 0,
+    PROCESS_STATE_IDLE,
+    PROCESS_STATE_WORK,
+    PROCESS_STATE_SLEEP
+}process_Bcu;
+
+extern void BCU_Init(void);
+extern void BCU(void);
+extern void BCUEEDataSave(void);
+

+ 119 - 0
code/app/bms/BCUCal.c

@@ -0,0 +1,119 @@
+
+#include "rtwtypes.h"
+
+const uint16_T blcc_R_esr = 1000U;  /* 均衡电阻 */
+const uint16_T blcc_T_close = 125U; /* 均衡暂停温度; */
+const uint16_T blcc_T_open = 100U;  /* 均衡暂停恢复温度; */
+const uint16_T blcc_V_low = 10U;    /* 均衡开启电压阈值 */
+
+const uint16_T cmnc_Q_ratedCp = 500U;                                                                                                      /* 电池容量; */
+uint16_T cmnc_num_cellUNum = 20U;                                                                                                          /* 电压采样点实际个数; */
+uint16_T cmnc_num_modTNum = 4U;                                                                                                            /* 温度采样点实际个数; */
+const uint16_T cmnc_tm_parkTime = 1800U;                                                                                                   /* 静置时间阈值; */
+const uint16_T cmnm_F_polar[13] = {5708U, 10079U, 18901U, 24298U, 25621U, 24240U, 26329U, 29043U, 23753U, 25286U, 25622U, 25968U, 28782U}; /* 电池放电参数的RC数组; */
+const uint16_T cmnm_R_ohm[13] = {2364U, 2284U, 2234U, 2166U, 2128U, 2111U, 2090U, 2077U, 2077U, 2072U, 2085U, 2090U, 2077U};               /* 电池放电参数的Ro数组; */
+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_disChrgLim = 2900U;
+const uint16_T cmnc_V_chrgFul = 4190U; /* 充满电的截至电压; */
+const uint16_T cmnm_R_voloffset[28] = {0, 0, 0, 0, 0,
+                                       0, 770, 0, 0, 0,
+                                       0, 0, 0, 540, 0,
+                                       0, 0, 0, 0, 0,
+                                       0, 0, 0, 0, 0,
+                                       0, 0, 0}; /*电压铜牌阻值补偿,单位moh*/
+
+const uint16_T sfmc_I_chrgCurrOverThr = 600;     /* 充电电流阈值 */
+const uint16_T sfmc_I_disChrgCurrOverThr = 600;  /* 放电电流阈值 */
+const uint16_T sfmc_T_ACPlugTOverThrFlt1 = 90;   /* 慢充插头温度过高1级故障诊断阈值 */
+const uint16_T sfmc_T_ACPlugTOverThrFlt2 = 100;  /* 慢充插头温度过高2级故障诊断阈值 */
+const uint16_T sfmc_T_ACPlugTOverThrRec1 = 80;   /* 慢充插头温度过高1级故障恢复阈值 */
+const uint16_T sfmc_T_ACPlugTOverThrRec2 = 80;   /* 慢充插头温度过高2级故障恢复阈值 */
+const uint16_T sfmc_T_DCPlugTOverThrFlt1 = 90;   /* 快充插头温度过高1级故障诊断阈值 */
+const uint16_T sfmc_T_DCPlugTOverThrFlt2 = 100;  /* 快充插头温度过高2级故障诊断阈值 */
+const uint16_T sfmc_T_DCPlugTOverThrRec1 = 80;   /* 快充插头温度过高1级故障恢复阈值 */
+const uint16_T sfmc_T_DCPlugTOverThrRec2 = 80;   /* 快充插头温度过高2级故障恢复阈值 */
+const uint16_T sfmc_T_chrgModTLowThrFlt1 = 42U;  /* 充电模组温度过低1级故障诊断阈值 */
+const uint16_T sfmc_T_chrgModTLowThrFlt2 = 40U;  /* 充电模组温度过低2级故障诊断阈值 */
+const uint16_T sfmc_T_chrgModTLowThrRec1 = 45U;  /* 充电模组温度过低1级故障恢复阈值 */
+const uint16_T sfmc_T_chrgModTLowThrRec2 = 45U;  /* 充电模组温度过低2级故障恢复阈值 */
+const uint16_T sfmc_T_chrgModTOverThrFlt1 = 92U; /* 充电模组温度过高1级故障诊断阈值 */
+const uint16_T sfmc_T_chrgModTOverThrFlt2 = 95U; /* 充电模组温度过高2级故障诊断阈值 */
+const uint16_T sfmc_T_chrgModTOverThrRec1 = 90U; /* 充电模组温度过高1级故障恢复阈值 */
+const uint16_T sfmc_T_chrgModTOverThrRec2 = 90U; /* 充电模组温度过高2级故障恢复阈值 */
+const uint16_T sfmc_T_chrgMosTOverThrFlt1 = 120; /* 充电Mos温度过高1级故障诊断阈值 */
+const uint16_T sfmc_T_chrgMosTOverThrFlt2 = 125; /* 充电Mos温度过高2级故障诊断阈值 */
+const uint16_T sfmc_T_chrgMosTOverThrRec1 = 110; /* 充电Mos温度过高1级故障恢复阈值 */
+const uint16_T sfmc_T_chrgMosTOverThrRec2 = 110; /* 充电Mos温度过高2级故障恢复阈值 */
+
+const uint16_T sfmc_T_disChrgModTLowThrFlt1 = 25U;  /* 放电模组温度过低1级故障诊断阈值 */
+const uint16_T sfmc_T_disChrgModTLowThrFlt2 = 20U;  /* 放电模组温度过低2级故障诊断阈值 */
+const uint16_T sfmc_T_disChrgModTLowThrRec1 = 30U;  /* 放电模组温度过低1级故障恢复阈值 */
+const uint16_T sfmc_T_disChrgModTLowThrRec2 = 30U;  /* 放电模组温度过低2级故障恢复阈值 */
+const uint16_T sfmc_T_disChrgModTOverThrFlt1 = 92U; /* 放电模组温度过高1级故障诊断阈值 */
+const uint16_T sfmc_T_disChrgModTOverThrFlt2 = 95U; /* 放电模组温度过高2级故障诊断阈值 */
+const uint16_T sfmc_T_disChrgModTOverThrRec1 = 90U; /* 放电模组温度过高1级故障恢复阈值 */
+const uint16_T sfmc_T_disChrgModTOverThrRec2 = 90U; /* 放电模组温度过高2级故障恢复阈值 */
+const uint16_T sfmc_T_disChrgMosTOverThrFlt1 = 120U;
+const uint16_T sfmc_T_disChrgMosTOverThrRec1 = 110U;
+const uint16_T sfmc_T_disChrgMosTOverThrFlt2 = 125U;
+const uint16_T sfmc_T_disChrgMosTOverThrRec2 = 110U;
+
+const uint16_T sfmc_T_heatPanTOverThrFlt1 = 85; /* 加热板温度过高1级故障诊断阈值 */
+const uint16_T sfmc_T_heatPanTOverThrFlt2 = 90; /* 加热板温度过高2级故障诊断阈值 */
+const uint16_T sfmc_T_heatPanTOverThrRec1 = 80; /* 加热板温度过高1级故障恢复阈值 */
+const uint16_T sfmc_T_heatPanTOverThrRec2 = 80; /* 加热板温度过高2级故障恢复阈值 */
+const uint16_T sfmc_T_modTDiffThrFlt1 = 20;     /* 模组温差过大1级故障诊断阈值 */
+const uint16_T sfmc_T_modTDiffThrFlt2 = 25;     /* 模组温差过大2级故障诊断阈值 */
+const uint16_T sfmc_T_modTDiffThrRec1 = 15;     /* 模组温差过大1级故障恢复阈值 */
+const uint16_T sfmc_T_modTDiffThrRec2 = 15;     /* 模组温差过大2级故障恢复阈值 */
+
+const uint16_T sfmc_V_battULowThrFlt1 = 590U;    /* 总压欠压1级故障诊断阈值 */
+const uint16_T sfmc_V_battULowThrFlt2 = 560U;    /* 总压欠压2级故障诊断阈值 */
+const uint16_T sfmc_V_battULowThrRec1 = 600U;    /* 总压欠压1级故障恢复阈值 */
+const uint16_T sfmc_V_battULowThrRec2 = 600U;    /* 总压欠压2级故障恢复阈值 */
+const uint16_T sfmc_V_battUOverThrFlt1 = 850U;   /* 总压过压1级故障诊断阈值 */
+const uint16_T sfmc_V_battUOverThrFlt2 = 870U;   /* 总压过压2级故障诊断阈值 */
+const uint16_T sfmc_V_battUOverThrRec1 = 840U;   /* 总压过压1级故障恢复阈值 */
+const uint16_T sfmc_V_battUOverThrRec2 = 840U;   /* 总压过压2级故障恢复阈值 */
+const uint16_T sfmc_V_cellULowThrFlt1 = 2950U;   /* 单体电压欠压1级故障诊断阈值 */
+const uint16_T sfmc_V_cellULowThrFlt2 = 2800U;   /* 单体电压欠压2级故障诊断阈值 */
+const uint16_T sfmc_V_cellULowThrRec1 = 3000U;   /* 单体电压欠压1级故障恢复阈值 */
+const uint16_T sfmc_V_cellULowThrRec2 = 3000U;   /* 单体电压欠压2级故障恢复阈值 */
+const uint16_T sfmc_V_cellUOverThrFlt1 = 4250U;  /* 单体电压过压1级故障诊断阈值 */
+const uint16_T sfmc_V_cellUOverThrFlt2 = 4350U;  /* 单体电压过压2级故障诊断阈值 */
+const uint16_T sfmc_V_cellUOverThrRec1 = 4200U;  /* 单体电压过压1级故障恢复阈值 */
+const uint16_T sfmc_V_cellUOverThrRec2 = 4200U;  /* 单体电压过压2级故障恢复阈值 */
+const uint16_T sfmc_flg_cellUDiffThrFlt1 = 250U; /* 压差过大1级故障诊断阈值 */
+const uint16_T sfmc_flg_cellUDiffThrFlt2 = 300U; /* 压差过大2级故障诊断阈值 */
+const uint16_T sfmc_flg_cellUDiffThrRec1 = 250U; /* 压差过大1级故障恢复阈值 */
+const uint16_T sfmc_flg_cellUDiffThrRec2 = 250U; /* 压差过大2级故障恢复阈值 */
+
+const uint16_T sohc_Q_countThr = 60U;       /*soh计算需充入电量阈值*/
+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 = 940U;                    /* 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对应的电压; */
+const uint16_T socm_V_disChrgCor[3] = {3238U, 3319U, 3369U}; /* 放电CCV对应的电压; */
+const uint16_T socc_pct_chrgCor = 910;                       /* 充电CCV对应的SOC; */
+const uint16_T socc_pct_disChrgCor = 50;                     /* 放电CCV对应的SOC; */
+const uint16_T cmm_T_ChrgCurr[3] = {40, 60, 80};
+const uint16_T cmm_V_ChrgCurr[6] = {3200, 3201, 3900, 3901, 4100, 4101};
+const uint16_T cmm_I_ChrgCurr[18] = {0, 100, 100, 100, 100, 50,
+                                     50, 400, 400, 200, 200, 100,
+                                     40, 300, 300, 150, 150, 80};
+
+const uint16_T tmsc_T_openThr = 45U;     /* 热管理开启温度; */
+const uint16_T tmsc_T_closeMinThr = 50U; /* 热管理关闭温度(最低模组); */
+const uint16_T tmsc_T_closeMaxThr = 70U; /* 热管理开启温度(最高模组); */
+const uint16_T tmsc_pct_socOpen = 100;   /* 热管理开启SOC阈值(非充电)*/
+const uint16_T tmsc_pct_socClos = 50;    /* 热管理退出SOC阈值(非充电)*/

+ 115 - 0
code/app/bms/BCUCal.h

@@ -0,0 +1,115 @@
+
+#include "rtwtypes.h"
+#define cmnc_num_cellUNumMax 28
+#define cmnc_num_modTNumMax 8
+extern const uint16_T blcc_R_esr;   /* 均衡电阻 */
+extern const uint16_T blcc_T_close; /* 均衡暂停温度; */
+extern const uint16_T blcc_T_open;  /* 均衡暂停恢复温度; */
+extern const uint16_T blcc_V_low;   /* 均衡开启电压阈值 */
+
+extern const uint16_T cmnc_Q_ratedCp;                /* 电池容量; */
+extern uint16_T cmnc_num_cellUNum;                   /* 电压采样点实际个数; */
+extern uint16_T cmnc_num_modTNum;                    /* 温度采样点实际个数; */
+extern const uint16_T cmnc_tm_parkTime;              /* 静置时间阈值; */
+extern const uint16_T cmnm_F_polar[13];              /* 电池放电参数的C数组; */
+extern const uint16_T cmnm_R_ohm[13];                /* 电池放电参数的Ro数组; */
+extern const uint16_T cmnm_R_polar[13];              /* 电池放电参数的Rp数组; */
+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级故障诊断阈值 */
+extern const int16_T sfmc_T_ACPlugTOverThrFlt2;      /* 慢充插头温度过高2级故障诊断阈值 */
+extern const int16_T sfmc_T_ACPlugTOverThrRec1;      /* 慢充插头温度过高1级故障恢复阈值 */
+extern const int16_T sfmc_T_ACPlugTOverThrRec2;      /* 慢充插头温度过高2级故障恢复阈值 */
+extern const int16_T sfmc_T_DCPlugTOverThrFlt1;      /* 快充插头温度过高1级故障诊断阈值 */
+extern const int16_T sfmc_T_DCPlugTOverThrFlt2;      /* 快充插头温度过高2级故障诊断阈值 */
+extern const int16_T sfmc_T_DCPlugTOverThrRec1;      /* 快充插头温度过高1级故障恢复阈值 */
+extern const int16_T sfmc_T_DCPlugTOverThrRec2;      /* 快充插头温度过高2级故障恢复阈值 */
+extern const uint16_T sfmc_T_chrgModTLowThrFlt1;     /* 充电模组温度过低1级故障诊断阈值 */
+extern const uint16_T sfmc_T_chrgModTLowThrFlt2;     /* 充电模组温度过低2级故障诊断阈值 */
+extern const uint16_T sfmc_T_chrgModTLowThrRec1;     /* 充电模组温度过低1级故障恢复阈值 */
+extern const uint16_T sfmc_T_chrgModTLowThrRec2;     /* 充电模组温度过低2级故障恢复阈值 */
+extern const uint16_T sfmc_T_chrgModTOverThrFlt1;    /* 充电模组温度过高1级故障诊断阈值 */
+extern const uint16_T sfmc_T_chrgModTOverThrFlt2;    /* 充电模组温度过高2级故障诊断阈值 */
+extern const uint16_T sfmc_T_chrgModTOverThrRec1;    /* 充电模组温度过高1级故障恢复阈值 */
+extern const uint16_T sfmc_T_chrgModTOverThrRec2;    /* 充电模组温度过高2级故障恢复阈值 */
+extern const int16_T sfmc_T_chrgMosTOverThrFlt1;     /* 充电Mos温度过高1级故障诊断阈值 */
+extern const int16_T sfmc_T_chrgMosTOverThrFlt2;     /* 充电Mos温度过高2级故障诊断阈值 */
+extern const int16_T sfmc_T_chrgMosTOverThrRec1;     /* 充电Mos温度过高1级故障恢复阈值 */
+extern const int16_T sfmc_T_chrgMosTOverThrRec2;     /* 充电Mos温度过高2级故障恢复阈值 */
+extern const uint16_T sfmc_T_disChrgModTLowThrFlt1;  /* 放电模组温度过低1级故障诊断阈值 */
+extern const uint16_T sfmc_T_disChrgModTLowThrFlt2;  /* 放电模组温度过低2级故障诊断阈值 */
+extern const uint16_T sfmc_T_disChrgModTLowThrRec1;  /* 放电模组温度过低1级故障恢复阈值 */
+extern const uint16_T sfmc_T_disChrgModTLowThrRec2;  /* 放电模组温度过低2级故障恢复阈值 */
+extern const uint16_T sfmc_T_disChrgModTOverThrFlt1; /* 放电模组温度过高1级故障诊断阈值 */
+extern const uint16_T sfmc_T_disChrgModTOverThrFlt2; /* 放电模组温度过高2级故障诊断阈值 */
+extern const uint16_T sfmc_T_disChrgModTOverThrRec1; /* 放电模组温度过高1级故障恢复阈值 */
+extern const uint16_T sfmc_T_disChrgModTOverThrRec2; /* 放电模组温度过高2级故障恢复阈值 */
+extern const int16_T sfmc_T_heatPanTOverThrFlt1;     /* 加热板温度过高1级故障诊断阈值 */
+extern const int16_T sfmc_T_heatPanTOverThrFlt2;     /* 加热板温度过高2级故障诊断阈值 */
+extern const int16_T sfmc_T_heatPanTOverThrRec1;     /* 加热板温度过高1级故障恢复阈值 */
+extern const int16_T sfmc_T_heatPanTOverThrRec2;     /* 加热板温度过高2级故障恢复阈值 */
+extern const int16_T sfmc_T_modTDiffThrFlt1;         /* 模组温差过大1级故障诊断阈值 */
+extern const int16_T sfmc_T_modTDiffThrFlt2;         /* 模组温差过大2级故障诊断阈值 */
+extern const int16_T sfmc_T_modTDiffThrRec1;         /* 模组温差过大1级故障恢复阈值 */
+extern const int16_T sfmc_T_modTDiffThrRec2;         /* 模组温差过大2级故障恢复阈值 */
+extern const uint16_T sfmc_V_battULowThrFlt1;        /* 总压欠压1级故障诊断阈值 */
+extern const uint16_T sfmc_V_battULowThrFlt2;        /* 总压欠压2级故障诊断阈值 */
+extern const uint16_T sfmc_V_battULowThrRec1;        /* 总压欠压1级故障恢复阈值 */
+extern const uint16_T sfmc_V_battULowThrRec2;        /* 总压欠压2级故障恢复阈值 */
+extern const uint16_T sfmc_V_battUOverThrFlt1;       /* 总压过压1级故障诊断阈值 */
+extern const uint16_T sfmc_V_battUOverThrFlt2;       /* 总压过压2级故障诊断阈值 */
+extern const uint16_T sfmc_V_battUOverThrRec1;       /* 总压过压1级故障恢复阈值 */
+extern const uint16_T sfmc_V_battUOverThrRec2;       /* 总压过压2级故障恢复阈值 */
+extern const uint16_T sfmc_V_cellULowThrFlt1;        /* 单体电压欠压1级故障诊断阈值 */
+extern const uint16_T sfmc_V_cellULowThrFlt2;        /* 单体电压欠压2级故障诊断阈值 */
+extern const uint16_T sfmc_V_cellULowThrRec1;        /* 单体电压欠压1级故障恢复阈值 */
+extern const uint16_T sfmc_V_cellULowThrRec2;        /* 单体电压欠压2级故障恢复阈值 */
+extern const uint16_T sfmc_V_cellUOverThrFlt1;       /* 单体电压过压1级故障诊断阈值 */
+extern const uint16_T sfmc_V_cellUOverThrFlt2;       /* 单体电压过压2级故障诊断阈值 */
+extern const uint16_T sfmc_V_cellUOverThrRec1;       /* 单体电压过压1级故障恢复阈值 */
+extern const uint16_T sfmc_V_cellUOverThrRec2;       /* 单体电压过压2级故障恢复阈值 */
+extern const uint16_T sfmc_flg_cellUDiffThrFlt1;     /* 压差过大1级故障诊断阈值 */
+extern const uint16_T sfmc_flg_cellUDiffThrFlt2;     /* 压差过大2级故障诊断阈值 */
+extern const uint16_T sfmc_flg_cellUDiffThrRec1;     /* 压差过大1级故障恢复阈值 */
+extern const uint16_T sfmc_flg_cellUDiffThrRec2;     /* 压差过大2级故障恢复阈值 */
+extern const uint16_T sfmc_T_disChrgMosTOverThrFlt1;
+extern const uint16_T sfmc_T_disChrgMosTOverThrRec1;
+extern const uint16_T sfmc_T_disChrgMosTOverThrFlt2;
+extern const uint16_T sfmc_T_disChrgMosTOverThrRec2;
+
+extern const uint16_T sohc_Q_countThr;      /*                    */
+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对应的电流数据; */
+extern const int16_T socm_I_disChrgCor[3];  /* 放电CCV对应的电流数据; */
+extern const uint16_T socm_V_chrgCor[4];    /* 充电CCV对应的电压; */
+extern const uint16_T socm_V_disChrgCor[3]; /* 放电CCV对应的电压; */
+extern const uint16_T socc_pct_chrgCor;
+extern const uint16_T socc_pct_disChrgCor;
+
+extern const uint16_T cmm_T_ChrgCurr[3];
+extern const uint16_T cmm_V_ChrgCurr[6];
+extern const uint16_T cmm_I_ChrgCurr[18];
+
+extern const uint16_T tmsc_T_openThr;     /* 热管理开启温度; */
+extern const uint16_T tmsc_T_closeMinThr; /* 热管理关闭温度(最低模组); */
+extern const uint16_T tmsc_T_closeMaxThr; /* 热管理开启温度(最高模组); */
+extern const uint16_T tmsc_pct_socOpen;/* 热管理开启SOC阈值(非充电)*/
+extern const uint16_T tmsc_pct_socClos;/* 热管理推出SOC阈值(非充电)*/
+

+ 191 - 0
code/app/bms/BCUDisp.c

@@ -0,0 +1,191 @@
+
+#include "BCUdisp.h"
+
+uint16_T appv_V_cellU[cmnc_num_cellUNumMax];                        /* 静态电压 */
+uint8_T  appd_st_preCyc;
+
+boolean_T bcud_flg_firstRun;
+boolean_T  spmd_flg_firstRun;
+boolean_T  socd_flg_firstRun;
+boolean_T  sohd_flg_firstRun;
+boolean_T  blcd_flg_firstRun;
+boolean_T  sord_flg_firstRun;
+boolean_T  soed_flg_firstRun;
+boolean_T  iscd_flg_firstRun;
+boolean_T  pimd_flg_firstRun;
+boolean_T  sfmd_flg_firstRun;
+boolean_T  tmsd_flg_firstRun;
+boolean_T  cdmd_flg_firstRun;
+boolean_T  csmd_flg_firstRun;
+boolean_T  sopd_flg_firstRun;
+
+uint16_T  blcv_Q_reqCpEi[cmnc_num_cellUNumMax];                      /*均衡需求容量 读取量(数组); */
+uint16_T  blcv_Q_reqCpEo[cmnc_num_cellUNumMax];                      /*均衡需求容量 写入量(数组); */
+uint32_T  blcv_Q_totalCpEi[cmnc_num_cellUNumMax];                    /*累计均衡容量 读取量(数组); */
+uint32_T  blcv_Q_totalCpEo[cmnc_num_cellUNumMax];                    /*累计均衡容量 写入量(数组); */
+boolean_T blcv_flg_excute[cmnc_num_cellUNumMax];                    /*均衡执行请求标志位 (数组); */
+
+boolean_T ihd_flg_HVILFlt;                        /* 保护板上传的高压互锁故障 */
+boolean_T ihd_flg_DTCClear;                       /* 上位机发送的故障清楚指令;*/
+uint8_T   ihd_st_authFaild;                         /* 底层诊断的认证失败故障;*/
+int16_T   ihd_I_curr;                               /*电池包电流; */
+uint8_T   ihd_st_chrgConnect;                       /*充电器连接状态; */
+uint16_T  ihd_P_gas;                               /*气体浓度 */
+uint16_T  ihd_T_ACPlugT;                           /*慢充插头温度 +40 */
+uint16_T  ihd_T_DCPlugT;                           /*快充插头温度+40 */
+uint16_T  ihd_T_bdtemp;                            /*板子温度 */
+uint16_T  ihd_T_heatPanT1;                         /*加热板温度1+40 */
+uint16_T  ihd_T_heatPanT2;                         /*加热板温度2 +40 */
+uint16_T  ihd_T_mosT;                              /*Mos温度+40 */
+boolean_T ihd_flg_EESaveFlt;                      /*EE存储故障 */
+boolean_T ihd_flg_battULowFlt;                    /*保护板上传的总压欠压故障; */
+boolean_T ihd_flg_battUOverFlt;                   /*保护板上传的总压过压故障; */
+boolean_T ihd_flg_cellULowFlt;                    /*保护板上传的单体欠压故障; */
+boolean_T ihd_flg_cellUOverFlt;                   /*保护板上传的单体过压故障; */
+boolean_T ihd_flg_chrgCurrOverFlt;                /*保护板上传的充电过流故障; */
+boolean_T ihd_flg_chrgModTLowFlt;                 /*保护板上传的充电模组温度过低故障; */
+boolean_T ihd_flg_chrgModTOverFlt;                /*保护板上传的充电模组温度过高故障; */
+boolean_T ihd_flg_chrgMosClosFlt;                 /*充电Mos失效 */
+boolean_T ihd_flg_chrgMosTOverFlt;                /*保护板上传的充电Mos温度过高故障; */
+boolean_T ihd_flg_currOpenFlt;                    /*保护板上传的电流开路故障 */
+boolean_T ihd_flg_disChrgCurrOverFlt;             /*保护板上传的放电过流故障; */
+boolean_T ihd_flg_disChrgModTLowFlt;              /*保护板上传的放电模组温度过低故障; */
+boolean_T ihd_flg_disChrgModTOverFlt;             /*保护板上传的放电模组温度过高故障; */
+boolean_T ihd_flg_disChrgMosClosFlt;              /*放电Mos失效 */
+boolean_T ihd_flg_disChrgMosTOverFlt;             /*保护板上传的放电Mos温度过高故障; */
+boolean_T ihd_flg_urtRecFlt;                      /*内网通讯故障 */
+uint16_T  ihd_pct_soc;                             /*保护板SOC */
+uint16_T  ihd_pct_soh;                             /*保护板SOH */
+uint8_T   ihd_st_workStat;                          /*电池工作状态 */
+uint16_T  ihd_tm_parkTime;                         /*驻车时间; */
+uint16_T  ihv_T_modT[cmnc_num_modTNumMax];                           /*模组温度(数组)+40 */
+uint16_T  ihv_V_cellU[cmnc_num_cellUNumMax];                         /*电池单体电压(数组); */
+boolean_T ihd_st_chrgMosControl;    
+boolean_T ihd_st_disChrgMosControl; 
+boolean_T ihd_st_relayControl;    
+uint8_T   ihd_st_heatForceControl;
+uint8_T   ihd_st_EOLState;
+boolean_T ihd_flg_urtRecFlg;
+uint8_T   ihd_st_reSet;
+uint8_T ihd_st_heatStat;
+uint8_T ihd_st_wakeUpStat;
+
+int16_T   sfmd_I_curr;                              /*处理后整包电流 */
+uint16_T  sfmd_T_modTMax;                          /*处理后模组温度最小 */
+uint16_T  sfmd_T_modTMin;                          /*处理后模组温度最大 */
+uint16_T  sfmd_idx_modTMax;                          /*处理后模组温度最小 */
+uint16_T  sfmd_idx_modTMin;                          /*处理后模组温度最大 */
+uint16_T  sfmd_V_cellUAvrg;                        /*处理后单体电压平均 */
+uint16_T  sfmd_V_cellUMax;                         /*处理后单体电压最大 */
+uint16_T  sfmd_V_cellUMin;                         /*处理后单体电压最小 */
+uint16_T  sfmd_idx_cellUMin;
+uint16_T  sfmd_idx_cellUMax;
+boolean_T sfmd_flg_cellUInval;                  /*单体电压有效标志位 ; 0为有效;1为无效 */
+boolean_T sfmd_flg_currInval;                   /*电流有效标志位 ; 0为有效;1为无效 */
+boolean_T sfmd_flg_modTInval;                   /*模组温度有效标志位 ; 0为有效;1为无效 */
+uint16_T  sfmd_num_fltNum;                         /*故障数量 */
+uint8_T   sfmd_st_fltAct;                           /*故障禁止指令 */
+uint8_T   sfmd_st_fltLevel;                         /*故障等级 */
+uint16_T  sfmv_T_modT[cmnc_num_modTNumMax];                          /*处理后模组温度 */
+uint16_T  sfmv_V_cellU[cmnc_num_cellUNumMax];                        /*处理后单体电压 */
+uint16_T  sfmv_idx_fltCode[20];                    /*诊断故障码(数组) */
+uint16_T  sfmd_V_battU;                            /* 处理过后的总电压 */
+boolean_T sfmd_flg_mainCirClosFltEi;              /*主回路常闭故障读取量 */  
+boolean_T sfmd_flg_mainCirClosFltEo;              /*主回路常闭故障写入量 */  
+boolean_T sfmd_flg_heatCirClosFltEi;              /*加热回路常闭故障读取量 */  
+boolean_T sfmd_flg_heatCirClosFltEo;              /*加热回路常闭故障写入量 */  
+boolean_T sfmd_flg_heatCirOpenFltEi;              /*加热回路常开故障读取量 */  
+boolean_T sfmd_flg_heatCirOpenFltEo;              /*加热回路常开故障写入量 */  
+boolean_T sfmd_flg_heatRunFltEi;
+boolean_T sfmd_flg_heatRunFltEo;
+boolean_T sfmd_flg_iscFltEi;
+boolean_T sfmd_flg_iscFltEo;
+
+uint16_T  socd_pct_vcuSoc;                          /*vcuSOC; */
+uint16_T  socd_pct_ahSoc;                          /*安时SOC; */
+uint16_T  socd_pct_estSoc;                         /*估算SOC;*/
+uint16_T  socd_flg_EEsave;                         /*实时存储标志位;*/
+uint16_T  socd_pct_ekfSoc;                         /*EKFSOC;*/
+uint16_T  socd_pct_battSoc;                        /*电池真实SOC; */
+uint16_T  socd_pct_battSocEi;                      /*电池真实SOC 读取量; */
+uint16_T  socd_pct_battSocEo;                      /*电池真实SOC 写入量; */
+uint16_T  socd_pct_bcuSoc;                         /*电池显示SOC; */
+uint16_T  socd_pct_bcuSocEi;                       /*电池显示SOC读取量; */
+uint16_T  socd_pct_bcuSocEo;                       /*电池显示SOC写入量; */
+uint16_T  socv_pct_cellSoc[cmnc_num_cellUNumMax];
+uint16_T  socd_pct_cellBattSoc;
+boolean_T socd_flg_cellSocDisable;
+
+uint16_T  sohd_Q_chrgEi;                           /*充入容量读取量; */
+uint16_T  sohd_Q_chrgEo;                           /*充入容量写入量; */
+boolean_T sohd_flg_chrgEndEi;                     /*充电结束标志位读取量; */
+boolean_T sohd_flg_chrgEndEo;                     /*充电结束标志位写入量; */
+uint16_T  sohd_pct_bcuSoh;                         /*电池SOH; */
+uint16_T  sohd_tm_chrgStartStatEi;                 /*充电前静置时间读取量; */
+uint16_T  sohd_tm_chrgStartStatEo;                 /*充电前静置时间写入量; */
+uint16_T  sohv_Q_cellCap[cmnc_num_cellUNumMax];                      /*单体容量 */
+uint16_T  sohv_Q_cellCapArrEi[cmnc_num_cellUNumMax];                 /*单体容量(数组) 读取量 */
+uint16_T  sohv_Q_cellCapArrEo[cmnc_num_cellUNumMax];                 /*单体容量(数组) 写入量 */
+uint16_T  sohv_Q_packCapArrEi[10];                 /*10次整包容量(数组)读取量; */
+uint16_T  sohv_Q_packCapArrEo[10];                 /*10次整包容量(数组)写入量; */
+uint16_T  sohv_V_chrgStartStatEi[cmnc_num_cellUNumMax];              /*充电开始时刻的单体电压(数组)读取量; */
+uint16_T  sohv_V_chrgStartStatEo[cmnc_num_cellUNumMax];              /*充电开始时刻的单体电压(数组)写入量; */
+
+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_R_cellEi[cmnc_num_cellUNumMax];
+uint16_T  sorv_R_cellEo[cmnc_num_cellUNumMax];
+uint16_T  sorv_R_cell[cmnc_num_cellUNumMax];
+
+boolean_T iscd_flg_flt[3];
+uint16_T  iscv_Q_remainCpEi[cmnc_num_cellUNumMax];
+uint32_T  iscd_tm_totalEi;
+uint16_T  iscv_Q_remainCpEo[cmnc_num_cellUNumMax];
+uint32_T  iscd_tm_totalEo;
+
+uint8_T   tmsd_st_heatAct;                          /*热管理请求状态; */
+
+uint8_T   csmd_st_chrgMod;                           /* 充电模式  */
+uint8_T   csmd_st_chrgSt;                            /* 充电状态  */
+int16_T   csmd_I_chrgCurrReq;                       /* 充电需求电流  */
+uint8_T   csmd_idx_chrgEndReason;                    /* 充电结束原因  */
+
+uint16_T  cand_idx_cellNr;                          /*循环发送的单体编号; */
+uint16_T  cand_Q_cellCap;                          /*循环发送的单体容量; */
+uint16_T  cand_V_chrgStartStat;                    /*循环发送的充电前单体电压; */
+uint16_T  cand_Q_blcReqCp;                            /*循环发送的单体需求均衡容量; */
+uint16_T  cand_Q_blcTotalCp;                          /*循环发送的单体累计均衡容量; */
+
+int16_T   cdmv_V_deltOCV[cmnc_num_cellUNumMax];
+int16_T   cdmv_R_deltOhm[cmnc_num_cellUNumMax];
+boolean_T cdmv_flg_inval[cmnc_num_cellUNumMax];
+
+uint16_T   pimd_V_ocv;
+uint16_T   pimd_R_ohm;
+uint16_T   pimd_R_polar;
+uint16_T   pimd_F_polar;
+uint16_T   pimv_V_cellOcv[cmnc_num_cellUNumMax];
+uint16_T   pimv_R_cellOhm[cmnc_num_cellUNumMax];
+uint16_T   pimd_pct_battSoc;
+uint16_T   pimv_pct_cellSoc[cmnc_num_cellUNumMax];
+boolean_T  pimv_flg_inval[cmnc_num_cellUNumMax];
+boolean_T  pimd_flg_inval; 
+	
+
+uint16_T test_cellCap[cmnc_num_cellUNumMax];
+real_T test_U1;
+real_T test_U[cmnc_num_cellUNumMax];
+
+
+
+

+
+

+

+ 187 - 0
code/app/bms/BCUDisp.h

@@ -0,0 +1,187 @@
+
+#include "rtwtypes.h"
+#include "BCUCal.h"
+
+extern uint16_T appv_V_cellU[cmnc_num_cellUNumMax];                        /* 静态电压 */
+extern uint8_T appd_st_preCyc;
+
+extern boolean_T  bcud_flg_firstRun;
+extern boolean_T  spmd_flg_firstRun;
+extern boolean_T  socd_flg_firstRun;
+extern boolean_T  sohd_flg_firstRun;
+extern boolean_T  blcd_flg_firstRun;
+extern boolean_T  sord_flg_firstRun;
+extern boolean_T  soed_flg_firstRun;
+extern boolean_T  iscd_flg_firstRun;
+extern boolean_T  pimd_flg_firstRun;
+extern boolean_T  sfmd_flg_firstRun;
+extern boolean_T  tmsd_flg_firstRun;
+extern boolean_T  cdmd_flg_firstRun;
+extern boolean_T  csmd_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];                      /*均衡需求容量 写入量(数组); */
+extern uint32_T  blcv_Q_totalCpEi[cmnc_num_cellUNumMax];                    /*累计均衡容量 读取量(数组); */
+extern uint32_T  blcv_Q_totalCpEo[cmnc_num_cellUNumMax];                    /*累计均衡容量 写入量(数组); */
+extern boolean_T blcv_flg_excute[cmnc_num_cellUNumMax];                    /*均衡执行请求标志位 (数组); */
+
+extern boolean_T ihd_flg_HVILFlt;                        /* 保护板上传的高压互锁故障 */
+extern boolean_T ihd_flg_DTCClear;                       /* 上位机发送的故障清楚指令;*/
+extern uint8_T   ihd_st_authFaild;                         /* 底层诊断的认证失败故障;*/
+extern int16_T   ihd_I_curr;                               /*电池包电流; */
+extern uint8_T   ihd_st_chrgConnect;                       /*充电器连接状态; */
+extern uint16_T  ihd_P_gas;                               /*气体浓度 */
+extern uint16_T  ihd_T_ACPlugT;                           /*慢充插头温度 +40 */
+extern uint16_T  ihd_T_DCPlugT;                           /*快充插头温度+40 */
+extern uint16_T  ihd_T_bdtemp;                            /*板子温度 */
+extern uint16_T  ihd_T_heatPanT1;                         /*加热板温度1+40 */
+extern uint16_T  ihd_T_heatPanT2;                         /*加热板温度2 +40 */
+extern uint16_T  ihd_T_mosT;                              /*Mos温度+40 */
+extern boolean_T ihd_flg_EESaveFlt;                      /*EE存储故障 */
+extern boolean_T ihd_flg_battULowFlt;                    /*保护板上传的总压欠压故障; */
+extern boolean_T ihd_flg_battUOverFlt;                   /*保护板上传的总压过压故障; */
+extern boolean_T ihd_flg_cellULowFlt;                    /*保护板上传的单体欠压故障; */
+extern boolean_T ihd_flg_cellUOverFlt;                   /*保护板上传的单体过压故障; */
+extern boolean_T ihd_flg_chrgCurrOverFlt;                /*保护板上传的充电过流故障; */
+extern boolean_T ihd_flg_chrgModTLowFlt;                 /*保护板上传的充电模组温度过低故障; */
+extern boolean_T ihd_flg_chrgModTOverFlt;                /*保护板上传的充电模组温度过高故障; */
+extern boolean_T ihd_flg_chrgMosClosFlt;                 /*充电Mos失效 */
+extern boolean_T ihd_flg_chrgMosTOverFlt;                /*保护板上传的充电Mos温度过高故障; */
+extern boolean_T ihd_flg_currOpenFlt;                    /*保护板上传的电流开路故障 */
+extern boolean_T ihd_flg_disChrgCurrOverFlt;             /*保护板上传的放电过流故障; */
+extern boolean_T ihd_flg_disChrgModTLowFlt;              /*保护板上传的放电模组温度过低故障; */
+extern boolean_T ihd_flg_disChrgModTOverFlt;             /*保护板上传的放电模组温度过高故障; */
+extern boolean_T ihd_flg_disChrgMosClosFlt;              /*放电Mos失效 */
+extern boolean_T ihd_flg_disChrgMosTOverFlt;             /*保护板上传的放电Mos温度过高故障; */
+extern boolean_T ihd_flg_urtRecFlt;                      /*内网通讯故障 */
+extern uint16_T  ihd_pct_soc;                             /*保护板SOC */
+extern uint16_T  ihd_pct_soh;                             /*保护板SOH */
+extern uint8_T   ihd_st_workStat;                          /*电池工作状态 */
+extern uint16_T  ihd_tm_parkTime;                         /*驻车时间; */
+extern uint16_T  ihv_T_modT[cmnc_num_modTNumMax];                           /*模组温度(数组)+40 */
+extern uint16_T  ihv_V_cellU[cmnc_num_cellUNumMax];                         /*电池单体电压(数组); */
+extern boolean_T ihd_st_chrgMosControl;    
+extern boolean_T ihd_st_disChrgMosControl; 
+extern boolean_T ihd_st_relayControl;    
+extern uint8_T   ihd_st_heatForceControl;
+extern uint8_T   ihd_st_EOLState;
+extern boolean_T ihd_flg_urtRecFlg;
+extern uint8_T   ihd_st_reSet;
+extern uint8_T   ihd_st_heatStat;
+extern uint8_T   ihd_st_wakeUpStat; 
+
+extern int16_T   sfmd_I_curr;                              /*处理后整包电流 */
+extern uint16_T  sfmd_T_modTMax;                          /*处理后模组温度最小 */
+extern uint16_T  sfmd_T_modTMin;                          /*处理后模组温度最大 */
+extern uint16_T  sfmd_idx_modTMax;                          /*处理后模组温度最小 */
+extern uint16_T  sfmd_idx_modTMin;                          /*处理后模组温度最大 */
+extern uint16_T  sfmd_V_cellUAvrg;                        /*处理后单体电压平均 */
+extern uint16_T  sfmd_V_cellUMax;                         /*处理后单体电压最大 */
+extern uint16_T  sfmd_V_cellUMin;                         /*处理后单体电压最小 */
+extern uint16_T  sfmd_idx_cellUMin;
+extern uint16_T  sfmd_idx_cellUMax;
+extern boolean_T sfmd_flg_cellUInval;                  /*单体电压有效标志位 ; 0为有效;1为无效 */
+extern boolean_T sfmd_flg_currInval;                   /*电流有效标志位 ; 0为有效;1为无效 */
+extern boolean_T sfmd_flg_modTInval;                   /*模组温度有效标志位 ; 0为有效;1为无效 */
+extern uint16_T  sfmd_num_fltNum;                         /*故障数量 */
+extern uint8_T   sfmd_st_fltAct;                           /*故障禁止指令 */
+extern uint8_T   sfmd_st_fltLevel;                         /*故障等级 */
+extern uint16_T  sfmv_T_modT[cmnc_num_modTNumMax];                          /*处理后模组温度 */
+extern uint16_T  sfmv_V_cellU[cmnc_num_cellUNumMax];                        /*处理后单体电压 */
+extern uint16_T  sfmv_idx_fltCode[20];                    /*诊断故障码(数组) */
+extern uint16_T  sfmd_V_battU;                            /* 处理过后的总电压 */
+extern boolean_T sfmd_flg_mainCirClosFltEi;              /*主回路常闭故障读取量 */  
+extern boolean_T sfmd_flg_mainCirClosFltEo;              /*主回路常闭故障写入量 */  
+extern boolean_T sfmd_flg_heatCirClosFltEi;              /*加热回路常闭故障读取量 */  
+extern boolean_T sfmd_flg_heatCirClosFltEo;              /*加热回路常闭故障写入量 */  
+extern boolean_T sfmd_flg_heatCirOpenFltEi;              /*加热回路常开故障读取量 */  
+extern boolean_T sfmd_flg_heatCirOpenFltEo;              /*加热回路常开故障写入量 */  
+extern boolean_T sfmd_flg_heatRunFltEi;
+extern boolean_T sfmd_flg_heatRunFltEo;
+extern boolean_T sfmd_flg_iscFltEi;
+extern boolean_T sfmd_flg_iscFltEo;
+
+extern uint16_T  socd_pct_vcuSoc;                          /*vcuSOC; */
+extern uint16_T  socd_pct_ahSoc;                          /*安时SOC; */
+extern uint16_T  socd_pct_estSoc;                         /*估算SOC;*/
+extern uint16_T  socd_flg_EEsave;                         /*实时存储标志位;*/
+extern uint16_T  socd_pct_ekfSoc;                         /*EKFSOC;*/
+extern uint16_T  socd_pct_battSoc;                        /*电池真实SOC; */
+extern uint16_T  socd_pct_battSocEi;                      /*电池真实SOC 读取量; */
+extern uint16_T  socd_pct_battSocEo;                      /*电池真实SOC 写入量; */
+extern uint16_T  socd_pct_bcuSoc;                         /*电池显示SOC; */
+extern uint16_T  socd_pct_bcuSocEi;                       /*电池显示SOC读取量; */
+extern uint16_T  socd_pct_bcuSocEo;                       /*电池显示SOC写入量; */
+extern uint16_T  socv_pct_cellSoc[cmnc_num_cellUNumMax];
+extern uint16_T  socd_pct_cellBattSoc;
+extern boolean_T socd_flg_cellSocDisable;
+
+extern uint16_T  sohd_Q_chrgEi;                           /*充入容量读取量; */
+extern uint16_T  sohd_Q_chrgEo;                           /*充入容量写入量; */
+extern boolean_T sohd_flg_chrgEndEi;                     /*充电结束标志位读取量; */
+extern boolean_T sohd_flg_chrgEndEo;                     /*充电结束标志位写入量; */
+extern uint16_T  sohd_pct_bcuSoh;                         /*电池SOH; */
+extern uint16_T  sohd_tm_chrgStartStatEi;                 /*充电前静置时间读取量; */
+extern uint16_T  sohd_tm_chrgStartStatEo;                 /*充电前静置时间写入量; */
+extern uint16_T  sohv_Q_cellCap[cmnc_num_cellUNumMax];                      /*单体容量 */
+extern uint16_T  sohv_Q_cellCapArrEi[cmnc_num_cellUNumMax];                 /*单体容量(数组) 读取量 */
+extern uint16_T  sohv_Q_cellCapArrEo[cmnc_num_cellUNumMax];                 /*单体容量(数组) 写入量 */
+extern uint16_T  sohv_Q_packCapArrEi[10];                 /*10次整包容量(数组)读取量; */
+extern uint16_T  sohv_Q_packCapArrEo[10];                 /*10次整包容量(数组)写入量; */
+extern uint16_T  sohv_V_chrgStartStatEi[cmnc_num_cellUNumMax];              /*充电开始时刻的单体电压(数组)读取量; */
+extern uint16_T  sohv_V_chrgStartStatEo[cmnc_num_cellUNumMax];              /*充电开始时刻的单体电压(数组)写入量; */
+
+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_R_cellEi[cmnc_num_cellUNumMax];
+extern uint16_T sorv_R_cellEo[cmnc_num_cellUNumMax];
+extern uint16_T sorv_R_cell[cmnc_num_cellUNumMax];
+
+extern boolean_T iscd_flg_flt[3];
+extern uint16_T  iscv_Q_remainCpEi[cmnc_num_cellUNumMax];
+extern uint32_T  iscd_tm_totalEi;
+extern uint16_T  iscv_Q_remainCpEo[cmnc_num_cellUNumMax];
+extern uint32_T  iscd_tm_totalEo;
+
+extern uint8_T tmsd_st_heatAct;                          /*热管理请求状态; */
+
+extern uint8_T csmd_st_chrgMod;                           /* 充电模式  */
+extern uint8_T csmd_st_chrgSt;                            /* 充电状态  */
+extern int16_T csmd_I_chrgCurrReq;                       /* 充电需求电流  */
+extern uint8_T csmd_idx_chrgEndReason;                    /* 充电结束原因  */
+
+extern uint16_T cand_idx_cellNr;                          /*循环发送的单体编号; */
+extern uint16_T cand_Q_cellCap;                          /*循环发送的单体容量; */
+extern uint16_T cand_V_chrgStartStat;                    /*循环发送的充电前单体电压; */
+extern uint16_T cand_Q_blcReqCp;                            /*循环发送的单体需求均衡容量; */
+extern uint16_T cand_Q_blcTotalCp;                          /*循环发送的单体累计均衡容量; */
+
+extern int16_T   cdmv_V_deltOCV[cmnc_num_cellUNumMax];
+extern int16_T   cdmv_R_deltOhm[cmnc_num_cellUNumMax];
+extern boolean_T cdmv_flg_inval[cmnc_num_cellUNumMax];
+
+
+extern uint16_T  pimd_V_ocv;
+extern uint16_T  pimd_R_ohm;
+extern uint16_T  pimd_R_polar;
+extern uint16_T  pimd_F_polar;
+extern uint16_T  pimv_V_cellOcv[cmnc_num_cellUNumMax];
+extern uint16_T  pimv_R_cellOhm[cmnc_num_cellUNumMax];
+extern uint16_T  pimd_pct_battSoc;
+extern uint16_T  pimv_pct_cellSoc[cmnc_num_cellUNumMax];
+extern boolean_T pimv_flg_inval[cmnc_num_cellUNumMax];
+extern boolean_T  pimd_flg_inval; 
+
+extern uint16_T test_cellCap[cmnc_num_cellUNumMax];
+extern real_T test_U1;
+extern real_T test_U[cmnc_num_cellUNumMax];
+
+

+ 169 - 0
code/app/bms/BLC.c

@@ -0,0 +1,169 @@
+#include "BLC.h"
+
+////////////////////////////////////////////////////////////////////////////
+void BLC_Init(void)
+{
+    blcd_flg_firstRun = true;
+}
+
+///////////////////////////////////////////////////////////////////////////
+void BLC(void)
+{   
+    uint16_T i;
+    static uint16_T blcn_Q_reqCpEE[cmnc_num_cellUNumMax];
+    static uint32_T blcn_Q_totalCpEE[cmnc_num_cellUNumMax];
+    
+    static boolean_T blcn_flg_judge;
+    boolean_T blcn_flg_enable;
+
+    
+    uint16_T blcn_pct_cellSoc[cmnc_num_cellUNumMax];
+    uint16_T blcn_pct_cellSocMin;
+    static uint16_T blcn_Q_reqCpNow[cmnc_num_cellUNumMax];
+    real_T Qmin;
+    real_T QL;
+    real_T reqCp;
+    
+    static uint16_T blcn_Q_reqCpEo_Delay[cmnc_num_cellUNumMax];
+    boolean_T blcn_flg_stop[cmnc_num_cellUNumMax];
+	boolean_T blcn_flg_pause[cmnc_num_cellUNumMax];
+    static real_T temp[cmnc_num_cellUNumMax];
+    uint16_T blcn_Q_impleCp[cmnc_num_cellUNumMax];
+
+	if(blcd_flg_firstRun)
+	{
+	  memset(blcn_Q_reqCpEo_Delay,0,sizeof(blcn_Q_reqCpEo_Delay));
+	  memset(temp,0,sizeof(temp)); 
+	}
+    //=========================================================================
+    //---------------------------------EE校验----------------------------------
+    //=========================================================================
+    
+    if(blcd_flg_firstRun)
+    {
+        if(ArrMax(blcv_Q_reqCpEi, cmnc_num_cellUNum) > cmnc_Q_ratedCp)
+        {
+            memset(blcn_Q_reqCpEE,  0, sizeof(blcn_Q_reqCpEE));
+            memset(blcn_Q_totalCpEE,0, sizeof(blcn_Q_totalCpEE));
+        }
+        else
+        {
+            memcpy(blcn_Q_reqCpEE,  blcv_Q_reqCpEi, sizeof(blcv_Q_reqCpEi));
+            memcpy(blcn_Q_totalCpEE,blcv_Q_totalCpEi, sizeof(blcn_Q_totalCpEE));
+        }	
+    }
+
+    //=========================================================================
+    //---------------------------------使能判断--------------------------------
+    //=========================================================================
+    if(blcd_flg_firstRun)
+    {
+		blcn_flg_judge	= (ihd_tm_parkTime >= cmnc_tm_parkTime)&& !sfmd_flg_cellUInval && (sfmd_I_curr > -10 && sfmd_I_curr < 10);
+    }
+    blcn_flg_enable = ((sfmd_st_fltAct >> 7) & 0x01) != 1;
+
+    //=========================================================================
+    //---------------------------------需求计算--------------------------------
+    //=========================================================================
+    if(blcd_flg_firstRun)
+    {
+        //压差法
+        if(blcn_flg_judge)
+        {
+            blcn_pct_cellSocMin = look1_u16tu16(sfmd_V_cellUMin,cmnm_V_ocv, cmnm_pct_soc, 13);
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                blcn_pct_cellSoc[i] = look1_u16tu16(sfmv_V_cellU[i], cmnm_V_ocv, cmnm_pct_soc, 13);
+            }
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                if(sfmv_V_cellU[i] - sfmd_V_cellUMin > blcc_V_low)
+                {
+                    blcn_Q_reqCpNow[i] = (uint16_T) ((real_T)(cmnc_Q_ratedCp * 0.1) * (real_T)((blcn_pct_cellSoc[i] - blcn_pct_cellSocMin) * 0.1) /100 * 1000);
+                }
+                else
+                {
+                    blcn_Q_reqCpNow[i] = 0;
+                }
+            }
+        }
+        else
+        {
+            memcpy(blcn_Q_reqCpNow,blcn_Q_reqCpEE, sizeof(blcn_Q_reqCpEE));
+        }
+  
+	
+        /*/ 最大化容量法
+        if(blcn_flg_judge)
+        {
+            Qmin = (real_T)(sohv_Q_cellCap[0] * 0.1) * (real_T)(blcn_pct_cellSoc[0] * 0.1)/100;
+            for(i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                if (Qmin >  (real_T)(sohv_Q_cellCap[i] * 0.1) * (real_T)(blcn_pct_cellSoc[i] * 0.1)/100)
+                {
+                    Qmin =  (real_T)(sohv_Q_cellCap[i] * 0.1) * (real_T)(blcn_pct_cellSoc[i] * 0.1)/100;
+                    QL   =  (real_T)(sohv_Q_cellCap[i] * 0.1) - Qmin;
+                }
+            }
+            for(i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                reqCp = QL- (real_T)(sohv_Q_cellCap[i] * 0.1)*(real_T)(blcn_pct_cellSoc[i] * 0.1)/100;
+                if (reqCp >0.001)
+                {
+                    blcn_Q_reqCpNow[i] =uint16_T(reqCp * 1000);
+                }
+            }
+        }
+        else
+        {
+            memcpy(blcn_Q_reqCpNow,blcn_Q_reqCpEE, sizeof(blcn_Q_reqCpEE));
+        } */
+    }
+
+
+    //=========================================================================
+    //---------------------------------stop计算--------------------------------
+    //=========================================================================
+    for(i = 0; i < cmnc_num_cellUNum; i++)
+    {
+        if(blcn_Q_reqCpEo_Delay[i] > 0)
+        {
+            blcn_flg_stop[i] = false;
+        }
+        else
+        {
+            blcn_flg_stop[i] = true;
+        }
+    }
+	   
+    //=========================================================================
+    //---------------------------------pause计算-------------------------------
+    //=========================================================================
+    for(i = 0; i < cmnc_num_cellUNum; i++)
+    {
+        blcn_flg_pause[i] = false;
+    }
+    //=========================================================================
+    //--------------------------------指令及实际均衡容量计算--------------------
+    //=========================================================================
+    for(i = 0; i < cmnc_num_cellUNum; i++)
+    {
+        if(blcn_flg_enable && !blcn_flg_pause[i] && !  blcn_flg_stop[i])
+        {
+            blcv_flg_excute[i] = true ;
+            temp[i] = temp[i] +  (real_T) (sfmv_V_cellU[i] * 0.001) /  (real_T) (blcc_R_esr * 0.1);
+        }
+        else
+        {
+            blcv_flg_excute[i] = false ;
+        }
+
+		blcn_Q_impleCp[i] = (uint16_T) (temp[i] /3600 * 1000);
+        blcv_Q_reqCpEo[i] = ((int16_T)(blcn_Q_reqCpNow[i] - blcn_Q_impleCp[i]) < 0 ? 0 :blcn_Q_reqCpNow[i] - blcn_Q_impleCp[i]);
+        blcv_Q_totalCpEo[i] = (uint32_T) (blcn_Q_totalCpEE[i] + blcn_Q_impleCp[i]);  
+    }
+    //
+    blcd_flg_firstRun = false;
+    memcpy(blcn_Q_reqCpEo_Delay,blcv_Q_reqCpEo, sizeof(blcn_Q_reqCpEE));
+
+}

+ 7 - 0
code/app/bms/BLC.h

@@ -0,0 +1,7 @@
+#include "rtwtypes.h"
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+
+extern void BLC_Init(void);
+extern void BLC(void);

+ 132 - 0
code/app/bms/CDM.c

@@ -0,0 +1,132 @@
+#include "CDM.h"
+#define cdmd_L_rls 51
+void CDM_Init(void)
+{
+    cdmd_flg_firstRun = true;
+}
+
+void CDM(void)
+{
+    real_T temp_curr;
+    real_T cmdn_V_cellUDelt;
+    static real_T cdmn_M_P[2][2][cmnc_num_cellUNumMax];
+    real_T P[2][2];
+    real_T A[2];
+    real_T K[2];
+    real_T arf;
+    real_T theta[2];
+    static real_T deltaE[cmnc_num_cellUNumMax];
+    static real_T deltaR[cmnc_num_cellUNumMax];
+    static int16_T cdmn_I_curr[cdmd_L_rls];
+    uint16_T i;
+    static uint8_T cmdn_st_workStat_Delay;
+    static uint8_T cdmn_num_Cnt;
+
+    //------模式切换后重置--------------------
+    if (cmdn_st_workStat_Delay != 1 && ihd_st_workStat == 1)
+    {
+        cdmd_flg_firstRun = true;
+    }
+
+    //初值归零---------------------------------
+    if (cdmd_flg_firstRun)
+    {
+        cdmn_num_Cnt = 0;
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            cdmn_M_P[0][0][i] = 10;
+            cdmn_M_P[0][1][i] = 0;
+            cdmn_M_P[1][0][i] = 0;
+            cdmn_M_P[1][1][i] = 10;
+            deltaE[i] = 0;
+            deltaR[i] = 0;
+            cdmv_flg_inval[i] = 1;
+        }
+    }
+    //记忆区间-----------------------------------
+    if (cdmd_flg_firstRun)
+    {
+        for (i = 0; i < cdmd_L_rls; i++)
+        {
+            cdmn_I_curr[i] = sfmd_I_curr;
+        }
+    }
+    else
+    {
+        for (i = 0; i < cdmd_L_rls - 1; i++)
+        {
+            cdmn_I_curr[i] = cdmn_I_curr[i + 1];
+        }
+        cdmn_I_curr[i] = sfmd_I_curr;
+    }
+
+    //放电使能----------------------------------------
+    if (cmdn_st_workStat_Delay == 1 && ihd_st_heatStat == 0)
+    {
+        for (i = 1; i < cmnc_num_cellUNum; i++)
+        {
+            //新增
+            cmdn_V_cellUDelt = (real_T)(sfmv_V_cellU[i] - sfmv_V_cellU[0]) * 0.001; // #0单体为基准
+            A[0] = 1;
+            A[1] = (real_T)cdmn_I_curr[cdmd_L_rls - 1] * 0.1;
+
+            theta[0] = deltaE[i];
+            theta[1] = deltaR[i];
+            K[0] = (cdmn_M_P[0][0][i] * A[0] + cdmn_M_P[0][1][i] * A[1]) / (1 + (A[0] * cdmn_M_P[0][0][i] + A[1] * cdmn_M_P[1][0][i]) * A[0] + (A[0] * cdmn_M_P[0][1][i] + A[1] * cdmn_M_P[1][1][i]) * A[1]);
+            K[1] = (cdmn_M_P[1][0][i] * A[0] + cdmn_M_P[1][1][i] * A[1]) / (1 + (A[0] * cdmn_M_P[0][0][i] + A[1] * cdmn_M_P[1][0][i]) * A[0] + (A[0] * cdmn_M_P[0][1][i] + A[1] * cdmn_M_P[1][1][i]) * A[1]);
+
+            arf = cmdn_V_cellUDelt - (theta[0] * A[0] + theta[1] * A[1]);
+            theta[0] = theta[0] + K[0] * arf;
+            theta[1] = theta[1] + K[1] * arf;
+
+            P[0][0] = cdmn_M_P[0][0][i] - K[0] * (A[0] * cdmn_M_P[0][0][i] + A[1] * cdmn_M_P[1][0][i]);
+            P[0][1] = cdmn_M_P[0][1][i] - K[0] * (A[0] * cdmn_M_P[0][1][i] + A[1] * cdmn_M_P[1][1][i]);
+            P[1][0] = cdmn_M_P[1][0][i] - K[1] * (A[0] * cdmn_M_P[0][0][i] + A[1] * cdmn_M_P[1][0][i]);
+            P[1][1] = cdmn_M_P[1][1][i] - K[1] * (A[0] * cdmn_M_P[0][1][i] + A[1] * cdmn_M_P[1][1][i]);
+
+            cdmn_M_P[0][0][i] = P[0][0];
+            cdmn_M_P[0][1][i] = P[0][1];
+            cdmn_M_P[1][0][i] = P[1][0];
+            cdmn_M_P[1][1][i] = P[1][1];
+
+            //删去
+            if (cdmn_num_Cnt > cdmd_L_rls + 1)
+            {
+                A[0] = 1;
+                A[1] = (real_T)cdmn_I_curr[0] * 0.1;
+                K[0] = (cdmn_M_P[0][0][i] * A[0] + cdmn_M_P[0][1][i] * A[1]) / (1 + (A[0] * cdmn_M_P[0][0][i] + A[1] * cdmn_M_P[1][0][i]) * A[0] + (A[0] * cdmn_M_P[0][1][i] + A[1] * cdmn_M_P[1][1][i]) * A[1]);
+                K[1] = (cdmn_M_P[1][0][i] * A[0] + cdmn_M_P[1][1][i] * A[1]) / (1 + (A[0] * cdmn_M_P[0][0][i] + A[1] * cdmn_M_P[1][0][i]) * A[0] + (A[0] * cdmn_M_P[0][1][i] + A[1] * cdmn_M_P[1][1][i]) * A[1]);
+
+                P[0][0] = cdmn_M_P[0][0][i] + K[0] * (A[0] * cdmn_M_P[0][0][i] + A[1] * cdmn_M_P[1][0][i]);
+                P[0][1] = cdmn_M_P[0][1][i] + K[0] * (A[0] * cdmn_M_P[0][1][i] + A[1] * cdmn_M_P[1][1][i]);
+                P[1][0] = cdmn_M_P[1][0][i] + K[1] * (A[0] * cdmn_M_P[0][0][i] + A[1] * cdmn_M_P[1][0][i]);
+                P[1][1] = cdmn_M_P[1][1][i] + K[1] * (A[0] * cdmn_M_P[0][1][i] + A[1] * cdmn_M_P[1][1][i]);
+
+                cdmn_M_P[0][0][i] = P[0][0];
+                cdmn_M_P[0][1][i] = P[0][1];
+                cdmn_M_P[1][0][i] = P[1][0];
+                cdmn_M_P[1][1][i] = P[1][1];
+            }
+
+            cdmv_flg_inval[i] = (arf > 0.04 || arf < -0.04);
+
+
+            deltaE[i] = theta[0];
+            deltaR[i] = theta[1];
+			
+            cdmv_V_deltOCV[i] = (int16_T)(deltaE[i] * 1000);
+            cdmv_R_deltOhm[i] = (int16_T)(deltaR[i] * 1000 * 1000);
+        }
+        //
+        cdmn_num_Cnt = cdmn_num_Cnt + 1;
+    }
+    else
+    {
+       
+        memset(cdmv_V_deltOCV, 0, sizeof(cdmv_V_deltOCV));
+        memset(cdmv_R_deltOhm, 0, sizeof(cdmv_R_deltOhm));
+    }
+
+    cdmd_flg_firstRun = false;
+    cmdn_st_workStat_Delay = ihd_st_workStat;
+}

+ 8 - 0
code/app/bms/CDM.h

@@ -0,0 +1,8 @@
+#include "rtwtypes.h"
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+
+extern void CDM_Init(void);
+extern void CDM(void);
+

+ 155 - 0
code/app/bms/CSM.c

@@ -0,0 +1,155 @@
+#include "CSM.h"
+
+
+void CSM_Init(void)
+{
+    csmd_flg_firstRun = true;
+}
+
+void CSM(void)
+{
+    static uint16_T csmn_V_cellUMax;
+    static uint16_T csmn_V_cellUMin;
+    static uint16_T chrgFulCnt;
+    static boolean_T csmn_flg_chrgFul;
+    static uint16_T chrgCnt;
+    static uint16_T noChrgCnt;
+    uint16_T csmd_I_chrgCurrReq1 = 0;
+    uint16_T csmd_I_chrgCurrReq2 = 0;
+    uint16_T csmd_I_chrgCurrReq3 = 0;
+    uint16_T csmd_I_chrgCurrReq4 = 0;
+	static boolean_T First;
+    static uint8_T csmd_st_chrgSt_end;
+	static boolean_T chrgFul;
+    if(csmd_flg_firstRun)
+    {
+        csmn_V_cellUMax = 0;
+        csmn_V_cellUMin = 0;
+        chrgFulCnt = 0;
+        chrgCnt = 0;
+        noChrgCnt = 0;
+        csmn_flg_chrgFul = false;
+		csmd_st_chrgSt = 0;
+		chrgFul = 0;
+    }
+    //=====================================================================
+    //============================充电模式=================================
+    //=====================================================================
+    if(ihd_st_chrgConnect > 0)
+    {
+        csmd_st_chrgMod = 1;
+    }
+    else
+    {
+        csmd_st_chrgMod = 0;
+    }
+	
+    //=====================================================================
+    //============================充电需求电流=============================
+    //=====================================================================
+    if (csmd_st_chrgMod)
+    {
+        if(sfmd_V_cellUMin > csmn_V_cellUMin)
+        {
+            csmn_V_cellUMin = sfmd_V_cellUMin;
+        }
+        if(sfmd_V_cellUMax > csmn_V_cellUMax)
+        {
+            csmn_V_cellUMax = sfmd_V_cellUMax;
+        }
+        csmd_I_chrgCurrReq1 = look2_u16u16tu16(csmn_V_cellUMin,sfmd_T_modTMin,cmm_V_ChrgCurr,cmm_T_ChrgCurr,cmm_I_ChrgCurr,6,3);
+        csmd_I_chrgCurrReq2 = look2_u16u16tu16(csmn_V_cellUMax,sfmd_T_modTMin,cmm_V_ChrgCurr,cmm_T_ChrgCurr,cmm_I_ChrgCurr,6,3);
+        csmd_I_chrgCurrReq3 = look2_u16u16tu16(csmn_V_cellUMin,sfmd_T_modTMax,cmm_V_ChrgCurr,cmm_T_ChrgCurr,cmm_I_ChrgCurr,6,3);
+        csmd_I_chrgCurrReq4 = look2_u16u16tu16(csmn_V_cellUMax,sfmd_T_modTMax,cmm_V_ChrgCurr,cmm_T_ChrgCurr,cmm_I_ChrgCurr,6,3);
+		csmd_I_chrgCurrReq =  min( min(csmd_I_chrgCurrReq1, csmd_I_chrgCurrReq2),min(csmd_I_chrgCurrReq3,csmd_I_chrgCurrReq4));
+    }
+    else
+    {
+        csmd_I_chrgCurrReq = 0;
+    }
+	
+    //=====================================================================
+    //============================充电状态=================================
+    //=====================================================================
+    if (csmd_st_chrgMod > 0)
+    {
+        noChrgCnt = 0; 
+        if (sfmd_I_curr > 1)
+        {
+            csmd_st_chrgSt = 1;
+        } 
+		if(JudgeTimeSystem(1,sfmd_V_cellUMax >= cmnc_V_chrgFul ,&chrgFulCnt ,20))
+		{
+		   chrgFul = true;
+           csmn_flg_chrgFul = true;
+		} 
+        if(csmn_flg_chrgFul)
+        {
+            csmd_st_chrgSt = 2;
+            csmd_I_chrgCurrReq = 0;
+        }
+
+		//
+        if (csmd_st_chrgSt != 2 && JudgeTimeSystem(1,sfmd_I_curr < 1 ,&chrgCnt ,100) )
+        {
+            csmd_st_chrgSt = 3;
+            csmd_I_chrgCurrReq = 0;
+        }
+		//
+        if((sfmd_st_fltAct >> 6) & 0x01)
+        {
+            csmd_st_chrgSt = 3;
+            csmd_I_chrgCurrReq = 0; 
+        }
+
+
+
+
+		
+		csmd_st_chrgSt_end = csmd_st_chrgSt;
+    }
+    else
+    {   
+        csmn_flg_chrgFul = false;
+        chrgCnt = 0;
+        noChrgCnt ++;
+        if(csmd_st_chrgSt_end == 1  && noChrgCnt <= 100 )
+        {
+            csmd_st_chrgSt = 3;
+        }
+        else
+        {
+            csmd_st_chrgSt = 0;
+        }
+    }
+	
+    // ===================================================================
+    // =================故障结束原因========================================
+    // ===================================================================
+    if(csmd_st_chrgSt == 3 )
+    {
+        if (ihd_st_chrgConnect == 0 && First)
+        {
+            csmd_idx_chrgEndReason = 1 ; // 用户主动停止
+        }
+        if((sfmd_st_fltAct >> 6) & 0x01 && First)
+        {
+            csmd_idx_chrgEndReason = 2 ; // 因电池故障限制充电;
+        }
+
+        First = false;
+    }
+    else
+    {
+        First = true ;
+        csmd_idx_chrgEndReason = 0;
+    }
+
+    csmd_flg_firstRun = false;
+	//printf("fltAct:%d,chrgMod:%d,chrgSt:%d,chrgCurrReq:%d,chrgEndReason:%d\n\n",sfmd_st_fltAct,cmd_st_chrgMod,cmd_st_chrgSt,cmd_I_chrgCurrReq,cmd_idx_chrgEndReason);
+}
+
+
+//==============================================================================================================================
+//==============================================================================================================================
+

+ 9 - 0
code/app/bms/CSM.h

@@ -0,0 +1,9 @@
+#include "rtwtypes.h"
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+
+extern void CSM_Init(void);
+extern void CSM(void);
+
+

+ 158 - 0
code/app/bms/ISC.c

@@ -0,0 +1,158 @@
+#include "ISC.h"
+
+void ISC_Init(void)
+{
+    iscd_flg_firstRun = true;
+}
+//-------------------------------------------------------------------------
+
+void ISC(void)
+{
+    uint16_T i;
+    static uint32_T iscd_tm_totalEE;
+    static uint16_T iscv_Q_remainCpEE[cmnc_num_cellUNumMax];
+    uint16_T iscn_pct_cellSoc1[cmnc_num_cellUNumMax];
+    uint16_T iscn_pct_cellSoc2[cmnc_num_cellUNumMax];
+    int16_T iscn_Q_deltAh[cmnc_num_cellUNumMax];
+    uint16_T iscn_Q_cellAh[cmnc_num_cellUNumMax];
+    static uint16_T iscn_Q_cellAh0[cmnc_num_cellUNumMax];
+    static boolean_T iscd_flg_timedWakeUpFlt;
+    static boolean_T iscd_flg_disChrgFlt;
+    static uint16_T TimeCtn;
+    static uint16_T RunCtn;
+    static uint16_T iscn_num_fltNr[cmnc_num_cellUNumMax];
+    static boolean_T iscd_flg_fulStat;
+    //初值
+    if (iscd_flg_firstRun)
+    {
+        iscd_flg_timedWakeUpFlt = false;
+        iscd_flg_disChrgFlt = false;
+        memset(iscn_Q_cellAh0, 0, sizeof(iscn_Q_cellAh0));
+        memset(iscn_pct_cellSoc1, 0, sizeof(iscn_pct_cellSoc1));
+        memset(iscn_pct_cellSoc2, 0, sizeof(iscn_pct_cellSoc2));
+        memset(iscn_Q_cellAh, 0, sizeof(iscn_Q_cellAh));
+        memset(iscn_Q_deltAh, 0, sizeof(iscn_Q_deltAh));
+        memset(iscn_num_fltNr, 0, sizeof(iscn_num_fltNr));
+        TimeCtn = 0;
+        RunCtn = 0;
+    }
+    //=====================================================================
+    //================高端SOC点诊断=================================== 0.1A
+    //=====================================================================
+    RunCtn = (RunCtn + 1) > 60000 ? 60000 : (RunCtn + 1);
+    if (iscd_flg_firstRun)
+    {
+        //
+        if (ArrMax(iscv_Q_remainCpEi, cmnc_num_cellUNum) > cmnc_Q_ratedCp)
+        {
+            memset(iscv_Q_remainCpEE, 0, sizeof(iscv_Q_remainCpEi));
+            iscd_tm_totalEE = 0;
+        }
+        else
+        {
+            memcpy(iscv_Q_remainCpEE, iscv_Q_remainCpEi, sizeof(iscv_Q_remainCpEi));
+            iscd_tm_totalEE = iscd_tm_totalEi;
+        }
+        //
+        if ((iscd_tm_totalEE + ihd_tm_parkTime >= 20 * 3600 || iscd_tm_totalEE == 0) && ihd_tm_parkTime >= cmnc_tm_parkTime && socd_pct_battSoc > 900 && sfmd_I_curr > -10 && sfmd_I_curr < 10)
+        {
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                iscn_pct_cellSoc1[i] = look1_u16tu16(sfmv_V_cellU[i], cmnm_V_ocv, cmnm_pct_soc, 13);
+                iscn_Q_cellAh[i] = (uint16_T)((uint16_T)((uint32_T)iscn_pct_cellSoc1[i] * sohv_Q_cellCap[i] / 2000U) << 1);
+                iscn_Q_deltAh[i] = (int16_T)(iscn_Q_cellAh[i] - iscv_Q_remainCpEE[i]);
+            }
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                if ((real_T)(ArrMean(iscn_Q_deltAh, cmnc_num_cellUNum) - iscn_Q_deltAh[i]) * 0.1 / (iscd_tm_totalEE + ihd_tm_parkTime) * 3600 > 0.1)
+                {
+                    iscd_flg_fulStat = true && iscd_tm_totalEE != 0;
+                }
+            }
+            memcpy(iscv_Q_remainCpEo, iscn_Q_cellAh, sizeof(iscn_Q_cellAh));
+            iscd_tm_totalEE = 0;
+        }
+        else
+        {
+            memcpy(iscv_Q_remainCpEo, iscv_Q_remainCpEi, sizeof(iscv_Q_remainCpEi));
+            iscd_tm_totalEE = iscd_tm_totalEE + ihd_tm_parkTime;
+        }
+    }
+    if (iscv_Q_remainCpEo[0] != 0)
+    {
+        iscd_tm_totalEo = iscd_tm_totalEE + RunCtn;
+    }
+
+    //=====================================================================
+    //================定时唤醒诊断======================================1A
+    //=====================================================================
+    if (appd_st_preCyc == 1 && ihd_tm_parkTime >= cmnc_tm_parkTime && sfmd_I_curr < 10 && sfmd_I_curr > -10 && iscd_flg_firstRun)
+    {
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            iscn_pct_cellSoc1[i] = look1_u16tu16(appv_V_cellU[i], cmnm_V_ocv, cmnm_pct_soc, 13);
+            iscn_pct_cellSoc2[i] = look1_u16tu16(sfmv_V_cellU[i], cmnm_V_ocv, cmnm_pct_soc, 13);
+            iscn_Q_deltAh[i] = (int16_T)((uint16_T)((uint32_T)iscn_pct_cellSoc2[i] * sohv_Q_cellCap[i] / 2000U) << 1) - (int16_T)((uint16_T)((uint32_T)iscn_pct_cellSoc1[i] * sohv_Q_cellCap[i] / 2000U) << 1);
+        }
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            if (ArrMean(iscn_Q_deltAh, cmnc_num_cellUNum) - iscn_Q_deltAh[i] > 10)
+            {
+                iscd_flg_timedWakeUpFlt = false;
+            }
+        }
+    }
+
+    //=====================================================================
+    //================放电过程中诊断=================================== 2A
+    //=====================================================================
+    if (!pimd_flg_inval)
+    {
+        TimeCtn = TimeCtn + 1;
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            iscn_Q_cellAh[i] = (uint16_T)((uint32_T)(pimv_pct_cellSoc[i] * sohv_Q_cellCap[i]) / 1000);
+        }
+        if (TimeCtn == 60)
+        {
+            memcpy(iscn_Q_cellAh0, iscn_Q_cellAh, sizeof(iscn_Q_cellAh));
+        }
+        if (TimeCtn > 60 + 360)
+        {
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                iscn_Q_deltAh[i] = (int16_T)(iscn_Q_cellAh[i] - iscn_Q_cellAh0[i]);
+            }
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                if ((real_T)(ArrMean(iscn_Q_deltAh, cmnc_num_cellUNum) - iscn_Q_deltAh[i]) * 0.1 / (TimeCtn - 60) * 3600 > 2)
+                {
+                    iscn_num_fltNr[i] = (iscn_num_fltNr[i] + 1) > 60000 ? 60000 : (iscn_num_fltNr[i] + 1);
+                }
+                else
+                {
+                    iscn_num_fltNr[i] = 0;
+                }
+                if (iscn_num_fltNr[i] > 600)
+                {
+                    iscd_flg_disChrgFlt = true;
+                }
+            }
+        }
+        if (TimeCtn > 3600)
+        {
+            TimeCtn = 60;
+        }
+    }
+    else
+    {
+        TimeCtn = 0;
+    }
+
+    /////
+    iscd_flg_flt[0] = iscd_flg_disChrgFlt;
+    iscd_flg_flt[1] = iscd_flg_timedWakeUpFlt;
+    iscd_flg_flt[2] = iscd_flg_fulStat;
+
+    iscd_flg_firstRun = false;
+}

+ 8 - 0
code/app/bms/ISC.h

@@ -0,0 +1,8 @@
+#include <math.h>
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+
+extern void ISC_Init(void);
+extern void ISC(void);
+

+ 253 - 0
code/app/bms/PIM.c

@@ -0,0 +1,253 @@
+#include "PIM.h"
+
+#define pimd_L_rls 51
+
+void PIM_Init(void)
+{
+    pimd_flg_firstRun = true;
+}
+
+void PIM(void)
+{
+    static uint8_T pimn_st_workStat_Delay;
+    uint16_T i;
+    uint16_T j;
+    static uint16_T pimn_V_volt[pimd_L_rls];
+    static int16_T  pimn_I_curr[pimd_L_rls];
+    static real_T  pimn_V_ocv;
+    static real_T  pimn_R_ohm;
+    static real_T  pimn_R_polar;
+    static real_T  pimn_F_polar;
+    
+    static uint16_T pimn_num_cnt;
+    static real_T pimn_M_P[4][4];
+    real_T theta[4];
+    real_T P[4][4];
+    real_T A[4];
+    real_T K[4];
+    real_T temp;
+    uint16_T socMax;
+    uint16_T socMin;
+    boolean_T pimn_flg_inval;
+    uint16_T factor;
+    //重置--------------------
+    if (pimn_st_workStat_Delay != 1 && ihd_st_workStat == 1)
+    {
+        pimd_flg_firstRun = true;
+    }
+    
+    
+    //限定记忆长度------------------------
+    if (pimd_flg_firstRun)
+    {
+        for (i = 0; i < pimd_L_rls; i++)
+        {
+            pimn_V_volt[i] = sfmv_V_cellU[0];   //和CMD匹配
+            pimn_I_curr[i] = sfmd_I_curr;
+        }
+    }
+    else
+    {
+        for (i = 0; i < pimd_L_rls - 1; i++)
+        {
+            pimn_V_volt[i]  = pimn_V_volt[i+1];
+            pimn_I_curr[i] = pimn_I_curr[i+1];
+        }
+        pimn_V_volt[i] = sfmv_V_cellU[0];
+        pimn_I_curr[i] = sfmd_I_curr;
+    }
+    
+    //初值-------------------
+    if (pimd_flg_firstRun)
+    {
+        pimn_M_P[0][0] = 10; pimn_M_P[0][1] =  0;  pimn_M_P[0][2] =  0;  pimn_M_P[0][3] =  0;
+        pimn_M_P[1][0] =  0; pimn_M_P[1][1] = 10;  pimn_M_P[1][2] =  0;  pimn_M_P[1][3] =  0;
+        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 = 0.001;;
+        pimn_F_polar = 5;
+        pimn_num_cnt = 0;
+        pimn_st_workStat_Delay = 0;
+    }
+    //放电使能
+    if(pimn_st_workStat_Delay == 1 && ihd_st_heatStat == 0)
+    {
+        pimn_num_cnt = pimn_num_cnt + 1;
+        //新增-------------------
+        A[0] = (real_T)pimn_V_volt[pimd_L_rls - 2] * 0.001;
+        A[1] = (real_T)pimn_I_curr[pimd_L_rls - 1] * 0.1;
+        A[2] =-(real_T)pimn_I_curr[pimd_L_rls - 2] * 0.1;
+        A[3] = 1;
+        //参数形变
+        
+        theta[0] = exp(-1/pimn_F_polar);
+        theta[1] = pimn_R_ohm;
+        theta[2] = pimn_R_ohm * exp(-1/pimn_F_polar) -pimn_R_polar * (1-exp(-1/pimn_F_polar));
+        theta[3] = (1 -theta[0]) * pimn_V_ocv;
+        
+        //增益矩阵
+        temp =  (A[0] * pimn_M_P[0][0] +A[1] * pimn_M_P[1][0] + A[2] * pimn_M_P[2][0] + A[3] * pimn_M_P[3][0]) * A[0] +
+                (A[0] * pimn_M_P[0][1] +A[1] * pimn_M_P[1][1] + A[2] * pimn_M_P[2][1] + A[3] * pimn_M_P[3][1]) * A[1] +
+                (A[0] * pimn_M_P[0][2] +A[1] * pimn_M_P[1][2] + A[2] * pimn_M_P[2][2] + A[3] * pimn_M_P[3][2]) * A[2] +
+                (A[0] * pimn_M_P[0][3] +A[1] * pimn_M_P[1][3] + A[2] * pimn_M_P[2][3] + A[3] * pimn_M_P[3][3]) * A[3];
+        for(i = 0;i < 4;i++)
+        {
+            K[i] = (pimn_M_P[i][0] * A[0] + pimn_M_P[i][1] * A[1] + pimn_M_P[i][2] * A[2] + pimn_M_P[i][3] * A[3])/(1 + temp);
+        }
+        //参数更新
+        
+        temp = (real_T)pimn_V_volt[pimd_L_rls - 1] * 0.001 - (theta[0] * A[0] + theta[1] * A[1] + theta[2] * A[2] + theta[3] * A[3]);
+		pimn_flg_inval = (temp > 0.03 || temp < -0.03);
+        for(i = 0;i < 4;i++)
+        {
+            theta[i] = theta[i] + K[i] * temp;
+        }
+        //协方差更新
+        for(i = 0;i < 4;i++)
+        {
+            for(j = 0;j < 4;j++)
+            {
+                P[i][j] = pimn_M_P[i][j] - K[i] * (A[0] * pimn_M_P[0][j] + A[1] * pimn_M_P[1][j] + A[2] * pimn_M_P[2][j] + A[3] * pimn_M_P[3][j]);
+            }
+            
+        }
+        
+        //传递下循环
+        for(i = 0;i < 4;i++)
+        {
+            for(j = 0;j < 4;j++)
+            {
+                pimn_M_P[i][j] = P[i][j];
+            }
+        }
+        
+        //删去---------------
+        if(pimn_num_cnt > pimd_L_rls + 1)
+        {
+            //输入
+            A[0] = (real_T)pimn_V_volt[0] * 0.001;
+            A[1] = (real_T)pimn_I_curr[1] * 0.1;
+            A[2] =-(real_T)pimn_I_curr[0] * 0.1;
+            A[3] = 1;
+            
+            //增益矩阵
+            temp =  (A[0] * pimn_M_P[0][0] +A[1] * pimn_M_P[1][0] + A[2] * pimn_M_P[2][0] + A[3] * pimn_M_P[3][0]) * A[0] +
+                    (A[0] * pimn_M_P[0][1] +A[1] * pimn_M_P[1][1] + A[2] * pimn_M_P[2][1] + A[3] * pimn_M_P[3][1]) * A[1] +
+                    (A[0] * pimn_M_P[0][2] +A[1] * pimn_M_P[1][2] + A[2] * pimn_M_P[2][2] + A[3] * pimn_M_P[3][2]) * A[2] +
+                    (A[0] * pimn_M_P[0][3] +A[1] * pimn_M_P[1][3] + A[2] * pimn_M_P[2][3] + A[3] * pimn_M_P[3][3]) * A[3];
+            for(i = 0;i <4;i++)
+            {
+                K[i] = (pimn_M_P[i][0] * A[0] + pimn_M_P[i][1] * A[1] + pimn_M_P[i][2] * A[2] + pimn_M_P[i][3] * A[3])/(1 + temp);
+            }
+            
+            //协方差更新
+            for(i = 0;i < 4;i++)
+            {
+                for(j = 0;j < 4;j++)
+                {
+                    P[i][j] = pimn_M_P[i][j] + K[i] * (A[0] * pimn_M_P[0][j] + A[1] * pimn_M_P[1][j] + A[2] * pimn_M_P[2][j] + A[3] * pimn_M_P[3][j]);
+                }
+            }
+            //传递下一循环
+            for(i = 0;i < 4;i++)
+            {
+                for(j = 0;j < 4;j++)
+                {
+                    pimn_M_P[i][j] = P[i][j];
+                }
+            }
+        }
+        //参数求解
+        pimn_V_ocv   = theta[3]/(1 - theta[0]);
+        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);
+        pimd_F_polar = (uint16_T)(pimn_F_polar * 1000);
+        if(pimd_V_ocv > 4400 || pimd_V_ocv < 1000 || pimd_R_ohm < 1000 || pimd_R_ohm > 10000)
+        {
+            pimn_flg_inval = 1;
+        }
+    }
+    else
+    {
+        pimd_V_ocv   = 0;
+        pimd_R_ohm   = 0;
+        pimd_R_polar = 0;
+        pimd_F_polar = 0;
+        pimn_flg_inval = 1;
+    }
+    
+    //全部单体参数---------------------
+    for(i = 0;i < cmnc_num_cellUNum;i++)
+    {
+        pimv_V_cellOcv[i]   = pimd_V_ocv + cdmv_V_deltOCV[i];
+        pimv_R_cellOhm[i]   = pimd_R_ohm + cdmv_R_deltOhm[i];
+        pimv_pct_cellSoc[i] = look1_u16tu16(pimv_V_cellOcv[i], cmnm_V_ocv, cmnm_pct_soc, 13);
+        if((!pimn_flg_inval && !cdmv_flg_inval[i]))
+        {
+            pimv_flg_inval[i] = (pimv_V_cellOcv[i] > 4400 || pimv_V_cellOcv[i] < 1000 || pimv_R_cellOhm[i] < 1000 || pimv_R_cellOhm[i] > 10000);
+        }
+        else
+        {
+            pimv_flg_inval[i] = 1;
+        }
+    }
+    pimd_flg_inval = 0;
+    for(i = 0;i < cmnc_num_cellUNum;i++)
+    {
+        if(pimv_flg_inval[i] == 1)
+        {
+            pimd_flg_inval = 1;
+            break;
+        }
+    }
+    // 整包SOC
+    socMin = 1000;
+    socMax = 0;
+    for(i = 0;i < cmnc_num_cellUNum;i++)
+    {
+        if(!pimv_flg_inval[i] && pimv_pct_cellSoc[i] > socMax)
+        {
+            socMax = pimv_pct_cellSoc[i];
+        }
+        if(!pimv_flg_inval[i] && pimv_pct_cellSoc[i] < socMin)
+        {
+            socMin = pimv_pct_cellSoc[i];
+        }
+    }
+    
+    if (socMax > 800)
+    {
+        factor = 100;
+    }
+    else if (socMin < 200)
+    {
+        factor = 0;
+    }
+    else
+    {
+        factor = (uint16_T)(((uint16_T)(((uint32_T)(socMin - 200) << 6) / (800 - (socMax - socMin) - 200)) * 25U) >> 4);
+    }
+    pimd_pct_battSoc = (uint16_T)(((1 - (real_T)(factor * 0.01)) * (real_T)(socMin * 0.1) + (real_T)(factor * 0.01) * (real_T)(socMax * 0.1)) * 10);
+    
+    
+    //
+    pimn_st_workStat_Delay = ihd_st_workStat;
+    pimd_flg_firstRun = false;
+}
+
+
+

+ 9 - 0
code/app/bms/PIM.h

@@ -0,0 +1,9 @@
+#include "rtwtypes.h"
+#include <math.h>
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+
+extern void PIM_Init(void);
+extern void PIM(void);
+

+ 1764 - 0
code/app/bms/SFM.c

@@ -0,0 +1,1764 @@
+#include "SFM.h"
+#define FltArrLen 200
+#define FltDispArrLen 20
+
+DiagThrstruct DiagThr;
+DiagTimestruct DiagTime;
+
+void SFM_Init(void)
+{
+    sfmd_flg_firstRun = true;
+}
+
+void SFM(void)
+{
+    static uint8_T sfmn_num_Cnt;
+    boolean_T sfmn_flg_interComFlt;
+    boolean_T sfmn_flg_authFlt;
+    boolean_T sfmn_flg_HVILFlt;
+    boolean_T sfmn_flg_chrgMosClosFlt;
+    boolean_T sfmn_flg_disChrgMosClosFlt;
+
+    static uint16_T Time0Cnt;
+    static uint16_T modTMaxArr[10];
+    static uint16_T SumT0;
+    static uint16_T Time1Cnt;
+    static uint16_T heatT1Arr[10];
+    static uint16_T SumT1;
+    static uint16_T Time2Cnt;
+    static uint16_T heatT2Arr[10];
+    static uint16_T SumT2;
+
+    static uint16_T CellUArry[4][cmnc_num_cellUNumMax];
+    static uint8_T ErrNr[cmnc_num_cellUNumMax];
+    static uint8_T RecNr[cmnc_num_cellUNumMax];
+    static boolean_T sfmv_flg_cellUOpenFlt[cmnc_num_cellUNumMax];
+    static boolean_T ErrUFlg[cmnc_num_cellUNumMax];
+    uint32_T SumU;
+    uint16_T UNum;
+    boolean_T sfmd_flg_volFlt;
+    boolean_T Enable1;
+    boolean_T Enable2;
+
+    static uint8_T modTOpenNr[cmnc_num_modTNumMax];
+    boolean_T sfmd_flg_modTOpenFlt;
+    boolean_T sfmv_flg_modTOpenFlt[cmnc_num_modTNumMax];
+    boolean_T sfmd_flg_chrgMosTOpenFlt;
+    boolean_T sfmd_flg_DCPlugTOpenFlt;
+    boolean_T sfmd_flg_ACPlugTOpenFlt;
+    boolean_T sfmd_flg_heatPanT1OpenFlt;
+    boolean_T sfmd_flg_heatPanT2OpenFlt;
+
+    static uint16_T modTArr[cmnc_num_modTNumMax];
+    uint16_T Tnum;
+    uint32_T SumT;
+
+    static uint8_T modTRatNr[cmnc_num_modTNumMax];
+    boolean_T sfmd_flg_modTRatFlt;
+    boolean_T sfmv_flg_modTRatFlt[cmnc_num_modTNumMax];
+    boolean_T sfmd_flg_chrgMosTRatFlt;
+    boolean_T sfmd_flg_DCPlugTRatFlt;
+    boolean_T sfmd_flg_ACPlugTRatFlt;
+    boolean_T sfmd_flg_heatPanT1RatFlt;
+    boolean_T sfmd_flg_heatPanT2RatFlt;
+    boolean_T sfmn_flg_chrgMosTRatFltOnce;
+    boolean_T sfmn_flg_DCPlugTRatFltOnce;
+    boolean_T sfmn_flg_ACPlugTRatFltOnce;
+    boolean_T sfmn_flg_heatPanT1RatFltOnce;
+    boolean_T sfmn_flg_heatPanT2RatFltOnce;
+    static uint16_T sfmn_T_mosT_Delay;
+    static uint16_T sfmn_T_DCPlugT_Delay;
+    static uint16_T sfmn_T_ACPlugT_Delay;
+    static uint16_T sfmn_T_heatPanT1_Delay;
+    static uint16_T sfmn_T_heatPanT2_Delay;
+    static uint16_T sfmn_T_heatPanT1_Delay1;
+    static uint16_T sfmn_T_heatPanT2_Delay1;
+    boolean_T sfmd_flg_modTAllFlt;
+    boolean_T sfmd_flg_heatPanTAllFlt;
+    boolean_T sfmd_flg_currOpenFlt;
+    uint16_T sfmn_I_currAbs;
+    static boolean_T sfmd_flg_cellUOverFlt2;
+    static boolean_T sfmd_flg_cellUOverFlt1;
+    static boolean_T sfmd_flg_cellULowFlt2;
+    static boolean_T sfmd_flg_cellULowFlt1;
+    static boolean_T sfmd_flg_cellUDiffFlt2;
+    static boolean_T sfmd_flg_cellUDiffFlt1;
+    static boolean_T sfmd_flg_battUOverFlt2;
+    static boolean_T sfmd_flg_battUOverFlt1;
+    static boolean_T sfmd_flg_battULowFlt2;
+    static boolean_T sfmd_flg_battULowFlt1;
+
+    boolean_T chrgFlg;
+    boolean_T disChrgFlg;
+    static boolean_T sfmd_flg_chrgModTOverFlt2;
+    static boolean_T sfmd_flg_chrgModTOverFlt1;
+    static boolean_T sfmd_flg_chrgModTLowFlt2;
+    static boolean_T sfmd_flg_chrgModTLowFlt1;
+    static boolean_T sfmd_flg_disChrgModTOverFlt2;
+    static boolean_T sfmd_flg_disChrgModTOverFlt1;
+    static boolean_T sfmd_flg_disChrgModTLowFlt2;
+    static boolean_T sfmd_flg_disChrgModTLowFlt1;
+    static boolean_T sfmd_flg_modTDiffFlt2;
+    static boolean_T sfmd_flg_modTDiffFlt1;
+    static boolean_T sfmd_flg_chrgMosTOverFlt2;
+    static boolean_T sfmd_flg_chrgMosTOverFlt1;
+    static boolean_T sfmd_flg_disChrgMosTOverFlt2;
+    static boolean_T sfmd_flg_disChrgMosTOverFlt1;
+    static boolean_T sfmd_flg_DCPlugTOverFlt2;
+    static boolean_T sfmd_flg_DCPlugTOverFlt1;
+    static boolean_T sfmd_flg_ACPlugTOverFlt2;
+    static boolean_T sfmd_flg_ACPlugTOverFlt1;
+    static boolean_T sfmd_flg_heatPanTOverFlt2_1;
+    static boolean_T sfmd_flg_heatPanTOverFlt2_2;
+    boolean_T sfmd_flg_heatPanTOverFlt2;
+    static boolean_T sfmd_flg_heatPanTOverFlt1_1;
+    static boolean_T sfmd_flg_heatPanTOverFlt1_2;
+    boolean_T sfmd_flg_heatPanTOverFlt1;
+    static boolean_T sfmd_flg_chrgCurrOverFlt;
+    static boolean_T sfmd_flg_disChrgCurrOverFlt;
+
+    boolean_T sfmd_flg_chrgCurrOverMisFlt;
+    boolean_T sfmd_flg_disChrgCurrOverMisFlt;
+    boolean_T sfmd_flg_battULowMisFlt;
+    boolean_T sfmd_flg_battUOverMisFlt;
+    boolean_T sfmd_flg_cellULowMisFlt;
+    boolean_T sfmd_flg_cellUOverMisFlt;
+    boolean_T sfmd_flg_chrgModTOverMisFlt;
+    boolean_T sfmd_flg_chrgModTLowMisFlt;
+    boolean_T sfmd_flg_disChrgModTOverMisFlt;
+    boolean_T sfmd_flg_disChrgModTLowMisFlt;
+    boolean_T sfmd_flg_chrgMosTOverMisFlt;
+    boolean_T sfmd_flg_disChrgMosTOverMisFlt;
+    boolean_T sfmd_flg_socMisFlt;
+    boolean_T sfmd_flg_sohMisFlt;
+    boolean_T sfmd_flg_socJumpFlt;
+    boolean_T sfmd_flg_EEsaveFlt;
+    static uint16_T sfmn_pct_bcuSoc_Delay;
+
+    static uint16_T noDisChrgCnt;
+    static int16_T sfmd_I_curr_Delay;
+    static boolean_T sfmn_flg_Udrop;
+    static boolean_T sfmd_flg_heatclear;
+    static boolean_T sfmn_flg_volFlt_keep;
+    static uint16_T CntA;
+    static uint16_T ModTStor[4][cmnc_num_modTNumMax];
+    static boolean_T sfmn_flg_Tup;
+    static boolean_T sfmn_flg_modTOpenFlt_keep;
+    static uint16_T CntB;
+    static boolean_T sfmn_flg_urtRecFlt_Delay = false;
+
+    int32_T SumR;
+    int32_T SumRR;
+    boolean_T sfmd_flg_deltRFlt;
+    static uint8_T deltRFltNr[cmnc_num_cellUNumMax];
+
+    boolean_T FltFlg[FltArrLen];
+    uint16_T FltLevel[FltArrLen];
+    uint8_T FltAct[FltArrLen];
+    uint16_T FltCodeArr[FltDispArrLen];
+    uint16_T FltLevelArr[FltDispArrLen];
+    uint8_T FltActArr[FltDispArrLen];
+    uint16_T i;
+    uint16_T j;
+    uint16_T k;
+
+    if (sfmn_flg_urtRecFlt_Delay)
+    {
+        sfmd_flg_firstRun = true;
+    }
+    sfmn_flg_urtRecFlt_Delay = ihd_flg_urtRecFlt;
+    //初值
+    if (sfmd_flg_firstRun)
+    {
+        sfmn_num_Cnt = 10;
+        memset(&DiagThr, 0, sizeof(DiagThr));
+        memset(&DiagTime, 0, sizeof(DiagTime));
+        memset(heatT1Arr, 0, sizeof(heatT1Arr));
+        memset(heatT2Arr, 0, sizeof(heatT2Arr));
+        memset(ErrNr, 0, sizeof(ErrNr));
+        memset(sfmv_flg_cellUOpenFlt, 0, sizeof(sfmv_flg_cellUOpenFlt));
+        memset(ErrUFlg, 0, sizeof(ErrUFlg));
+        memset(RecNr, 0, sizeof(RecNr));
+        memset(modTOpenNr, 0, sizeof(modTOpenNr));
+        memset(modTRatNr, 0, sizeof(modTRatNr));
+        memset(deltRFltNr, 0, sizeof(deltRFltNr));
+        sfmd_flg_cellUOverFlt2 = false;
+        sfmd_flg_cellUOverFlt1 = false;
+        sfmd_flg_cellULowFlt2 = false;
+        sfmd_flg_cellULowFlt1 = false;
+        sfmd_flg_cellUDiffFlt2 = false;
+        sfmd_flg_cellUDiffFlt1 = false;
+        sfmd_flg_battUOverFlt2 = false;
+        sfmd_flg_battUOverFlt1 = false;
+        sfmd_flg_battULowFlt2 = false;
+        sfmd_flg_battULowFlt1 = false;
+        sfmd_flg_chrgModTOverFlt2 = false;
+        sfmd_flg_chrgModTOverFlt1 = false;
+        sfmd_flg_chrgModTLowFlt2 = false;
+        sfmd_flg_chrgModTLowFlt1 = false;
+        sfmd_flg_disChrgModTOverFlt2 = false;
+        sfmd_flg_disChrgModTOverFlt1 = false;
+        sfmd_flg_disChrgModTLowFlt2 = false;
+        sfmd_flg_disChrgModTLowFlt1 = false;
+        sfmd_flg_modTDiffFlt2 = false;
+        sfmd_flg_modTDiffFlt1 = false;
+        sfmd_flg_chrgMosTOverFlt2 = false;
+        sfmd_flg_chrgMosTOverFlt1 = false;
+        sfmd_flg_disChrgMosTOverFlt2 = false;
+        sfmd_flg_disChrgMosTOverFlt1 = false;
+        sfmd_flg_DCPlugTOverFlt2 = false;
+        sfmd_flg_DCPlugTOverFlt1 = false;
+        sfmd_flg_ACPlugTOverFlt2 = false;
+        sfmd_flg_ACPlugTOverFlt1 = false;
+        sfmd_flg_heatPanTOverFlt2_1 = false;
+        sfmd_flg_heatPanTOverFlt2_2 = false;
+        sfmd_flg_heatPanTOverFlt1_1 = false;
+        sfmd_flg_heatPanTOverFlt1_2 = false;
+        sfmd_flg_chrgCurrOverFlt = false;
+        sfmd_flg_disChrgCurrOverFlt = false;
+
+        noDisChrgCnt = 0;
+        sfmd_I_curr_Delay = ihd_I_curr;
+        sfmn_flg_Udrop = false;
+        sfmd_flg_heatclear = false;
+        sfmn_flg_volFlt_keep = false;
+        CntA = 10;
+        sfmn_flg_Tup = false;
+        sfmn_flg_modTOpenFlt_keep = false;
+        CntB = 0;
+
+        sfmn_T_mosT_Delay = ihd_T_mosT;
+        sfmn_T_DCPlugT_Delay = ihd_T_DCPlugT;
+        sfmn_T_ACPlugT_Delay = ihd_T_ACPlugT;
+        sfmn_T_heatPanT1_Delay = ihd_T_heatPanT1;
+        sfmn_T_heatPanT2_Delay = ihd_T_heatPanT2;
+        sfmn_T_heatPanT1_Delay1 = ihd_T_heatPanT1;
+        sfmn_T_heatPanT2_Delay1 = ihd_T_heatPanT2;
+        sfmn_pct_bcuSoc_Delay = socd_pct_bcuSoc;
+    }
+
+    // 故障清楚指令
+    if (ihd_flg_DTCClear)
+    {
+        sfmd_flg_mainCirClosFltEi = false;
+        sfmd_flg_mainCirClosFltEo = false;
+        sfmd_flg_heatCirOpenFltEi = false;
+        sfmd_flg_heatCirOpenFltEo = false;
+        sfmd_flg_heatCirClosFltEi = false;
+        sfmd_flg_heatCirClosFltEo = false;
+        sfmd_flg_heatRunFltEi = false;
+        sfmd_flg_heatRunFltEo = false;
+        sfmd_flg_iscFltEi = false;
+        sfmd_flg_iscFltEo = false;
+    }
+
+    //=======================================================================================
+    //====================================故障诊断    =======================================
+    //=======================================================================================
+    //=======================================================================================
+    // 1 内网通信故障
+    if (ihd_flg_urtRecFlt)
+    {
+        sfmn_flg_interComFlt = true;
+    }
+    else
+    {
+        sfmn_flg_interComFlt = false;
+    }
+
+    // 5 认证失败故障
+    sfmn_flg_authFlt = (ihd_st_authFaild == 1) && (!sfmn_flg_interComFlt);
+
+    // 11 高压互锁故障
+    if (ihd_flg_HVILFlt)
+    {
+        sfmn_flg_HVILFlt = true;
+    }
+    else
+    {
+        sfmn_flg_HVILFlt = false;
+    }
+    // 16
+    sfmd_flg_iscFltEo = iscd_flg_flt[0] || iscd_flg_flt[1] || iscd_flg_flt[2] || sfmd_flg_iscFltEi || sfmd_flg_iscFltEo;
+
+    // 22 充电Mos失效故障
+    sfmn_flg_chrgMosClosFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, ihd_flg_chrgMosClosFlt, &DiagTime.N22, 2);
+
+    // 24 放电Mos失效故障
+    sfmn_flg_disChrgMosClosFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, ihd_flg_disChrgMosClosFlt, &DiagTime.N24, 2);
+
+    // 34 主回路常闭故障   //(充电MOS及放电MOS,主继电器断开  使能)
+    sfmd_flg_mainCirClosFltEo = JudgeTimeSystem(!ihd_st_chrgMosControl && !ihd_st_disChrgMosControl && !ihd_st_relayControl, sfmd_I_curr > 5 || sfmd_I_curr < -5, &DiagTime.N34, 5) || sfmd_flg_mainCirClosFltEo || sfmd_flg_mainCirClosFltEi;
+
+    // 52 电压开路故障
+    sfmn_num_Cnt = sfmn_num_Cnt + 1;
+    if (!sfmn_flg_interComFlt && sfmn_num_Cnt >= 0)
+    {
+        sfmn_num_Cnt = 0;
+        // 矩阵更新
+        for (j = 0; j < 4 && sfmd_flg_firstRun; j++)
+        {
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                CellUArry[j][i] = ihv_V_cellU[i];
+            }
+        }
+        for (j = 0; j < 3; j++)
+        {
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                CellUArry[j][i] = CellUArry[j + 1][i];
+            }
+        }
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            CellUArry[j][i] = ihv_V_cellU[i];
+        }
+        // 故障判断
+        for (i = 0; i < cmnc_num_cellUNum - 1; i++)
+        {
+            if ((int16_T)(CellUArry[3][i] - CellUArry[1][i]) < -50 && (int16_T)(CellUArry[3][i + 1] - CellUArry[1][i + 1]) > 50)
+            {
+                ErrNr[i] = ErrNr[i] + 1;
+            }
+            else
+            {
+                ErrNr[i] = 0;
+            }
+            if (ErrNr[i] >= 2 || ((int16_T)(CellUArry[3][i] - CellUArry[2][i]) < -1000 && (int16_T)(CellUArry[3][i + 1] - CellUArry[2][i + 1]) > 1000))
+            {
+                sfmv_flg_cellUOpenFlt[i] = true;
+                ErrUFlg[i] = true;
+                ErrUFlg[i + 1] = true;
+            }
+            if (sfmv_flg_cellUOpenFlt[i])
+            {
+                for (k = 0; k < i; k++)
+                {
+                    if ((int16_T)(CellUArry[3][i - k] - CellUArry[2][i - k]) < -200)
+                    {
+                        sfmv_flg_cellUOpenFlt[i - k] = true;
+                        ErrUFlg[i - k] = true;
+                    }
+                }
+            }
+        }
+    }
+    //
+    if (!sfmn_flg_interComFlt)
+    {
+        sfmd_V_cellUMax = 0;
+        sfmd_V_cellUMin = 10000;
+        SumU = 0;
+        UNum = 0;
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            if (!ErrUFlg[i])
+            {
+                SumU = SumU + ihv_V_cellU[i];
+                UNum = UNum + 1;
+                if (sfmd_V_cellUMax < ihv_V_cellU[i])
+                {
+                    sfmd_V_cellUMax = ihv_V_cellU[i];
+                    sfmd_idx_cellUMax = i;
+                }
+                if (sfmd_V_cellUMin > ihv_V_cellU[i])
+                {
+                    sfmd_V_cellUMin = ihv_V_cellU[i];
+                    sfmd_idx_cellUMin = i;
+                }
+            }
+        }
+        if (sfmd_V_cellUMax - sfmd_V_cellUMin > 5000) // 2021 10.24
+        {
+            sfmd_V_cellUAvrg = (SumU - sfmd_V_cellUMax - sfmd_V_cellUMin) / (UNum - 2);
+            for (i = 0; i < cmnc_num_cellUNum; i++)
+            {
+                if (!ErrUFlg[i] && (int16_T)(ihv_V_cellU[i] - sfmd_V_cellUAvrg) > 1500)
+                {
+                    ErrUFlg[i] = true;
+                }
+                if (!ErrUFlg[i] && (int16_T)(ihv_V_cellU[i] - sfmd_V_cellUAvrg) < -1500)
+                {
+                    ErrUFlg[i] = true;
+                    sfmv_flg_cellUOpenFlt[i] = true;
+                }
+            }
+        }
+        else
+        {
+            sfmd_V_cellUAvrg = (SumU - sfmd_V_cellUMax - sfmd_V_cellUMin) / (UNum - 2);
+        }
+
+        // 恢复
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            if (ErrUFlg[i])
+            {
+                if ((int16_T)(ihv_V_cellU[i] - sfmd_V_cellUAvrg) < 200 && (int16_T)(ihv_V_cellU[i] - sfmd_V_cellUAvrg) > -200)
+                {
+                    RecNr[i] = (RecNr[i] + 1) > 200 ? 200 : (RecNr[i] + 1);
+                }
+                else
+                {
+                    RecNr[i] = 0;
+                }
+                if (RecNr[i] >= 2)
+                {
+                    sfmv_flg_cellUOpenFlt[i] = false;
+                    ErrUFlg[i] = false;
+                }
+            }
+        }
+    }
+    //=======================电压处理======================================
+    SumU = 0;
+    sfmd_flg_volFlt = false;
+    for (i = 0; i < cmnc_num_cellUNum; i++)
+    {
+        if (ErrUFlg[i] && !sfmn_flg_interComFlt)
+        {
+            sfmv_V_cellU[i] = sfmd_V_cellUAvrg;
+        }
+        else
+        {
+            sfmv_flg_cellUOpenFlt[i] = false;
+            sfmv_V_cellU[i] = ihv_V_cellU[i];
+        }
+        SumU = SumU + sfmv_V_cellU[i];
+        sfmd_flg_volFlt = sfmd_flg_volFlt || sfmv_flg_cellUOpenFlt[i];
+    }
+    sfmd_V_battU = (uint16_T)(SumU * 0.01);
+
+    // 53 模组温度开路故障
+    sfmd_flg_modTOpenFlt = false;
+    for (i = 0; i < cmnc_num_modTNum; i++)
+    {
+        if (ihv_T_modT[i] == 10 && !sfmn_flg_interComFlt) //-30℃
+        {
+            modTOpenNr[i] = (modTOpenNr[i] + 1) > 200 ? 200 : (modTOpenNr[i] + 1);
+        }
+        else
+        {
+            modTOpenNr[i] = 0;
+        }
+        if (modTOpenNr[i] >= 2)
+        {
+            sfmv_flg_modTOpenFlt[i] = true;
+        }
+        else
+        {
+            sfmv_flg_modTOpenFlt[i] = false;
+        }
+
+        sfmd_flg_modTOpenFlt = sfmd_flg_modTOpenFlt || sfmv_flg_modTOpenFlt[i];
+    }
+
+    // 54 Mos温度开路故障
+    sfmd_flg_chrgMosTOpenFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, ihd_T_mosT == 10, &DiagTime.N54, 2);
+
+    // 56 快充插头温度开路故障
+    sfmd_flg_DCPlugTOpenFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, ihd_T_DCPlugT == 0, &DiagTime.N56, 2);
+    // 57 慢充插头温度开路故障
+    sfmd_flg_ACPlugTOpenFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, ihd_T_ACPlugT == 0, &DiagTime.N57, 2);
+    // 58 加热板#1温度开路故障
+    sfmd_flg_heatPanT1OpenFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, ihd_T_heatPanT1 == 0, &DiagTime.N58, 2);
+    // 59 加热板#2温度开路故障
+    sfmd_flg_heatPanT2OpenFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, ihd_T_heatPanT2 == 0, &DiagTime.N59, 2);
+
+    // 61 模组温度合理性故障
+    sfmd_flg_modTRatFlt = false;
+    for (i = 0; i < cmnc_num_modTNum && sfmd_flg_firstRun; i++)
+    {
+        modTArr[i] = ihv_T_modT[i];
+    }
+    for (i = 0; i < cmnc_num_modTNum; i++)
+    {
+        if (!sfmv_flg_modTOpenFlt[i] && ((int16_T)(modTArr[i] - ihv_T_modT[i]) > 10 || (int16_T)(modTArr[i] - ihv_T_modT[i]) < -20) && !sfmn_flg_interComFlt)
+        {
+            modTRatNr[i] = (modTRatNr[i] + 1) > 200 ? 200 : (modTRatNr[i] + 1);
+        }
+        else
+        {
+            modTRatNr[i] = 0;
+            modTArr[i] = ihv_T_modT[i];
+        }
+        if (modTRatNr[i] >= 2)
+        {
+            sfmv_flg_modTRatFlt[i] = true;
+        }
+        else
+        {
+            sfmv_flg_modTRatFlt[i] = false;
+        }
+
+        sfmd_flg_modTRatFlt = sfmd_flg_modTRatFlt || sfmv_flg_modTRatFlt[i];
+    }
+
+    // printf("%d,%d,%d,%d\n",sfmn_T_mosT_Delay,ihd_T_mosT,FirstRun_SFM,ihd_flg_urtRecFlt);
+    // 62 充电Mos 温度合理性故障
+    sfmn_flg_chrgMosTRatFltOnce = !sfmn_flg_interComFlt && !sfmd_flg_chrgMosTOpenFlt && ((int16_T)(ihd_T_mosT - sfmn_T_mosT_Delay) < -10 || (int16_T)(ihd_T_mosT - sfmn_T_mosT_Delay) > 20);
+    if (!sfmn_flg_chrgMosTRatFltOnce)
+    {
+        sfmn_T_mosT_Delay = ihd_T_mosT;
+    }
+    sfmd_flg_chrgMosTRatFlt = JudgeTimeSystem(1, sfmn_flg_chrgMosTRatFltOnce, &DiagTime.N62, 2);
+
+    // 64 快充插头温度合理性故障
+    sfmn_flg_DCPlugTRatFltOnce = !sfmn_flg_interComFlt && !sfmd_flg_DCPlugTOpenFlt && ((int16_T)(ihd_T_DCPlugT - sfmn_T_DCPlugT_Delay) < -10 || (int16_T)(ihd_T_DCPlugT - sfmn_T_DCPlugT_Delay) > 20);
+    if (!sfmn_flg_chrgMosTRatFltOnce)
+    {
+        sfmn_T_DCPlugT_Delay = ihd_T_DCPlugT;
+    }
+    sfmd_flg_DCPlugTRatFlt = JudgeTimeSystem(1, sfmn_flg_DCPlugTRatFltOnce, &DiagTime.N64, 2);
+
+    // 65 慢插头温度合理性故障
+    sfmn_flg_ACPlugTRatFltOnce = !sfmn_flg_interComFlt && !sfmd_flg_ACPlugTOpenFlt && ((int16_T)(ihd_T_ACPlugT - sfmn_T_ACPlugT_Delay) < -10 || (int16_T)(ihd_T_ACPlugT - sfmn_T_ACPlugT_Delay) > 20);
+    if (!sfmn_flg_ACPlugTRatFltOnce)
+    {
+        sfmn_T_ACPlugT_Delay = ihd_T_ACPlugT;
+    }
+    sfmd_flg_ACPlugTRatFlt = JudgeTimeSystem(1, sfmn_flg_ACPlugTRatFltOnce, &DiagTime.N65, 2);
+
+    // 66 加热板#1 温度合理性故障
+    sfmn_flg_heatPanT1RatFltOnce = !sfmn_flg_interComFlt && !sfmd_flg_heatPanT1OpenFlt && ((int16_T)(ihd_T_heatPanT1 - sfmn_T_heatPanT1_Delay) < -10 || (int16_T)(ihd_T_heatPanT1 - sfmn_T_heatPanT1_Delay) > 20);
+    if (!sfmn_flg_heatPanT1RatFltOnce)
+    {
+        sfmn_T_heatPanT1_Delay = ihd_T_heatPanT1;
+    }
+    sfmd_flg_heatPanT1RatFlt = JudgeTimeSystem(1, sfmn_flg_heatPanT1RatFltOnce, &DiagTime.N66, 2);
+
+    // 67 加热板#2 温度合理性故障
+    sfmn_flg_heatPanT2RatFltOnce = !sfmn_flg_interComFlt && !sfmd_flg_heatPanT2OpenFlt && ((int16_T)(ihd_T_heatPanT2 - sfmn_T_heatPanT2_Delay) < -10 || (int16_T)(ihd_T_heatPanT2 - sfmn_T_heatPanT2_Delay) > 20);
+    if (!sfmn_flg_heatPanT2RatFltOnce)
+    {
+        sfmn_T_heatPanT2_Delay = ihd_T_heatPanT2;
+    }
+    sfmd_flg_heatPanT2RatFlt = JudgeTimeSystem(1, sfmn_flg_heatPanT2RatFltOnce, &DiagTime.N67, 2);
+
+    // 68 模组温度全部不可用
+    sfmd_flg_modTAllFlt = true;
+    for (i = 0; i < cmnc_num_modTNum; i++)
+    {
+        sfmd_flg_modTAllFlt = sfmd_flg_modTAllFlt && (sfmv_flg_modTOpenFlt[i] || sfmv_flg_modTRatFlt[i]);
+    }
+
+    // 温度处理
+    sfmd_T_modTMax = 0;
+    sfmd_T_modTMin = 200;
+    Tnum = 0;
+    SumT = 0;
+    if (!sfmd_flg_modTAllFlt)
+    {
+        for (i = 0; i < cmnc_num_modTNum; i++)
+        {
+            if (!sfmv_flg_modTRatFlt[i] && !sfmv_flg_modTOpenFlt[i])
+            {
+                SumT = SumT + ihv_T_modT[i];
+                Tnum = Tnum + 1;
+                if (sfmd_T_modTMax < ihv_T_modT[i])
+                {
+                    sfmd_T_modTMax = ihv_T_modT[i];
+                    sfmd_idx_modTMax = i;
+                }
+                if (sfmd_T_modTMin > ihv_T_modT[i])
+                {
+                    sfmd_T_modTMin = ihv_T_modT[i];
+                    sfmd_idx_modTMin = i;
+                }
+            }
+        }
+        for (i = 0; i < cmnc_num_modTNum; i++)
+        {
+            if (!sfmv_flg_modTRatFlt[i] && !sfmv_flg_modTOpenFlt[i])
+            {
+                sfmv_T_modT[i] = ihv_T_modT[i];
+            }
+            else
+            {
+                sfmv_T_modT[i] = SumT / Tnum;
+            }
+        }
+    }
+
+    // 69 加热板温度全部开路故障
+    sfmd_flg_heatPanTAllFlt = (sfmd_flg_heatPanT1OpenFlt || sfmd_flg_heatPanT1RatFlt) && (sfmd_flg_heatPanT2OpenFlt || sfmd_flg_heatPanT2RatFlt);
+
+    // 71 电流传感器故障
+    sfmd_flg_currOpenFlt = false;
+    sfmd_I_curr = ihd_I_curr;
+    // 81 单体过压故障2级
+    sfmd_flg_cellUOverFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt, sfmd_V_cellUMax, sfmc_V_cellUOverThrFlt2, sfmc_V_cellUOverThrRec2, 2, 2, &DiagThr.fltNum81, &DiagThr.recNum81, &sfmd_flg_cellUOverFlt2);
+    // 82 单体过压故障1级
+    sfmd_flg_cellUOverFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt, sfmd_V_cellUMax, sfmc_V_cellUOverThrFlt1, sfmc_V_cellUOverThrRec1, 2, 2, &DiagThr.fltNum82, &DiagThr.recNum82, &sfmd_flg_cellUOverFlt1) && !sfmd_flg_cellUOverFlt2;
+
+    // 83 单体欠压故障2级
+    sfmd_flg_cellULowFlt2 = DiagThrSystem2(1, !sfmn_flg_interComFlt, sfmd_V_cellUMin, sfmc_V_cellULowThrFlt2, sfmc_V_cellULowThrRec2, 2, 2, &DiagThr.fltNum83, &DiagThr.recNum83, &sfmd_flg_cellULowFlt2);
+    // 84 单体欠压故障1级
+    sfmd_flg_cellULowFlt1 = DiagThrSystem2(0, !sfmn_flg_interComFlt, sfmd_V_cellUMin, sfmc_V_cellULowThrFlt1, sfmc_V_cellULowThrRec1, 2, 2, &DiagThr.fltNum84, &DiagThr.recNum84, &sfmd_flg_cellULowFlt1) && !sfmd_flg_cellULowFlt2;
+
+    // 85 压差过大2级
+    sfmd_flg_cellUDiffFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && socd_pct_battSoc > 200, sfmd_V_cellUMax - sfmd_V_cellUMin, sfmc_flg_cellUDiffThrFlt2, sfmc_flg_cellUDiffThrRec2, 2, 2, &DiagThr.fltNum85, &DiagThr.recNum85, &sfmd_flg_cellUDiffFlt2);
+    // 86 压差过大1级
+    sfmd_flg_cellUDiffFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && socd_pct_battSoc > 200, sfmd_V_cellUMax - sfmd_V_cellUMin, sfmc_flg_cellUDiffThrFlt1, sfmc_flg_cellUDiffThrRec1, 2, 2, &DiagThr.fltNum86, &DiagThr.recNum86, &sfmd_flg_cellUDiffFlt1) && !sfmd_flg_cellUDiffFlt2;
+
+    // 87 总压过压2级
+    sfmd_flg_battUOverFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt, sfmd_V_battU, sfmc_V_battUOverThrFlt2, sfmc_V_battUOverThrRec2, 2, 2, &DiagThr.fltNum87, &DiagThr.recNum87, &sfmd_flg_battUOverFlt2);
+    // 88 总压过压1级
+    sfmd_flg_battUOverFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt, sfmd_V_battU, sfmc_V_battUOverThrFlt1, sfmc_V_battUOverThrRec1, 2, 2, &DiagThr.fltNum88, &DiagThr.recNum88, &sfmd_flg_battUOverFlt1) && !sfmd_flg_battUOverFlt2;
+
+    // 89 总压欠压2级
+    sfmd_flg_battULowFlt2 = DiagThrSystem2(1, !sfmn_flg_interComFlt, sfmd_V_battU, sfmc_V_battULowThrFlt2, sfmc_V_battULowThrRec2, 2, 2, &DiagThr.fltNum89, &DiagThr.recNum89, &sfmd_flg_battULowFlt2);
+    // 90 总压欠压1级
+    sfmd_flg_battULowFlt1 = DiagThrSystem2(0, !sfmn_flg_interComFlt, sfmd_V_battU, sfmc_V_battULowThrFlt1, sfmc_V_battULowThrRec1, 2, 2, &DiagThr.fltNum90, &DiagThr.recNum90, &sfmd_flg_battULowFlt1) && !sfmd_flg_battULowFlt2;
+
+    chrgFlg = ihd_st_workStat == 2;
+    disChrgFlg = ihd_st_workStat != 2;
+
+    // 97 模组充电温度过高2级故障
+    sfmd_flg_chrgModTOverFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && chrgFlg && !sfmd_flg_modTAllFlt, sfmd_T_modTMax, sfmc_T_chrgModTOverThrFlt2, sfmc_T_chrgModTOverThrRec2, 3, 3, &DiagThr.fltNum97, &DiagThr.recNum97, &sfmd_flg_chrgModTOverFlt2);
+    // 98 模组充电温度过高1级故障
+    sfmd_flg_chrgModTOverFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && chrgFlg && !sfmd_flg_modTAllFlt, sfmd_T_modTMax, sfmc_T_chrgModTOverThrFlt1, sfmc_T_chrgModTOverThrRec1, 3, 3, &DiagThr.fltNum98, &DiagThr.recNum98, &sfmd_flg_chrgModTOverFlt1) && !sfmd_flg_chrgModTOverFlt2;
+    // 99 模组充电温度过低2级故障
+    sfmd_flg_chrgModTLowFlt2 = DiagThrSystem2(0, !sfmn_flg_interComFlt && chrgFlg && !sfmd_flg_modTAllFlt, sfmd_T_modTMin, sfmc_T_chrgModTLowThrFlt2, sfmc_T_chrgModTLowThrRec2, 3, 3, &DiagThr.fltNum99, &DiagThr.recNum99, &sfmd_flg_chrgModTLowFlt2);
+    // 100 模组充电温度过低1级故障
+    sfmd_flg_chrgModTLowFlt1 = DiagThrSystem2(0, !sfmn_flg_interComFlt && chrgFlg && !sfmd_flg_modTAllFlt, sfmd_T_modTMin, sfmc_T_chrgModTLowThrFlt1, sfmc_T_chrgModTLowThrRec1, 3, 3, &DiagThr.fltNum100, &DiagThr.recNum100, &sfmd_flg_chrgModTLowFlt1) && !sfmd_flg_chrgModTLowFlt2;
+
+    // 101 模组放电温度过高2级故障
+    sfmd_flg_disChrgModTOverFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && disChrgFlg && !sfmd_flg_modTAllFlt, sfmd_T_modTMax, sfmc_T_disChrgModTOverThrFlt2, sfmc_T_disChrgModTOverThrRec2, 3, 3, &DiagThr.fltNum101, &DiagThr.recNum101, &sfmd_flg_disChrgModTOverFlt2);
+    // 102 模组放电温度过高1级故障
+    sfmd_flg_disChrgModTOverFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && disChrgFlg && !sfmd_flg_modTAllFlt, sfmd_T_modTMax, sfmc_T_disChrgModTOverThrFlt1, sfmc_T_disChrgModTOverThrRec1, 3, 3, &DiagThr.fltNum102, &DiagThr.recNum102, &sfmd_flg_disChrgModTOverFlt1) && !sfmd_flg_disChrgModTOverFlt2;
+    // 103 模组放电温度过低2级故障
+    sfmd_flg_disChrgModTLowFlt2 = DiagThrSystem2(0, !sfmn_flg_interComFlt && disChrgFlg && !sfmd_flg_modTAllFlt, sfmd_T_modTMin, sfmc_T_disChrgModTLowThrFlt2, sfmc_T_disChrgModTLowThrRec2, 3, 3, &DiagThr.fltNum103, &DiagThr.recNum103, &sfmd_flg_disChrgModTLowFlt2);
+    // 104 模组放电温度过低1级故障
+    sfmd_flg_disChrgModTLowFlt1 = DiagThrSystem2(0, !sfmn_flg_interComFlt && disChrgFlg && !sfmd_flg_modTAllFlt, sfmd_T_modTMin, sfmc_T_disChrgModTLowThrFlt1, sfmc_T_disChrgModTLowThrRec1, 3, 3, &DiagThr.fltNum104, &DiagThr.recNum104, &sfmd_flg_disChrgModTLowFlt1) && !sfmd_flg_disChrgModTLowFlt2;
+
+    //
+    // 105 模组温差2级故障
+    sfmd_flg_modTDiffFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && !sfmd_flg_modTAllFlt, sfmd_T_modTMax - sfmd_T_modTMin, sfmc_T_modTDiffThrFlt2, sfmc_T_modTDiffThrRec2, 3, 3, &DiagThr.fltNum105, &DiagThr.recNum105, &sfmd_flg_modTDiffFlt2);
+    // 106 模组温差1级故障
+    sfmd_flg_modTDiffFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && !sfmd_flg_modTAllFlt, sfmd_T_modTMax - sfmd_T_modTMin, sfmc_T_modTDiffThrFlt1, sfmc_T_modTDiffThrRec1, 3, 3, &DiagThr.fltNum106, &DiagThr.recNum106, &sfmd_flg_modTDiffFlt1) && !sfmd_flg_modTDiffFlt2;
+
+    // 107 充电Mos温度过高2级故障
+    sfmd_flg_chrgMosTOverFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && chrgFlg && sfmd_flg_chrgMosTRatFlt && sfmd_flg_chrgMosTOpenFlt, ihd_T_mosT, sfmc_T_chrgMosTOverThrFlt2, sfmc_T_chrgMosTOverThrRec2, 3, 3, &DiagThr.fltNum107, &DiagThr.recNum107, &sfmd_flg_chrgMosTOverFlt2);
+    // 108 充电Mos温度过高1级故障
+    sfmd_flg_chrgMosTOverFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && chrgFlg && sfmd_flg_chrgMosTRatFlt && sfmd_flg_chrgMosTOpenFlt, ihd_T_mosT, sfmc_T_chrgMosTOverThrFlt1, sfmc_T_chrgMosTOverThrRec1, 3, 3, &DiagThr.fltNum108, &DiagThr.recNum108, &sfmd_flg_chrgMosTOverFlt1) && !sfmd_flg_chrgMosTOverFlt2;
+    // 109 放电Mos温度过高2级故障
+    sfmd_flg_disChrgMosTOverFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && disChrgFlg && sfmd_flg_chrgMosTRatFlt && sfmd_flg_chrgMosTOpenFlt, ihd_T_mosT, sfmc_T_disChrgMosTOverThrFlt2, sfmc_T_disChrgMosTOverThrRec2, 3, 3, &DiagThr.fltNum109, &DiagThr.recNum109, &sfmd_flg_disChrgMosTOverFlt2);
+    // 110 放电Mos温度过高1级故障
+    sfmd_flg_disChrgMosTOverFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && disChrgFlg && sfmd_flg_chrgMosTRatFlt && sfmd_flg_chrgMosTOpenFlt, ihd_T_mosT, sfmc_T_disChrgMosTOverThrFlt1, sfmc_T_disChrgMosTOverThrRec1, 3, 3, &DiagThr.fltNum110, &DiagThr.recNum110, &sfmd_flg_disChrgMosTOverFlt1) && !sfmd_flg_disChrgMosTOverFlt2;
+
+    // 111 快充插头温度过高2级故障
+    sfmd_flg_DCPlugTOverFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && sfmd_flg_DCPlugTRatFlt && sfmd_flg_DCPlugTOpenFlt, ihd_T_DCPlugT, sfmc_T_DCPlugTOverThrFlt2, sfmc_T_DCPlugTOverThrRec2, 3, 3, &DiagThr.fltNum111, &DiagThr.recNum111, &sfmd_flg_DCPlugTOverFlt2);
+    // 112 快充插头温度过高1级故障
+    sfmd_flg_DCPlugTOverFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && sfmd_flg_DCPlugTRatFlt && sfmd_flg_DCPlugTOpenFlt, ihd_T_DCPlugT, sfmc_T_DCPlugTOverThrFlt1, sfmc_T_DCPlugTOverThrRec1, 3, 3, &DiagThr.fltNum112, &DiagThr.recNum112, &sfmd_flg_DCPlugTOverFlt1) && !sfmd_flg_DCPlugTOverFlt2;
+    // 113 慢充插头温度过高2级故障
+    sfmd_flg_ACPlugTOverFlt2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && sfmd_flg_ACPlugTRatFlt && sfmd_flg_ACPlugTOpenFlt, ihd_T_ACPlugT, sfmc_T_ACPlugTOverThrFlt2, sfmc_T_ACPlugTOverThrRec2, 3, 3, &DiagThr.fltNum113, &DiagThr.recNum113, &sfmd_flg_ACPlugTOverFlt2);
+    // 114 慢充插头温度过高1级故障
+    sfmd_flg_ACPlugTOverFlt1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && sfmd_flg_ACPlugTRatFlt && sfmd_flg_ACPlugTOpenFlt, ihd_T_ACPlugT, sfmc_T_ACPlugTOverThrFlt1, sfmc_T_ACPlugTOverThrRec1, 3, 3, &DiagThr.fltNum114, &DiagThr.recNum114, &sfmd_flg_ACPlugTOverFlt1) && !sfmd_flg_ACPlugTOverFlt2;
+
+    // 115 加热板温度过高2级故障
+    sfmd_flg_heatPanTOverFlt2_1 = DiagThrSystem1(1, !sfmn_flg_interComFlt && sfmd_flg_heatPanT1RatFlt && sfmd_flg_heatPanT1OpenFlt, ihd_T_heatPanT1, sfmc_T_heatPanTOverThrFlt2, sfmc_T_heatPanTOverThrRec2, 3, 3, &DiagThr.fltNum115_1, &DiagThr.recNum115_1, &sfmd_flg_heatPanTOverFlt2_1);
+    sfmd_flg_heatPanTOverFlt2_2 = DiagThrSystem1(1, !sfmn_flg_interComFlt && sfmd_flg_heatPanT2RatFlt && sfmd_flg_heatPanT2OpenFlt, ihd_T_heatPanT2, sfmc_T_heatPanTOverThrFlt2, sfmc_T_heatPanTOverThrRec2, 3, 3, &DiagThr.fltNum115_2, &DiagThr.recNum115_2, &sfmd_flg_heatPanTOverFlt2_2);
+    sfmd_flg_heatPanTOverFlt2 = sfmd_flg_heatPanTOverFlt2_1 || sfmd_flg_heatPanTOverFlt2_2;
+    // 116 加热板温度过高1级故障
+    sfmd_flg_heatPanTOverFlt1_1 = DiagThrSystem1(0, !sfmn_flg_interComFlt && sfmd_flg_heatPanT1RatFlt && sfmd_flg_heatPanT1OpenFlt, ihd_T_heatPanT1, sfmc_T_heatPanTOverThrFlt1, sfmc_T_heatPanTOverThrRec1, 3, 3, &DiagThr.fltNum116_1, &DiagThr.recNum116_1, &sfmd_flg_heatPanTOverFlt1_1) && !sfmd_flg_heatPanTOverFlt2;
+    sfmd_flg_heatPanTOverFlt1_2 = DiagThrSystem1(0, !sfmn_flg_interComFlt && sfmd_flg_heatPanT2RatFlt && sfmd_flg_heatPanT2OpenFlt, ihd_T_heatPanT2, sfmc_T_heatPanTOverThrFlt1, sfmc_T_heatPanTOverThrRec1, 3, 3, &DiagThr.fltNum116_2, &DiagThr.recNum116_2, &sfmd_flg_heatPanTOverFlt1_2) && !sfmd_flg_heatPanTOverFlt2;
+    sfmd_flg_heatPanTOverFlt1 = sfmd_flg_heatPanTOverFlt1_1 || sfmd_flg_heatPanTOverFlt1_2;
+
+    sfmd_I_curr = ihd_I_curr;
+    sfmn_I_currAbs = (uint16_T)(sfmd_I_curr > 0 ? sfmd_I_curr : -sfmd_I_curr);
+    // 131 充电电流过高
+    sfmd_flg_chrgCurrOverFlt = DiagThrSystem1(1, !sfmn_flg_interComFlt && chrgFlg && !sfmd_flg_currOpenFlt, sfmn_I_currAbs, sfmc_I_chrgCurrOverThr, sfmc_I_chrgCurrOverThr, 2, 2, &DiagThr.fltNum131, &DiagThr.recNum131, &sfmd_flg_chrgCurrOverFlt);
+    // 132 放电电流过高
+    sfmd_flg_disChrgCurrOverFlt = DiagThrSystem1(1, !sfmn_flg_interComFlt && disChrgFlg && !sfmd_flg_currOpenFlt, sfmn_I_currAbs, sfmc_I_disChrgCurrOverThr, sfmc_I_disChrgCurrOverThr, 2, 2, &DiagThr.fltNum132, &DiagThr.recNum132, &sfmd_flg_disChrgCurrOverFlt);
+
+    // 151 充电过流故障不匹配
+    sfmd_flg_chrgCurrOverMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_chrgCurrOverFlt != ihd_flg_chrgCurrOverFlt, &DiagTime.N151, 2);
+    // 152 放电过流故障不匹配
+    sfmd_flg_disChrgCurrOverMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_disChrgCurrOverFlt != ihd_flg_disChrgCurrOverFlt, &DiagTime.N152, 2);
+    // 153 总压欠压不匹配
+    sfmd_flg_battULowMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_battULowFlt2 != ihd_flg_battULowFlt, &DiagTime.N153, 2);
+    // 154 总压过压不匹配
+    sfmd_flg_battUOverMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_battUOverFlt2 != ihd_flg_battUOverFlt, &DiagTime.N154, 2);
+
+    // 155 单体欠压故障不匹配
+    sfmd_flg_cellULowMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_cellULowFlt2 != ihd_flg_cellULowFlt, &DiagTime.N155, 2);
+    // 156 单体过压故障不匹配
+    sfmd_flg_cellUOverMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_cellUOverFlt2 != ihd_flg_cellUOverFlt, &DiagTime.N156, 2);
+
+    // 157 充电模组过温故障不匹配
+    sfmd_flg_chrgModTOverMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_chrgModTOverFlt2 != ihd_flg_chrgModTOverFlt, &DiagTime.N157, 2);
+    // 158 充电模组低温故障不匹配
+    sfmd_flg_chrgModTLowMisFlt = JudgeTimeSystem(0 && !sfmn_flg_interComFlt, sfmd_flg_chrgModTLowFlt2 != ihd_flg_chrgModTLowFlt, &DiagTime.N158, 2);
+    // 159 放电模组过温故障不匹配
+    sfmd_flg_disChrgModTOverMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_disChrgModTOverFlt2 != ihd_flg_disChrgModTOverFlt, &DiagTime.N159, 2);
+    // 160 放电模组低温故障不匹配
+    sfmd_flg_disChrgModTLowMisFlt = JudgeTimeSystem(0 && !sfmn_flg_interComFlt, sfmd_flg_disChrgModTLowFlt2 != ihd_flg_disChrgModTLowFlt, &DiagTime.N160, 2);
+
+    // 161 充电Mos过温故障不匹配
+    sfmd_flg_chrgMosTOverMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_chrgMosTOverFlt2 != ihd_flg_chrgMosTOverFlt, &DiagTime.N161, 2);
+    // 162 放电Mos过温故障不匹配
+    sfmd_flg_disChrgMosTOverMisFlt = JudgeTimeSystem(!sfmn_flg_interComFlt, sfmd_flg_disChrgMosTOverFlt2 != ihd_flg_disChrgMosTOverFlt, &DiagTime.N162, 2);
+
+    // 163 soc不匹配
+    sfmd_flg_socMisFlt = 0 && !sfmd_flg_firstRun && (!sfmn_flg_interComFlt) && ((int16_T)(socd_pct_vcuSoc - ihd_pct_soc) > 100 || (int16_T)(socd_pct_vcuSoc - ihd_pct_soc) < -100);
+    // 164 SOH 不匹配
+    sfmd_flg_sohMisFlt = 0 && !sfmd_flg_firstRun && (!sfmn_flg_interComFlt) && ((int16_T)(sohd_pct_bcuSoh - ihd_pct_soh) > 50 || (int16_T)(sohd_pct_bcuSoh - ihd_pct_soh) < -50);
+
+    // 178
+    sfmd_flg_deltRFlt = false;
+    if (!sfmn_flg_interComFlt)
+    {
+        SumR = 0;
+        SumRR = 0;
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            if (!cdmv_flg_inval[i])
+            {
+                SumR = SumR + cdmv_R_deltOhm[i];
+                SumRR = SumRR + cdmv_R_deltOhm[i] * cdmv_R_deltOhm[i];
+            }
+        }
+
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            if (!cdmv_flg_inval[i] && (cdmv_R_deltOhm[i] - SumR / cmnc_num_cellUNum) / (sqrt(SumRR / cmnc_num_cellUNum)) > 3 && (cdmv_R_deltOhm[i] - SumR / cmnc_num_cellUNum) > 500)
+            {
+                deltRFltNr[i] = (deltRFltNr[i] + 1) > 200 ? 200 : (deltRFltNr[i] + 1);
+            }
+            else
+            {
+                deltRFltNr[i] = 0;
+            }
+        }
+
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            if (deltRFltNr[i] > 60)
+            {
+                sfmd_flg_deltRFlt = true;
+            }
+        }
+    }
+
+    // 179 soc跳变
+    sfmd_flg_socJumpFlt = ((int16_T)(socd_pct_bcuSoc - sfmn_pct_bcuSoc_Delay) > 50 || (int16_T)(socd_pct_bcuSoc - sfmn_pct_bcuSoc_Delay) < -50) && JudgeTimeSystem(1, 1, &DiagTime.N179, 2);
+    sfmn_pct_bcuSoc_Delay = socd_pct_bcuSoc;
+    // 180 EE失效
+    sfmd_flg_EEsaveFlt = ihd_flg_EESaveFlt;
+
+    // 21 热失控故障
+    if (sfmd_I_curr > -2 && (sfmd_I_curr_Delay - sfmd_I_curr) > -2 && (sfmd_I_curr_Delay - sfmd_I_curr) < 2)
+    {
+        noDisChrgCnt = (noDisChrgCnt + 1) > 200 ? 200 : (noDisChrgCnt + 1);
+    }
+    else
+    {
+        noDisChrgCnt = 0;
+    }
+    sfmd_I_curr_Delay = sfmd_I_curr;
+
+    if (noDisChrgCnt > 60)
+    {
+        for (i = 0; i < cmnc_num_cellUNum; i++)
+        {
+            if ((int16_T)(CellUArry[3][i] - CellUArry[0][i]) < -100)
+            {
+                sfmn_flg_Udrop = true;
+            }
+        }
+        if (sfmd_flg_heatclear)
+        {
+            sfmn_flg_Udrop = false;
+        }
+    }
+    ////
+    if (sfmd_flg_volFlt)
+    {
+        sfmn_flg_volFlt_keep = true;
+    }
+    if (sfmd_flg_heatclear)
+    {
+        sfmn_flg_volFlt_keep = false;
+    }
+    //
+    CntA = CntA + 1;
+    if (CntA >= 0)
+    {
+        CntA = 0;
+        for (j = 0; j < 4 && sfmd_flg_firstRun; j++)
+        {
+            for (i = 0; i < cmnc_num_modTNum; i++)
+            {
+                ModTStor[j][i] = sfmv_T_modT[i];
+            }
+        }
+        for (j = 0; j < 3; j++)
+        {
+            for (i = 0; i < cmnc_num_modTNum; i++)
+            {
+                ModTStor[j][i] = ModTStor[j + 1][i];
+            }
+        }
+        for (i = 0; i < cmnc_num_modTNum; i++)
+        {
+            ModTStor[j][i] = sfmv_T_modT[i];
+        }
+        for (i = 0; i < cmnc_num_modTNum; i++)
+        {
+            if ((int16_T)(ModTStor[3][i] - ModTStor[2][i]) > 2 && (int16_T)(ModTStor[2][i] - ModTStor[1][i]) > 2 && (int16_T)(ModTStor[1][i] - ModTStor[0][i]) > 2)
+            {
+                sfmn_flg_Tup = true;
+            }
+        }
+        if (sfmd_flg_heatclear)
+        {
+            sfmn_flg_Tup = false;
+        }
+    }
+
+    //
+    if (sfmd_flg_modTOpenFlt)
+    {
+        sfmn_flg_modTOpenFlt_keep = true;
+    }
+    if (sfmd_flg_heatclear)
+    {
+        sfmn_flg_modTOpenFlt_keep = false;
+    }
+    //////
+    if (sfmn_flg_Udrop || sfmn_flg_volFlt_keep || sfmn_flg_Tup || sfmn_flg_modTOpenFlt_keep)
+    {
+        CntB = (CntB + 1) > 200 ? 200 : (CntB + 1);
+    }
+    if ((((sfmn_flg_Udrop && sfmn_flg_Tup) || (sfmn_flg_Udrop && sfmn_flg_modTOpenFlt_keep) || (sfmn_flg_volFlt_keep && sfmn_flg_Tup)) && CntB <= 180) || sfmd_flg_heatRunFltEi)
+    {
+        sfmd_flg_heatRunFltEo = true;
+    }
+    if (!sfmd_flg_heatRunFltEo && CntB > 180)
+    {
+        sfmd_flg_heatclear = true;
+        CntB = 0;
+    }
+    else
+    {
+        sfmd_flg_heatclear = false;
+    }
+
+    ////32 加热回路常闭故障
+    if (!sfmd_flg_modTAllFlt)
+    {
+        if (sfmd_flg_firstRun)
+        {
+            for (i = 0; i < 10; i++)
+            {
+                modTMaxArr[i] = sfmd_T_modTMax;
+            }
+            Time0Cnt = 0;
+            SumT0 = 0;
+        }
+        Time0Cnt++;
+        SumT0 = SumT0 + sfmd_T_modTMax;
+        if (Time0Cnt >= 60)
+        {
+            for (i = 0; i < 9; i++)
+            {
+                modTMaxArr[i] = modTMaxArr[i + 1];
+            }
+            modTMaxArr[9] = SumT0 / Time0Cnt;
+            Time0Cnt = 0;
+            SumT0 = 0;
+        }
+    }
+
+    if (!sfmd_flg_heatPanT1OpenFlt && !sfmd_flg_heatPanT1RatFlt && (int16_T)(ihd_T_heatPanT1 - sfmn_T_heatPanT1_Delay1) > -10 && (int16_T)(ihd_T_heatPanT1 - sfmn_T_heatPanT1_Delay1) < 20)
+    {
+        if (sfmd_flg_firstRun)
+        {
+            for (i = 0; i < 10; i++)
+            {
+                heatT1Arr[i] = ihd_T_heatPanT1;
+            }
+            Time1Cnt = 0;
+            SumT1 = 0;
+        }
+        Time1Cnt++;
+        SumT1 = SumT1 + ihd_T_heatPanT1;
+        if (Time1Cnt >= 60)
+        {
+            for (i = 0; i < 9; i++)
+            {
+                heatT1Arr[i] = heatT1Arr[i + 1];
+            }
+            heatT1Arr[9] = SumT1 / Time1Cnt;
+            Time1Cnt = 0;
+            SumT1 = 0;
+        }
+    }
+    sfmn_T_heatPanT1_Delay1 = ihd_T_heatPanT1;
+
+    if (!sfmd_flg_heatPanT2OpenFlt && !sfmd_flg_heatPanT2RatFlt && (int16_T)(ihd_T_heatPanT2 - sfmn_T_heatPanT2_Delay1) > -10 && (int16_T)(ihd_T_heatPanT2 - sfmn_T_heatPanT2_Delay1) < 20)
+    {
+        if (sfmd_flg_firstRun)
+        {
+            for (i = 0; i < 10; i++)
+            {
+                heatT2Arr[i] = ihd_T_heatPanT2;
+            }
+            Time2Cnt = 0;
+            SumT2 = 0;
+        }
+        Time2Cnt++;
+        SumT2 = SumT2 + ihd_T_heatPanT2;
+        if (Time2Cnt >= 60)
+        {
+            for (i = 0; i < 9; i++)
+            {
+                heatT2Arr[i] = heatT2Arr[i + 1];
+            }
+            heatT2Arr[9] = SumT2 / Time2Cnt;
+            Time2Cnt = 0;
+            SumT2 = 0;
+        }
+    }
+    sfmn_T_heatPanT2_Delay1 = ihd_T_heatPanT2;
+
+    // 32 加热回路常闭故障
+    Enable1 = JudgeTimeSystem(1, tmsd_st_heatAct == 0, &DiagTime.N32, 600);
+    sfmd_flg_heatCirClosFltEo = (((int16_T)(heatT2Arr[9] - heatT2Arr[0]) > 5 || (int16_T)(heatT1Arr[9] - heatT1Arr[0]) > 5) && (modTMaxArr[9] > modTMaxArr[0] + 4) && Enable1) || sfmd_flg_heatCirClosFltEo || sfmd_flg_heatCirClosFltEi;
+
+    // 33 加热回路常开故障
+    Enable2 = JudgeTimeSystem(1, tmsd_st_heatAct == 1, &DiagTime.N33, 600);
+    Enable2 = (DiagTime.N33 == 600);
+    sfmd_flg_heatCirOpenFltEo = (((int16_T)(heatT2Arr[9] - heatT2Arr[0]) < 5 && (int16_T)(heatT1Arr[9] - heatT1Arr[0]) < 5) && (modTMaxArr[9] < modTMaxArr[0] + 4) && Enable2) || sfmd_flg_heatCirOpenFltEo || sfmd_flg_heatCirOpenFltEi;
+
+    //================================================================================================================================================================
+    //================================================================================================================================================================
+    //===========故障码                                  故障等级                           禁止状态===================================================================
+    //================================================================================================================================================================
+    memset(FltFlg, 0, sizeof(FltFlg));
+    memset(FltLevel, 0, sizeof(FltLevel));
+    memset(FltAct, 0, sizeof(FltAct));
+
+    FltFlg[0] = sfmn_flg_interComFlt;
+    FltLevel[0] = 2;
+    FltAct[0] = 2; // 1 内网通讯故障
+
+    FltFlg[1] = 0;
+    FltLevel[1] = 0;
+    FltAct[1] = 0; // 2 外部通讯故障
+
+    FltFlg[2] = 0;
+    FltLevel[2] = 0;
+    FltAct[2] = 0; // 3 通讯模块故障
+
+    FltFlg[3] = 0;
+    FltLevel[3] = 0;
+    FltAct[3] = 0; // 4 通讯天线故障
+
+    FltFlg[4] = sfmn_flg_authFlt;
+    FltLevel[4] = 4;
+    FltAct[4] = 34; // 5 认证失败
+
+    FltFlg[5] = 0;
+    FltLevel[5] = 0;
+    FltAct[5] = 0; // 6 预留#5
+
+    FltFlg[6] = 0;
+    FltLevel[6] = 0;
+    FltAct[6] = 0; // 7 预留#4
+
+    FltFlg[7] = 0;
+    FltLevel[7] = 0;
+    FltAct[7] = 0; // 8 预留#3
+
+    FltFlg[8] = 0;
+    FltLevel[8] = 0;
+    FltAct[8] = 0; // 9  预留#2
+
+    FltFlg[9] = 0;
+    FltLevel[9] = 0;
+    FltAct[9] = 0; // 10 预留#1
+
+    FltFlg[10] = sfmn_flg_HVILFlt;
+    FltLevel[10] = 0;
+    FltAct[10] = 0; // 11 高压互锁
+
+    FltFlg[11] = 0;
+    FltLevel[11] = 0;
+    FltAct[11] = 0; // 12 硬件短路保护
+
+    FltFlg[12] = 0;
+    FltLevel[12] = 0;
+    FltAct[12] = 0; // 13 绝缘模块故障
+
+    FltFlg[13] = 0;
+    FltLevel[13] = 0;
+    FltAct[13] = 0; // 14 绝缘故障
+
+    FltFlg[14] = 0;
+    FltLevel[14] = 0;
+    FltAct[14] = 0; // 15 绝缘告警
+
+    FltFlg[15] = sfmd_flg_iscFltEo;
+    FltLevel[15] = 4;
+    FltAct[15] = 250; // 16
+
+    FltFlg[16] = 0;
+    FltLevel[16] = 0;
+    FltAct[16] = 0; // 17 预留4
+
+    FltFlg[17] = 0;
+    FltLevel[17] = 0;
+    FltAct[17] = 0; // 18 预留3
+
+    FltFlg[18] = 0;
+    FltLevel[18] = 0;
+    FltAct[18] = 0; // 19 预留2
+
+    FltFlg[19] = 0;
+    FltLevel[19] = 0;
+    FltAct[19] = 0; // 20 预留1
+
+    FltFlg[20] = sfmd_flg_heatRunFltEo;
+    FltLevel[20] = 5;
+    FltAct[20] = 255; // 21 热失控;
+
+    FltFlg[21] = sfmn_flg_chrgMosClosFlt;
+    FltLevel[21] = 4;
+    FltAct[21] = 106; // 22充电MOS常闭故障
+
+    FltFlg[22] = 0;
+    FltLevel[22] = 0;
+    FltAct[22] = 0; // 23充电MOS常开故障
+
+    FltFlg[23] = sfmn_flg_disChrgMosClosFlt;
+    FltLevel[23] = 4;
+    FltAct[23] = 106; // 24 放电Mos常闭故障
+
+    FltFlg[24] = 0;
+    FltLevel[24] = 0;
+    FltAct[24] = 0; // 25 放电Mos常开故障
+
+    FltFlg[25] = 0;
+    FltLevel[25] = 0;
+    FltAct[25] = 0;
+
+    FltFlg[26] = 0;
+    FltLevel[26] = 0;
+    FltAct[26] = 0;
+
+    FltFlg[27] = 0;
+    FltLevel[27] = 0;
+    FltAct[27] = 0;
+
+    FltFlg[28] = 0;
+    FltLevel[28] = 0;
+    FltAct[28] = 0;
+
+    FltFlg[29] = 0;
+    FltLevel[29] = 0;
+    FltAct[29] = 0;
+
+    FltFlg[30] = 0;
+    FltLevel[30] = 0;
+    FltAct[30] = 0;
+
+    FltFlg[31] = sfmd_flg_heatCirClosFltEo;
+    FltLevel[31] = 4;
+    FltAct[31] = 250; // 32 加热回路常闭故障
+
+    FltFlg[32] = sfmd_flg_heatCirOpenFltEo;
+    FltLevel[32] = 1;
+    FltAct[32] = 0; // 33 加热回路常开故障
+
+    FltFlg[33] = sfmd_flg_mainCirClosFltEo;
+    FltLevel[33] = 4;
+    FltAct[33] = 250; // 34 主回路常闭故障
+
+    FltFlg[34] = 0;
+    FltLevel[34] = 0;
+    FltAct[34] = 0;
+
+    FltFlg[35] = 0;
+    FltLevel[35] = 0;
+    FltAct[35] = 0;
+
+    FltFlg[36] = 0;
+    FltLevel[36] = 0;
+    FltAct[36] = 0;
+
+    FltFlg[37] = 0;
+    FltLevel[37] = 0;
+    FltAct[37] = 0;
+
+    FltFlg[38] = 0;
+    FltLevel[38] = 0;
+    FltAct[38] = 0;
+
+    FltFlg[39] = 0;
+    FltLevel[39] = 0;
+    FltAct[39] = 0;
+
+    FltFlg[40] = 0;
+    FltLevel[40] = 0;
+    FltAct[40] = 0;
+
+    FltFlg[41] = 0;
+    FltLevel[41] = 0;
+    FltAct[41] = 0;
+
+    FltFlg[42] = 0;
+    FltLevel[42] = 0;
+    FltAct[42] = 0;
+
+    FltFlg[43] = 0;
+    FltLevel[43] = 0;
+    FltAct[43] = 0;
+
+    FltFlg[44] = 0;
+    FltLevel[44] = 0;
+    FltAct[44] = 0;
+
+    FltFlg[45] = 0;
+    FltLevel[45] = 0;
+    FltAct[45] = 0;
+
+    FltFlg[46] = 0;
+    FltLevel[46] = 0;
+    FltAct[46] = 0;
+
+    FltFlg[47] = 0;
+    FltLevel[47] = 0;
+    FltAct[47] = 0;
+
+    FltFlg[48] = 0;
+    FltLevel[48] = 0;
+    FltAct[48] = 0;
+
+    FltFlg[49] = 0;
+    FltLevel[49] = 0;
+    FltAct[49] = 0;
+
+    FltFlg[50] = 0;
+    FltLevel[50] = 0;
+    FltAct[50] = 0; // 51均衡失效(合一) 暂缺
+
+    FltFlg[51] = sfmd_flg_volFlt;
+    FltLevel[51] = 4;
+    FltAct[51] = 234; // 52电压开路故障(合一)
+
+    FltFlg[52] = sfmd_flg_modTOpenFlt;
+    FltLevel[52] = 2;
+    FltAct[52] = 2; // 53温度开路故障(合一)
+
+    FltFlg[53] = sfmd_flg_chrgMosTOpenFlt;
+    FltLevel[53] = 2;
+    FltAct[53] = 130; // 54 Mos温度开路故障
+
+    FltFlg[54] = 0;
+    FltLevel[54] = 0;
+    FltAct[54] = 0;
+
+    FltFlg[55] = sfmd_flg_DCPlugTOpenFlt;
+    FltLevel[55] = 2;
+    FltAct[55] = 2; // 56 快充插头温度开路故障
+
+    FltFlg[56] = sfmd_flg_ACPlugTOpenFlt;
+    FltLevel[56] = 2;
+    FltAct[56] = 2; // 57  慢充插头温度开路故障
+
+    FltFlg[57] = sfmd_flg_heatPanT1OpenFlt;
+    FltLevel[57] = 2;
+    FltAct[57] = 2; // 58加热板#1温度开路故障
+
+    FltFlg[58] = sfmd_flg_heatPanT2OpenFlt;
+    FltLevel[58] = 2;
+    FltAct[58] = 2; // 59加热板#2温度开路故障
+
+    FltFlg[59] = 0;
+    FltLevel[59] = 0;
+    FltAct[59] = 0;
+
+    FltFlg[60] = sfmd_flg_modTRatFlt;
+    FltLevel[60] = 2;
+    FltAct[60] = 2; // 61模组温度合理性故障
+
+    FltFlg[61] = sfmd_flg_chrgMosTRatFlt;
+    FltLevel[61] = 2;
+    FltAct[61] = 130; // 62mos温度合理性故障
+
+    FltFlg[62] = 0;
+    FltLevel[62] = 0;
+    FltAct[62] = 0;
+
+    FltFlg[63] = sfmd_flg_DCPlugTRatFlt;
+    FltLevel[63] = 2;
+    FltAct[63] = 2; // 64快充插头温度合理性故障
+
+    FltFlg[64] = sfmd_flg_ACPlugTRatFlt;
+    FltLevel[64] = 2;
+    FltAct[64] = 2; // 65慢充插头温度合理性故障
+
+    FltFlg[65] = sfmd_flg_heatPanT1RatFlt;
+    FltLevel[65] = 2;
+    FltAct[65] = 2; // 66加热板#1温度合理性故障
+
+    FltFlg[66] = sfmd_flg_heatPanT2RatFlt;
+    FltLevel[66] = 2;
+    FltAct[66] = 2; // 67加热板#2温度合理性故障
+
+    FltFlg[67] = sfmd_flg_modTAllFlt;
+    FltLevel[67] = 4;
+    FltAct[67] = 250; // 模组温度全不可信
+
+    FltFlg[68] = sfmd_flg_heatPanTAllFlt;
+    FltLevel[68] = 3;
+    FltAct[68] = 18; // 加热板温度全不可信
+
+    FltFlg[69] = 0;
+    FltLevel[69] = 0;
+    FltAct[69] = 0;
+
+    FltFlg[70] = 0;
+    FltLevel[70] = 0;
+    FltAct[70] = 0; // 71 电流传感器故障 暂缺
+
+    FltFlg[71] = 0;
+    FltLevel[71] = 0;
+    FltAct[71] = 0;
+
+    FltFlg[72] = 0;
+    FltLevel[72] = 0;
+    FltAct[72] = 0;
+
+    FltFlg[73] = 0;
+    FltLevel[73] = 0;
+    FltAct[73] = 0;
+
+    FltFlg[74] = 0;
+    FltLevel[74] = 0;
+    FltAct[74] = 0;
+
+    FltFlg[75] = 0;
+    FltLevel[75] = 0;
+    FltAct[75] = 0;
+
+    FltFlg[76] = 0;
+    FltLevel[76] = 0;
+    FltAct[76] = 0;
+
+    FltFlg[77] = 0;
+    FltLevel[77] = 0;
+    FltAct[77] = 0;
+
+    FltFlg[78] = 0;
+    FltLevel[78] = 0;
+    FltAct[78] = 0;
+
+    FltFlg[79] = 0;
+    FltLevel[79] = 0;
+    FltAct[79] = 0;
+
+    FltFlg[80] = sfmd_flg_cellUOverFlt2;
+    FltLevel[80] = 4;
+    FltAct[80] = 66; // 81单体过压2级故障
+
+    FltFlg[81] = sfmd_flg_cellUOverFlt1;
+    FltLevel[81] = 4;
+    FltAct[81] = 66; // 82单体过压1级故障
+
+    FltFlg[82] = sfmd_flg_cellULowFlt2;
+    FltLevel[82] = 4;
+    FltAct[82] = 162; // 83单体欠压2级故障
+
+    FltFlg[83] = sfmd_flg_cellULowFlt1;
+    FltLevel[83] = 3;
+    FltAct[83] = 131; // 84单体欠压1级故障
+
+    FltFlg[84] = sfmd_flg_cellUDiffFlt2;
+    FltLevel[84] = 3;
+    FltAct[84] = 3; // 85压差过大2级故障
+
+    FltFlg[85] = sfmd_flg_cellUDiffFlt1;
+    FltLevel[85] = 2;
+    FltAct[85] = 2; // 86压差过大1级故障
+
+    FltFlg[86] = sfmd_flg_battUOverFlt2;
+    FltLevel[86] = 4;
+    FltAct[86] = 66; // 87总压过压2级故障
+
+    FltFlg[87] = sfmd_flg_battUOverFlt1;
+    FltLevel[87] = 4;
+    FltAct[87] = 66; // 88总压过压1级故障
+
+    FltFlg[88] = sfmd_flg_battULowFlt2;
+    FltLevel[88] = 4;
+    FltAct[88] = 162; // 89总压欠压2级故障
+
+    FltFlg[89] = sfmd_flg_battULowFlt1;
+    FltLevel[89] = 3;
+    FltAct[89] = 131; // 90总压欠压1级故障
+
+    FltFlg[90] = 0;
+    FltLevel[90] = 0;
+    FltAct[90] = 0;
+
+    FltFlg[91] = 0;
+    FltLevel[91] = 0;
+    FltAct[91] = 0;
+
+    FltFlg[92] = 0;
+    FltLevel[92] = 0;
+    FltAct[92] = 0;
+
+    FltFlg[93] = 0;
+    FltLevel[93] = 0;
+    FltAct[93] = 0;
+
+    FltFlg[94] = 0;
+    FltLevel[94] = 0;
+    FltAct[94] = 0;
+
+    FltFlg[95] = 0;
+    FltLevel[95] = 0;
+    FltAct[95] = 0;
+
+    FltFlg[96] = sfmd_flg_chrgModTOverFlt2;
+    FltLevel[96] = 4;
+    FltAct[96] = 250; // 97模组充电温度过高2级故障
+
+    FltFlg[97] = sfmd_flg_chrgModTOverFlt1;
+    FltLevel[97] = 3;
+    FltAct[97] = 145; // 98模组充电温度过高1级故障
+
+    FltFlg[98] = sfmd_flg_chrgModTLowFlt2;
+    FltLevel[98] = 0;
+    FltAct[98] = 0; // 99模组充电温度过低2级故障   =======
+
+    FltFlg[99] = sfmd_flg_chrgModTLowFlt1;
+    FltLevel[99] = 0;
+    FltAct[99] = 0; // 100模组充电温度过低1级故障  =======
+
+    FltFlg[100] = sfmd_flg_disChrgModTOverFlt2;
+    FltLevel[100] = 4;
+    FltAct[100] = 250; // 101模组充电温度过高2级故障
+
+    FltFlg[101] = sfmd_flg_disChrgModTOverFlt1;
+    FltLevel[101] = 3;
+    FltAct[101] = 145; // 102模组充电温度过高1级故障
+
+    FltFlg[102] = sfmd_flg_disChrgModTLowFlt2;
+    FltLevel[102] = 0;
+    FltAct[102] = 0; // 103模组充电温度过低2级故障  ==========
+
+    FltFlg[103] = sfmd_flg_disChrgModTLowFlt1;
+    FltLevel[103] = 0;
+    FltAct[103] = 0; // 104模组充电温度过低1级故障  ==========
+
+    FltFlg[104] = sfmd_flg_modTDiffFlt2;
+    FltLevel[104] = 3;
+    FltAct[104] = 19; // 105模组温差过大2级故障
+
+    FltFlg[105] = sfmd_flg_modTDiffFlt1;
+    FltLevel[105] = 1;
+    FltAct[105] = 0; // 106模组温差过大1级故障
+
+    FltFlg[106] = sfmd_flg_chrgMosTOverFlt2;
+    FltLevel[106] = 4;
+    FltAct[106] = 250; // 107 充电Mos温度过高2级故障
+
+    FltFlg[107] = sfmd_flg_chrgMosTOverFlt1;
+    FltLevel[107] = 3;
+    FltAct[107] = 19; // 108 充电Mos温度过高1级故障
+
+    FltFlg[108] = sfmd_flg_disChrgMosTOverFlt2;
+    FltLevel[108] = 4;
+    FltAct[108] = 250; // 109 放电Mos温度过高2级故障
+
+    FltFlg[109] = sfmd_flg_disChrgMosTOverFlt1;
+    FltLevel[109] = 3;
+    FltAct[109] = 19; // 110 放电Mos温度过高1级故障
+
+    FltFlg[110] = sfmd_flg_DCPlugTOverFlt2;
+    FltLevel[110] = 1;
+    FltAct[110] = 0; // 111 快充插头温度过高2级故障
+
+    FltFlg[111] = sfmd_flg_DCPlugTOverFlt1;
+    FltLevel[111] = 1;
+    FltAct[111] = 0; // 112 快充插头温度过高1级故障
+
+    FltFlg[112] = sfmd_flg_ACPlugTOverFlt1;
+    FltLevel[112] = 1;
+    FltAct[112] = 0; // 113 慢充插头温度过高2级故障
+
+    FltFlg[113] = sfmd_flg_ACPlugTOverFlt1;
+    FltLevel[113] = 1;
+    FltAct[113] = 0; // 114 慢充插头温度过高1级故障
+
+    FltFlg[114] = sfmd_flg_heatPanTOverFlt2;
+    FltLevel[114] = 3;
+    FltAct[114] = 18; // 115 加热板温度过高2级故障
+
+    FltFlg[115] = sfmd_flg_heatPanTOverFlt1;
+    FltLevel[115] = 1;
+    FltAct[115] = 0; // 116 加热板温度过高1级故障
+
+    FltFlg[116] = 0;
+    FltLevel[116] = 0;
+    FltAct[116] = 0;
+
+    FltFlg[117] = 0;
+    FltLevel[117] = 0;
+    FltAct[117] = 0;
+
+    FltFlg[118] = 0;
+    FltLevel[118] = 0;
+    FltAct[118] = 0;
+
+    FltFlg[119] = 0;
+    FltLevel[119] = 0;
+    FltAct[119] = 0;
+
+    FltFlg[120] = 0;
+    FltLevel[120] = 0;
+    FltAct[120] = 0;
+
+    FltFlg[121] = 0;
+    FltLevel[121] = 0;
+    FltAct[121] = 0;
+
+    FltFlg[122] = 0;
+    FltLevel[122] = 0;
+    FltAct[122] = 0;
+
+    FltFlg[123] = 0;
+    FltLevel[123] = 0;
+    FltAct[123] = 0;
+
+    FltFlg[124] = 0;
+    FltLevel[124] = 0;
+    FltAct[124] = 0;
+
+    FltFlg[125] = 0;
+    FltLevel[125] = 0;
+    FltAct[125] = 0;
+
+    FltFlg[126] = 0;
+    FltLevel[126] = 0;
+    FltAct[126] = 0;
+
+    FltFlg[127] = 0;
+    FltLevel[127] = 0;
+    FltAct[127] = 0;
+
+    FltFlg[128] = 0;
+    FltLevel[128] = 0;
+    FltAct[128] = 0;
+
+    FltFlg[129] = 0;
+    FltLevel[129] = 0;
+    FltAct[129] = 0;
+
+    FltFlg[130] = sfmd_flg_chrgCurrOverFlt;
+    FltLevel[130] = 4;
+    FltAct[130] = 66; // 131 充电电流过高
+
+    FltFlg[131] = sfmd_flg_disChrgCurrOverFlt;
+    FltLevel[131] = 4;
+    FltAct[131] = 34; // 132 放电电流过高
+
+    FltFlg[132] = 0;
+    FltLevel[132] = 0;
+    FltAct[132] = 0;
+
+    FltFlg[133] = 0;
+    FltLevel[133] = 0;
+    FltAct[133] = 0;
+
+    FltFlg[134] = 0;
+    FltLevel[134] = 0;
+    FltAct[134] = 0;
+
+    FltFlg[135] = 0;
+    FltLevel[135] = 0;
+    FltAct[135] = 0;
+
+    FltFlg[136] = 0;
+    FltLevel[136] = 0;
+    FltAct[136] = 0;
+
+    FltFlg[137] = 0;
+    FltLevel[137] = 0;
+    FltAct[137] = 0;
+
+    FltFlg[138] = 0;
+    FltLevel[138] = 0;
+    FltAct[138] = 0;
+
+    FltFlg[139] = 0;
+    FltLevel[139] = 0;
+    FltAct[139] = 0;
+
+    FltFlg[140] = 0;
+    FltLevel[140] = 0;
+    FltAct[140] = 0;
+
+    FltFlg[141] = 0;
+    FltLevel[141] = 0;
+    FltAct[141] = 0;
+
+    FltFlg[142] = 0;
+    FltLevel[142] = 0;
+    FltAct[142] = 0;
+
+    FltFlg[143] = 0;
+    FltLevel[143] = 0;
+    FltAct[143] = 0;
+
+    FltFlg[144] = 0;
+    FltLevel[144] = 0;
+    FltAct[144] = 0;
+
+    FltFlg[145] = 0;
+    FltLevel[145] = 0;
+    FltAct[145] = 0;
+
+    FltFlg[146] = 0;
+    FltLevel[146] = 0;
+    FltAct[146] = 0;
+
+    FltFlg[147] = 0;
+    FltLevel[147] = 0;
+    FltAct[147] = 0;
+
+    FltFlg[148] = 0;
+    FltLevel[148] = 0;
+    FltAct[148] = 0;
+
+    FltFlg[149] = 0;
+    FltLevel[149] = 0;
+    FltAct[149] = 0;
+
+    FltFlg[150] = sfmd_flg_chrgCurrOverMisFlt;
+    FltLevel[150] = 1;
+    FltAct[150] = 0; // 151 充电过流故障不匹配
+
+    FltFlg[151] = sfmd_flg_disChrgCurrOverMisFlt;
+    FltLevel[151] = 1;
+    FltAct[151] = 0; // 152 放电过流故障不匹配
+
+    FltFlg[152] = sfmd_flg_battULowMisFlt;
+    FltLevel[152] = 1;
+    FltAct[152] = 0; // 153 总压欠压不匹配
+
+    FltFlg[153] = sfmd_flg_battUOverMisFlt;
+    FltLevel[153] = 1;
+    FltAct[153] = 0; // 154 总压过压不匹配
+
+    FltFlg[154] = sfmd_flg_cellULowMisFlt;
+    FltLevel[154] = 1;
+    FltAct[154] = 0; // 155 单体欠压故障不匹配
+
+    FltFlg[155] = sfmd_flg_cellUOverMisFlt;
+    FltLevel[155] = 1;
+    FltAct[155] = 0; // 156 单体过压故障不匹配
+
+    FltFlg[156] = sfmd_flg_chrgModTOverMisFlt;
+    FltLevel[156] = 1;
+    FltAct[156] = 0; // 157 充电模组过温故障不匹配
+
+    FltFlg[157] = sfmd_flg_chrgModTLowMisFlt;
+    FltLevel[157] = 1;
+    FltAct[157] = 0; // 158 充电模组低温故障不匹配
+
+    FltFlg[158] = sfmd_flg_disChrgModTOverMisFlt;
+    FltLevel[158] = 1;
+    FltAct[158] = 0; // 159 放电模组过温故障不匹配
+
+    FltFlg[159] = sfmd_flg_disChrgModTLowMisFlt;
+    FltLevel[159] = 1;
+    FltAct[159] = 0; // 160 放电模组低温故障不匹配
+
+    FltFlg[160] = sfmd_flg_chrgMosTOverMisFlt;
+    FltLevel[160] = 1;
+    FltAct[160] = 0; // 161 充电Mos过温故障不匹配
+
+    FltFlg[161] = sfmd_flg_disChrgMosTOverMisFlt;
+    FltLevel[161] = 1;
+    FltAct[161] = 0; // 162 放电Mos过温故障不匹配
+
+    FltFlg[162] = sfmd_flg_socMisFlt;
+    FltLevel[162] = 1;
+    FltAct[162] = 0; // 163 soc不匹配
+
+    FltFlg[163] = sfmd_flg_sohMisFlt;
+    FltLevel[163] = 1;
+    FltAct[163] = 0; // 164 SOH 不匹配
+
+    FltFlg[164] = 0;
+    FltLevel[164] = 0;
+    FltAct[164] = 0;
+
+    FltFlg[165] = 0;
+    FltLevel[165] = 0;
+    FltAct[165] = 0;
+
+    FltFlg[166] = 0;
+    FltLevel[166] = 0;
+    FltAct[166] = 0;
+
+    FltFlg[167] = 0;
+    FltLevel[167] = 0;
+    FltAct[167] = 0;
+
+    FltFlg[168] = 0;
+    FltLevel[168] = 0;
+    FltAct[168] = 0;
+
+    FltFlg[169] = 0;
+    FltLevel[169] = 0;
+    FltAct[169] = 0;
+
+    FltFlg[170] = 0;
+    FltLevel[170] = 0;
+    FltAct[170] = 0;
+
+    FltFlg[171] = 0;
+    FltLevel[171] = 0;
+    FltAct[171] = 0;
+
+    FltFlg[172] = 0;
+    FltLevel[172] = 0;
+    FltAct[172] = 0;
+
+    FltFlg[173] = 0;
+    FltLevel[173] = 0;
+    FltAct[173] = 0;
+
+    FltFlg[174] = 0;
+    FltLevel[174] = 0;
+    FltAct[174] = 0;
+
+    FltFlg[175] = 0;
+    FltLevel[175] = 0;
+    FltAct[175] = 0;
+
+    FltFlg[176] = 0;
+    FltLevel[176] = 0;
+    FltAct[176] = 0;
+
+    FltFlg[177] = sfmd_flg_deltRFlt;
+    FltLevel[177] = 1;
+    FltAct[177] = 0;
+
+    FltFlg[178] = sfmd_flg_socJumpFlt;
+    FltLevel[178] = 1;
+    FltAct[178] = 0; // 179 soc跳变
+
+    FltFlg[179] = sfmd_flg_EEsaveFlt;
+    FltLevel[179] = 1;
+    FltAct[179] = 0; // 180 EE失效
+
+    //==========================================================================================================================================================
+    memset(FltCodeArr, 0, sizeof(FltCodeArr));
+    memset(FltLevelArr, 0, sizeof(FltLevelArr));
+    memset(FltActArr, 0, sizeof(FltActArr));
+    sfmd_num_fltNum = 0;
+
+    for (i = 0; i < FltArrLen && sfmd_num_fltNum < FltDispArrLen; i++)
+    {
+        if (FltFlg[i])
+        {
+            FltCodeArr[sfmd_num_fltNum] = i + 1;
+            FltLevelArr[sfmd_num_fltNum] = FltLevel[i];
+            FltActArr[sfmd_num_fltNum] = FltAct[i];
+            sfmd_num_fltNum = sfmd_num_fltNum + 1;
+
+            if (i == 50)
+            {
+                for (j = 0; j < cmnc_num_cellUNum; j++)
+                {
+
+                    FltCodeArr[sfmd_num_fltNum] = 1001 + j;
+                    FltLevelArr[sfmd_num_fltNum] = FltLevel[i];
+                    FltActArr[sfmd_num_fltNum] = FltAct[i];
+                    sfmd_num_fltNum = sfmd_num_fltNum + 1;
+                }
+            }
+            if (i == 51)
+            {
+                for (j = 0; j < cmnc_num_cellUNum; j++)
+                {
+                    if (sfmv_flg_cellUOpenFlt[j])
+                    {
+                        FltCodeArr[sfmd_num_fltNum] = 2001 + j;
+                        FltLevelArr[sfmd_num_fltNum] = FltLevel[i];
+                        FltActArr[sfmd_num_fltNum] = FltAct[i];
+                        sfmd_num_fltNum = sfmd_num_fltNum + 1;
+                    }
+                }
+            }
+            if (i == 52)
+            {
+                for (j = 0; j < cmnc_num_modTNum; j++)
+                {
+                    if (sfmv_flg_modTOpenFlt[j])
+                    {
+
+                        FltCodeArr[sfmd_num_fltNum] = 3001 + j;
+                        FltLevelArr[sfmd_num_fltNum] = FltLevel[i];
+                        FltActArr[sfmd_num_fltNum] = FltAct[i];
+                        sfmd_num_fltNum = sfmd_num_fltNum + 1;
+                    }
+                }
+            }
+            if (i == 60)
+            {
+                for (j = 0; j < cmnc_num_modTNum; j++)
+                {
+                    if (sfmv_flg_modTRatFlt[j])
+                    {
+                        FltCodeArr[sfmd_num_fltNum] = 3201 + j;
+                        FltLevelArr[sfmd_num_fltNum] = FltLevel[i];
+                        FltActArr[sfmd_num_fltNum] = FltAct[i];
+                        sfmd_num_fltNum = sfmd_num_fltNum + 1;
+                    }
+                }
+            }
+        }
+    }
+
+    memset(sfmv_idx_fltCode, 0, sizeof(sfmv_idx_fltCode));
+    sfmd_st_fltAct = 0;
+    sfmd_st_fltLevel = 0;
+    for (i = 0; i < sfmd_num_fltNum; i++)
+    {
+        sfmv_idx_fltCode[i] = FltLevelArr[i] * 10000 + FltCodeArr[i];
+
+        if (sfmd_st_fltLevel < FltLevelArr[i])
+        {
+            sfmd_st_fltLevel = FltLevelArr[i];
+        }
+        sfmd_st_fltAct = sfmd_st_fltAct | FltActArr[i];
+    }
+
+    /*
+     for(i=0;i < 20;i++)
+     {
+         printf("%d  ",sfmv_idx_fltCode[i]);
+     }
+     printf("\n");
+    */
+
+    ///=====================================================================
+    //======================================================================
+
+    sfmd_flg_cellUInval = sfmn_flg_interComFlt || sfmd_flg_volFlt;
+    sfmd_flg_currInval = sfmn_flg_interComFlt || sfmd_flg_currOpenFlt;
+    sfmd_flg_modTInval = sfmn_flg_interComFlt || sfmd_flg_modTOpenFlt || sfmd_flg_modTRatFlt;
+    sfmd_flg_firstRun = false;
+}
+
+//===============================================================================

+ 114 - 0
code/app/bms/SFM.h

@@ -0,0 +1,114 @@
+#include "rtwtypes.h"
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include <math.h>
+#include "funlib.h"
+
+extern void SFM_Init(void);
+extern void SFM(void);
+
+typedef struct
+{
+    uint8_T fltNum81;
+    uint8_T recNum81;
+    uint8_T fltNum82;
+    uint8_T recNum82;
+    uint8_T fltNum83;
+    uint8_T recNum83;
+    uint8_T fltNum84;
+    uint8_T recNum84;
+    uint8_T fltNum85;
+    uint8_T recNum85;
+    uint8_T fltNum86;
+    uint8_T recNum86;
+    uint8_T fltNum87;
+    uint8_T recNum87;
+    uint8_T fltNum88;
+    uint8_T recNum88;
+    uint8_T fltNum89;
+    uint8_T recNum89;
+    uint8_T fltNum90;
+    uint8_T recNum90;
+    uint8_T fltNum97;
+    uint8_T recNum97;
+    uint8_T fltNum98;
+    uint8_T recNum98;
+    uint8_T fltNum99;
+    uint8_T recNum99;
+    uint8_T fltNum100;
+    uint8_T recNum100;
+    uint8_T fltNum101;
+    uint8_T recNum101;
+    uint8_T fltNum102;
+    uint8_T recNum102;
+    uint8_T fltNum103;
+    uint8_T recNum103;
+    uint8_T fltNum104;
+    uint8_T recNum104;
+    uint8_T fltNum105;
+    uint8_T recNum105;
+    uint8_T fltNum106;
+    uint8_T recNum106;
+    uint8_T fltNum107;
+    uint8_T recNum107;
+    uint8_T fltNum108;
+    uint8_T recNum108;
+    uint8_T fltNum109;
+    uint8_T recNum109;
+    uint8_T fltNum110;
+    uint8_T recNum110;
+    uint8_T fltNum111;
+    uint8_T recNum111;
+    uint8_T fltNum112;
+    uint8_T recNum112;
+    uint8_T fltNum113;
+    uint8_T recNum113;
+    uint8_T fltNum114;
+    uint8_T recNum114;
+    uint8_T fltNum115_1;
+    uint8_T recNum115_1;
+    uint8_T fltNum115_2;
+    uint8_T recNum115_2;
+    uint8_T fltNum116_1;
+    uint8_T recNum116_1;
+    uint8_T fltNum116_2;
+    uint8_T recNum116_2;
+    uint8_T fltNum131;
+    uint8_T recNum131;
+    uint8_T fltNum132;
+    uint8_T recNum132;
+} DiagThrstruct;
+
+typedef struct
+{
+    uint16_T N22;
+    uint16_T N24;
+    uint16_T N32;
+    uint16_T N33;
+    uint16_T N34;
+    uint16_T N54;
+    uint16_T N56;
+    uint16_T N57;
+    uint16_T N58;
+    uint16_T N59;
+    uint16_T N62;
+    uint16_T N64;
+    uint16_T N65;
+    uint16_T N66;
+    uint16_T N67;
+    uint16_T N151;
+    uint16_T N152;
+    uint16_T N153;
+    uint16_T N154;
+    uint16_T N155;
+    uint16_T N156;
+    uint16_T N157;
+    uint16_T N158;
+    uint16_T N159;
+    uint16_T N160;
+    uint16_T N161;
+    uint16_T N162;
+    uint16_T N179;
+} DiagTimestruct;
+
+

+ 615 - 0
code/app/bms/SOC.c

@@ -0,0 +1,615 @@
+#include "SOC.h"
+
+//---------------SOC初始化-----------------------------------------------
+void SOC_Init(void)
+{
+    socd_flg_firstRun = true;
+}
+
+
+//-------------------------------------------------------------------------
+//---------------------------SOC-------------------------------------------
+//-------------------------------------------------------------------------
+void SOC(void)
+{
+    static uint16_T socn_pct_battSocEE;
+    static uint16_T socn_pct_bcuSocEE;
+    static uint16_T socn_Q_cap;
+    //
+    real_T Q;
+    real_T battcurr;
+    boolean_T socn_flg_ekfInvalidMin;
+    boolean_T socn_flg_ekfInvalidMax;
+    boolean_T socn_flg_ekfInvalidAvrg;
+    boolean_T socn_flg_ekfInvalid;
+    real_T ocv;
+    real_T Ro;
+    real_T Rp;
+    real_T RC;
+    real_T deltU;
+	real_T UL;
+    real_T A[4];
+    real_T B[2];
+    real_T H[2];
+    real_T K[2];
+    real_T P1[4];
+    static real_T P_Min_Delay[4];
+    static real_T P_Max_Delay[4];
+    static real_T P_avrg_Delay[4];
+    real_T soc1;
+    static real_T soc_Min_Delay;
+    static real_T soc_Avrg_Delay;
+    static real_T soc_Max_Delay;
+    real_T Up1;
+    static real_T Up_Min_Delay;
+    static real_T Up_Max_Delay;
+    static real_T Up_Avrg_Delay;
+	uint16_T EKFSOCMin;
+    uint16_T EKFSOCMax;
+	
+    uint16_T EKFSOCAvrg;
+	uint16_T cellSocMax;
+    uint16_T cellSocMin;
+    uint16_T factor;
+    //
+    static real_T ahDelay;
+    int16_T ahSoc;
+    //
+    boolean_T socn_flg_ekfDisable;
+    static uint16_T  ekfInvalidCntl;
+    static boolean_T onceFlg_est;
+    static int16_T   ahSoc0_est;
+    static uint16_T  ekfSoc0_est;
+    // 
+    uint16_T socn_V_chrgCCV;
+	uint16_T socn_V_disChrgCCV;
+    static boolean_T overFlg;
+    static boolean_T fulFlg;
+    static uint16_T overCntl;
+    static uint16_T fulCntl;
+    static boolean_T onceFlg_utrckOver;
+    static int16_T   ahSoc0_utrckOver;
+    static uint16_T  estSoc0_utrckOver;
+    static uint16_T Soc_Delay;
+    static boolean_T lowFlg;
+    static uint16_T lowCntl;
+    static boolean_T onceFlg_utrckLow;
+    static int16_T ahSoc0_utrckLow;
+    static uint16_T estSoc0_utrckLow;
+    uint16_T socn_pct_utrackSoc;
+    uint16_T socTemp;
+    //
+    //
+    static uint16_T statCntl;
+    static uint8_T  socn_st_workStat_Delay;
+    static uint16_T socn_pct_battSoc_Delay;
+    static uint16_T socn_pct_battSoc0;
+    static uint16_T socn_pct_bcuSoc0;
+    uint16_T delSOC;
+    uint16_T bcuSoc;
+    int16_T  coinSoc;
+    uint16_T x[3];
+    uint16_T y[3];
+    boolean_T Flg;
+    static boolean_T onceFlg_chrg;
+    static boolean_T onceFlg_dischrg;
+
+	static uint16_T socn_pct_battSoc_save;
+	static uint16_T socn_pct_bcuSoc_save;
+    uint16_T i;
+    //
+    if (socd_flg_firstRun)
+    {
+        onceFlg_est = true;
+        ekfInvalidCntl = 0;
+        overCntl = 0;
+        fulCntl = 0;
+        lowCntl = 0;
+        overFlg = false;
+        fulFlg = false;
+        lowFlg = false;
+		statCntl = 0;
+        Soc_Delay = 0;
+        onceFlg_utrckOver = true;
+        onceFlg_utrckLow = true;
+        socn_st_workStat_Delay = 0;
+        socn_pct_battSoc_Delay = 0;
+        onceFlg_chrg = true;
+        onceFlg_dischrg = true;
+		socn_pct_battSoc_save = 0;
+		socn_pct_bcuSoc_save = 0;
+    }
+    
+    //=====================================================================
+    ////////////////////////初始值获取/EE校验//////////////////////////////
+    //=====================================================================
+    if (socd_flg_firstRun)
+    { //
+        if (socd_pct_battSocEi > socc_pct_battSocUp || socd_pct_bcuSocEi > socc_pct_battSocUp || ihd_st_EOLState == 0  ||
+           (((int16_T)(socd_pct_battSocEi - socd_pct_bcuSocEi) > 300 || (int16_T)(socd_pct_battSocEi - socd_pct_bcuSocEi) < -300) && ihd_tm_parkTime >= cmnc_tm_parkTime && sfmd_I_curr < 10 && sfmd_I_curr > -10))
+        {
+            socn_pct_battSocEE = look1_u16tu16(sfmd_V_cellUAvrg, cmnm_V_ocv, cmnm_pct_soc, 13);
+            socn_pct_bcuSocEE  = look1_u16tu16(sfmd_V_cellUAvrg, cmnm_V_ocv, cmnm_pct_soc, 13);
+        }
+        else
+        {
+            socn_pct_battSocEE = socd_pct_battSocEi;
+            socn_pct_bcuSocEE  = socd_pct_bcuSocEi;
+        }
+        //
+        if (ihd_tm_parkTime >= cmnc_tm_parkTime  && sfmd_I_curr < 10 && sfmd_I_curr > -10)
+        {
+            socn_pct_battSocEE = look1_u16tu16(sfmd_V_cellUAvrg, cmnm_V_ocv, cmnm_pct_soc, 13);
+        }
+        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//////////////////////////////////////////
+    //======================================================================
+    battcurr = (real_T)sfmd_I_curr * 0.1;
+    Q = (real_T)socn_Q_cap * 0.1;
+    
+    //-------------------------EKFmin---------------------------------------
+    if (socd_flg_firstRun)
+    {
+        soc_Min_Delay = (real_T)socn_pct_battSocEE * 0.1;
+        Up_Min_Delay = 0;
+        P_Min_Delay[0] = 10;
+        P_Min_Delay[1] = 0;
+        P_Min_Delay[2] = 0;
+        P_Min_Delay[3] = 10;
+    }
+    //参数查表
+    ocv = (real_T)look1_u16tu16((uint16_T)(soc_Min_Delay * 10), cmnm_pct_soc, cmnm_V_ocv,  13) * 0.001;
+    Ro  = (real_T)look1_u16tu16((uint16_T)(soc_Min_Delay * 10), cmnm_pct_soc, cmnm_R_ohm,  13) * 0.001 * 0.001;
+    Rp  = (real_T)look1_u16tu16((uint16_T)(soc_Min_Delay * 10), cmnm_pct_soc, cmnm_R_polar,13) * 0.001 * 0.001;
+    RC  = (real_T)look1_u16tu16((uint16_T)(soc_Min_Delay * 10), cmnm_pct_soc, cmnm_F_polar,13) * 0.001;
+    A[0] = 1;
+    A[1] = 0;
+    A[2] = 0;
+    A[3] = exp(-1 / RC);
+    
+    B[0] = 1 / Q / 3600 * 100;
+    B[1] = Rp * (1 - exp(-1 / RC));
+    
+    H[0] = docvmath(soc_Min_Delay);
+    H[1] = 1;
+    
+    //先验
+    soc1 = soc_Min_Delay * A[0] + B[0] * battcurr;
+    Up1 = Up_Min_Delay * A[3] + B[1] * battcurr;
+    UL = ocv + battcurr * Ro + Up1;
+    P1[0] = P_Min_Delay[0] + 0.001;
+    P1[1] = P_Min_Delay[1] * A[3] + 0.001;
+    P1[2] = P_Min_Delay[2] * A[3] + 0.001;
+    P1[3] = P_Min_Delay[3] * A[3] * A[3] + 0.001;
+    
+    //增益
+    K[0] = (P1[0] * H[0] + P1[2]) / (H[0] * P1[0] * H[0] + P1[1] * H[0] + H[0] * P1[2] + P1[3] + 0.5);
+    K[1] = (P1[1] * H[0] + P1[3]) / (H[0] * P1[0] * H[0] + P1[1] * H[0] + H[0] * P1[2] + P1[3] + 0.5);
+    
+    //后验
+    deltU = (real_T)sfmd_V_cellUMin * 0.001 - UL;
+    soc_Min_Delay = soc1 + K[0] * deltU;
+    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];
+    P_Min_Delay[1] = -K[1] * H[0] * P1[0] + P1[1] * (1 - K[1]);
+    P_Min_Delay[2] = (1 - K[0] * H[0]) * P1[2] - K[0] * P1[3];
+    P_Min_Delay[3] = -K[1] * H[0] * P1[2] + P1[3] * (1 - K[1]);
+    
+    //输出
+    EKFSOCMin = (uint16_T)(soc_Min_Delay * 10);
+    socn_flg_ekfInvalidMin = (deltU > 0.02) || (deltU < -0.02);
+    //printf("2----socmin:%f,U:%d,R:%f\n",soc_Min_Delay,sfmd_V_cellUMin,Ro);
+	//------------------------EKFSOCmax-----------------------------------
+    if (socd_flg_firstRun)
+    {
+        soc_Max_Delay = (real_T)socn_pct_battSocEE * 0.1;
+        Up_Max_Delay = 0;
+        P_Max_Delay[0] = 10;
+        P_Max_Delay[1] = 0;
+        P_Max_Delay[2] = 0;
+        P_Max_Delay[3] = 10;
+    }
+    // 参数查表
+    ocv = (real_T)look1_u16tu16((uint16_T)(soc_Max_Delay * 10), cmnm_pct_soc, cmnm_V_ocv,  13) * 0.001;
+    Ro  = (real_T)look1_u16tu16((uint16_T)(soc_Max_Delay * 10), cmnm_pct_soc, cmnm_R_ohm,  13) * 0.001 * 0.001;
+    Rp  = (real_T)look1_u16tu16((uint16_T)(soc_Max_Delay * 10), cmnm_pct_soc, cmnm_R_polar,13) * 0.001 * 0.001;
+    RC  = (real_T)look1_u16tu16((uint16_T)(soc_Max_Delay * 10), cmnm_pct_soc, cmnm_F_polar,13) * 0.001;
+
+    A[0] = 1;
+    A[1] = 0;
+    A[2] = 0;
+    A[3] = exp(-1 / RC);
+    
+    B[0] = 1 / Q / 3600 * 100;
+    B[1] = Rp * (1 - exp(-1 / RC));
+    
+    H[0] = docvmath(soc_Max_Delay);
+    H[1] = 1;
+    
+    //先验
+    soc1 = soc_Max_Delay * A[0] + B[0] * battcurr;
+    Up1 = Up_Max_Delay * A[3] + B[1] * battcurr;
+    UL = ocv + battcurr * Ro + Up1;
+    
+    P1[0] = P_Max_Delay[0] + 0.001;
+    P1[1] = P_Max_Delay[1] * A[3] + 0.001;
+    P1[2] = P_Max_Delay[2] * A[3] + 0.002;
+    P1[3] = P_Max_Delay[3] * A[3] * A[3] + 0.001;
+    
+    //增益
+    K[0] = (P1[0] * H[0] + P1[2]) / (H[0] * P1[0] * H[0] + P1[1] * H[0] + H[0] * P1[2] + P1[3] + 0.5);
+    K[1] = (P1[1] * H[0] + P1[3]) / (H[0] * P1[0] * H[0] + P1[1] * H[0] + H[0] * P1[2] + P1[3] + 0.5);
+    
+    //后验
+    deltU = (real_T)sfmd_V_cellUMax * 0.001 - UL;
+    soc_Max_Delay = soc1 + K[0] * deltU;
+	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更新
+    P_Max_Delay[0] = (1 - K[0] * H[0]) * P1[0] - K[0] * P1[1];
+    P_Max_Delay[1] = -K[1] * H[0] * P1[0] + P1[1] * (1 - K[1]);
+    P_Max_Delay[2] = (1 - K[0] * H[0]) * P1[2] - K[0] * P1[3];
+    P_Max_Delay[3] = -K[1] * H[0] * P1[2] + P1[3] * (1 - K[1]);
+    //输出
+    EKFSOCMax = (uint16_T)(soc_Max_Delay * 10);
+    socn_flg_ekfInvalidMax = (deltU > 0.02) || (deltU < -0.02);
+    //printf("3----socmax:%f,U:%d,R:%f\n\n",soc_Max_Delay,sfmd_V_cellUMax,Ro);
+    //-----------------------EKFSOC----------------------------------------
+    socn_flg_ekfInvalid = socn_flg_ekfInvalidMax || socn_flg_ekfInvalidMin;
+    if (EKFSOCMax > 800)
+    {
+        factor = 100;
+    }
+    else if (EKFSOCMin < 200)
+    {
+        factor = 0;
+    }
+    else
+    {
+        factor = (uint16_T)(((uint16_T)(((uint32_T)(EKFSOCMin - 200) << 6) / (800 - (EKFSOCMax - EKFSOCMin) - 200)) * 25U) >> 4);
+    }
+    socd_pct_ekfSoc = (uint16_T)(((1 - (real_T)(factor * 0.01)) * (real_T)(EKFSOCMin * 0.1) + (real_T)(factor * 0.01) * (real_T)(EKFSOCMax * 0.1)) * 10);
+   
+   //printf("4----socd_pct_ekfSoc:%d,EKFSOCMax:%d,EKFSOCMin:%d,\n",socd_pct_ekfSoc,EKFSOCMax,EKFSOCMin);
+/*
+   //-------------------------EKFavrg---------------------------------------
+    if (socd_flg_firstRun)
+    {
+        soc_Avrg_Delay = (real_T)socn_pct_battSocEE * 0.1;
+        Up_Avrg_Delay = 0;
+        P_avrg_Delay[0] = 10;
+        P_avrg_Delay[1] = 0;
+        P_avrg_Delay[2] = 0;
+        P_avrg_Delay[3] = 10;
+    }
+    //参数查表
+    ocv = (real_T)look1_u16tu16((uint16_T)(soc_Avrg_Delay * 10), cmnm_pct_soc, cmnm_V_ocv,  13) * 0.001;
+    Ro  = (real_T)look1_u16tu16((uint16_T)(soc_Avrg_Delay * 10), cmnm_pct_soc, cmnm_R_ohm,  13) * 0.001 * 0.001;
+    Rp  = (real_T)look1_u16tu16((uint16_T)(soc_Avrg_Delay * 10), cmnm_pct_soc, cmnm_R_polar,13) * 0.001 * 0.001;
+    RC  = (real_T)look1_u16tu16((uint16_T)(soc_Avrg_Delay * 10), cmnm_pct_soc, cmnm_F_polar,13) * 0.001;
+
+    A[0] = 1;
+    A[1] = 0;
+    A[2] = 0;
+    A[3] = exp(-1 / RC);
+    
+    B[0] = 1 / Q / 3600 * 100;
+    B[1] = Rp * (1 - exp(-1 / RC));
+    
+    H[0] = docvmath(soc_Avrg_Delay);
+    H[1] = 1;
+    
+    //先验
+    soc1 = soc_Avrg_Delay * A[0] + B[0] * battcurr;
+    Up1 = Up_Avrg_Delay * A[3] + B[1] * battcurr;
+    UL = ocv + battcurr * Ro + Up1;
+    P1[0] = P_avrg_Delay[0] + 0.001;
+    P1[1] = P_avrg_Delay[1] * A[3] + 0.001;
+    P1[2] = P_avrg_Delay[2] * A[3] + 0.001;
+    P1[3] = P_avrg_Delay[3] * A[3] * A[3] + 0.001;
+    
+    //增益
+    K[0] = (P1[0] * H[0] + P1[2]) / (H[0] * P1[0] * H[0] + P1[1] * H[0] + H[0] * P1[2] + P1[3] + 0.5);
+    K[1] = (P1[1] * H[0] + P1[3]) / (H[0] * P1[0] * H[0] + P1[1] * H[0] + H[0] * P1[2] + P1[3] + 0.5);
+    
+    //后验
+    deltU = (real_T)sfmd_V_cellUAvrg * 0.001 - UL;
+    soc_Avrg_Delay = soc1 + K[0] * deltU;
+    
+    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];
+    P_avrg_Delay[1] = -K[1] * H[0] * P1[0] + P1[1] * (1 - K[1]);
+    P_avrg_Delay[2] = (1 - K[0] * H[0]) * P1[2] - K[0] * P1[3];
+    P_avrg_Delay[3] = -K[1] * H[0] * P1[2] + P1[3] * (1 - K[1]);
+    
+    //输出
+    EKFSOCAvrg = (uint16_T)(soc_Avrg_Delay * 10);
+    socn_flg_ekfInvalidAvrg = (deltU > 0.01) || (deltU < -0.01);
+	//printf("4----soc:%f,Up:%f,U:%d,deltU:%f,K[0]:%f,K[1]:%f\n\n",soc_Avrg_Delay,Up_Avrg_Delay,sfmd_V_cellUAvrg,deltU,K[0],K[1]);
+    //
+    for(i = 0;i < cmnc_num_cellUNum;i++)
+    {
+        socv_pct_cellSoc[i] = look1_u16tu16((look1_u16tu16(EKFSOCAvrg, cmnm_pct_soc, cmnm_V_ocv, 13) + cdmv_V_deltOCV[i]), cmnm_V_ocv, cmnm_pct_soc, 13);
+    }
+    socd_flg_cellSocDisable = socn_flg_ekfInvalidAvrg || cdmd_flg_deltOCVDisable;
+	
+    cellSocMax = ArrMax(socv_pct_cellSoc,cmnc_num_cellUNum);
+    cellSocMin = ArrMin(socv_pct_cellSoc,cmnc_num_cellUNum);
+	
+    if (cellSocMax > 800)
+    {
+        factor = 100;
+    }
+    else if (cellSocMin < 200)
+    {
+        factor = 0;
+    }
+    else
+    {
+        factor = (uint16_T)(((uint16_T)(((uint32_T)(cellSocMin - 200) << 6) / (800 - (cellSocMax - cellSocMin) - 200)) * 25U) >> 4);
+    }
+    socd_pct_cellBattSoc = (uint16_T)(((1 - (real_T)(factor * 0.01)) * (real_T)(cellSocMin * 0.1) + (real_T)(factor * 0.01) * (real_T)(cellSocMax * 0.1)) * 10);
+    
+*/
+    //======================================================================
+    ////////////////////////AhSOC//////////////////////////////////////////
+    //======================================================================
+    if (socd_flg_firstRun)
+    {
+        ahDelay = (real_T)(socn_pct_battSocEE * 0.1);
+    }
+    else
+    {
+        ahDelay = ahDelay + battcurr / (real_T)(cmnc_Q_ratedCp * 0.1) / 36.0;//cmnc_Q_ratedCp
+    }
+    ahSoc = (int16_T)(ahDelay * 10);
+	
+	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,2);
+    if (socn_flg_ekfDisable)
+    {
+        if (onceFlg_est)
+        {  
+            ahSoc0_est  = ahSoc;
+            ekfSoc0_est = socd_pct_ekfSoc;
+            onceFlg_est = false;
+        }
+        socd_pct_estSoc = (int16_T)(ahSoc - ahSoc0_est + ekfSoc0_est) > 0 ? (uint16_T)(ahSoc - ahSoc0_est + ekfSoc0_est) : 0;
+    }
+    else
+    {
+        onceFlg_est = true;
+        socd_pct_estSoc = socd_pct_ekfSoc;
+    }
+    socd_pct_estSoc = Saturation_u(socd_pct_estSoc, socc_pct_battSocLow, socc_pct_battSocUp);
+    //
+    //printf("6----ahSoc0_est:%d,ekfSoc0_est:%d,socd_pct_estSoc:%d\n",ahSoc0_est,ekfSoc0_est,socd_pct_estSoc);
+	
+    //======================================================================
+    ////////////////////////UtrackSOC//////////////////////////////////////////
+    //======================================================================
+    if (ihd_st_workStat == 2)
+    {
+        lowCntl = 0;
+        lowFlg = false;
+		
+	    socn_V_chrgCCV = look1_i16tu16(sfmd_I_curr,socm_I_chrgCor,socm_V_chrgCor,3); 
+		overFlg = JudgeTimeSystem(1,sfmd_V_cellUMax >= socn_V_chrgCCV,&overCntl,2) || overFlg;
+        fulFlg  = JudgeTimeSystem(1,sfmd_V_cellUMax >= cmnc_V_chrgFul,&fulCntl ,2) || fulFlg;
+        //
+        if (overFlg)
+        {
+            if (onceFlg_utrckOver)
+            {
+                onceFlg_utrckOver = false;
+                ahSoc0_utrckOver = ahSoc;
+                estSoc0_utrckOver = socd_pct_estSoc > socc_pct_chrgCor ? socd_pct_estSoc : socc_pct_chrgCor;
+            }
+            socTemp = (uint16_T)(ahSoc - ahSoc0_utrckOver + estSoc0_utrckOver);
+        }
+        else
+        {
+            onceFlg_utrckOver = true;
+            socTemp = socd_pct_estSoc > socc_pct_chrgCor ? socc_pct_chrgCor : socd_pct_estSoc;
+        }
+        //
+        socn_pct_utrackSoc = Soc_Delay + (socTemp > Soc_Delay ? (socTemp - Soc_Delay) : 0);
+        Soc_Delay = socn_pct_utrackSoc;
+        
+        if (fulFlg)
+        {
+            socn_pct_utrackSoc = socc_pct_battSocUp;
+        }
+        else
+        {
+            socn_pct_utrackSoc = socn_pct_utrackSoc > (socc_pct_battSocUp - 1) ? (socc_pct_battSocUp - 1) : socn_pct_utrackSoc;
+        }
+        
+       // printf("7----overCntl:%d,overFlg:%d,fulCntl:%d,fulFlg:%d,ahSoc0_utrckOver:%d,estSoc0_utrckOver:%d,socn_pct_utrackSoc:%d,socTemp:%d\n",overCntl,overFlg,fulCntl,fulFlg,ahSoc0_utrckOver,estSoc0_utrckOver,socn_pct_utrackSoc,socTemp);
+    }
+    else
+    {
+        Soc_Delay = 0;
+        overCntl = 0;
+        overFlg = false;
+        fulFlg = false;
+        fulCntl = 0;
+		if (!pimv_flg_inval[sfmd_idx_cellUMin])
+		{
+		    socn_V_disChrgCCV = look1_i16tu16(sfmd_I_curr,socm_I_disChrgCor,socm_V_disChrgCor,3) + (uint16_T)(sfmd_I_curr * (pimv_R_cellOhm[sfmd_idx_cellUMin]) * 0.001 * 0.1);
+		}
+		else
+		{
+		    socn_V_disChrgCCV = look1_i16tu16(sfmd_I_curr,socm_I_disChrgCor,socm_V_disChrgCor,3);
+		}
+		lowFlg = JudgeTimeSystem(1,sfmd_V_cellUMin <= socn_V_disChrgCCV,&lowCntl,2) || lowFlg;
+        //
+        if (lowFlg)
+        {
+            if (onceFlg_utrckLow)
+            {
+                onceFlg_utrckLow = false;
+                ahSoc0_utrckLow  = ahSoc;
+                estSoc0_utrckLow = socc_pct_disChrgCor;
+            }
+            socn_pct_utrackSoc = (int16_T)(ahSoc - ahSoc0_utrckLow + estSoc0_utrckLow) > 0 ? (uint16_T)(ahSoc - ahSoc0_utrckLow + estSoc0_utrckLow) : 0;
+        }
+        else 
+        {
+            onceFlg_utrckLow = true;
+            socn_pct_utrackSoc = socd_pct_estSoc < socc_pct_disChrgCor ? socc_pct_disChrgCor : socd_pct_estSoc;
+        }
+		
+        //printf("8----lowCntl:%d,lowFlg:%d,ahSoc0_utrckLow:%d,estSoc0_utrckLow:%d,socn_pct_utrackSoc:%d\n",lowCntl,lowFlg,ahSoc0_utrckLow,estSoc0_utrckLow,socn_pct_utrackSoc);
+    }
+	socd_pct_battSoc = Saturation_u(socn_pct_utrackSoc, socc_pct_battSocLow, socc_pct_battSocUp);
+    socd_pct_battSocEo = socd_pct_battSoc;
+
+    
+    //===============================================================================================================================================================
+    ////////////////////////////////////////////////BCUSOC///////////////////////////////////////////////////////////////////////////////////////////////////////////
+    //=============================================================================================================================================================== 
+    Flg = (socd_flg_firstRun || (socn_st_workStat_Delay == 2 && ihd_st_workStat != 2) || (socn_st_workStat_Delay != 2 && ihd_st_workStat == 2) ||
+          ((int16_T)(socd_pct_battSoc  - socn_pct_battSoc_Delay) > 5 || (int16_T)(socd_pct_battSoc - socn_pct_battSoc_Delay) < -5) ||
+          JudgeTimeSystem(1,sfmd_I_curr < 10 && sfmd_I_curr > -10,&statCntl ,3));
+	
+    socn_st_workStat_Delay = ihd_st_workStat;
+    socn_pct_battSoc_Delay = socd_pct_battSoc;
+    
+    //
+    if (Flg)
+    {
+        socn_pct_battSoc0 = socd_pct_battSoc;
+        if (socd_flg_firstRun)
+        {
+            socn_pct_bcuSoc0 = socn_pct_bcuSocEE;
+        }
+        else
+        {
+            socn_pct_bcuSoc0 = socd_pct_bcuSoc;
+        }
+    }
+    
+    //
+    if (ihd_st_workStat == 2)
+    {
+        delSOC = socn_pct_battSoc0 > socn_pct_bcuSoc0 ? (socn_pct_battSoc0 - socn_pct_bcuSoc0) : (socn_pct_bcuSoc0 - socn_pct_battSoc0);
+        coinSoc = (socn_pct_battSoc0 > socn_pct_bcuSoc0 ? socn_pct_battSoc0 : socn_pct_bcuSoc0) + (delSOC > 50 ? 50 : delSOC);
+        
+        x[0] = socn_pct_battSoc0 > socc_pct_battSocUp - 2 ? socc_pct_battSocUp - 2 : socn_pct_battSoc0;
+        x[1] = coinSoc > socc_pct_battSocUp - 1 ? socc_pct_battSocUp - 1: (uint16_T)coinSoc;
+        x[2] = socc_pct_battSocUp;
+        
+        y[0] = socn_pct_bcuSoc0 > socc_pct_battSocUp - 2 ? socc_pct_battSocUp - 2 : socn_pct_bcuSoc0;;
+        y[1] = coinSoc > socc_pct_battSocUp - 1 ? socc_pct_battSocUp - 1: (uint16_T)coinSoc;
+        y[2] = socc_pct_battSocUp;
+        bcuSoc = look1_u16tu16(socd_pct_battSoc, x, y,3);
+        
+        //
+        if (onceFlg_chrg)
+        {
+            onceFlg_chrg = false;
+            onceFlg_dischrg = true;
+            socd_pct_bcuSoc = bcuSoc;
+        }
+		
+        socd_pct_bcuSoc = DataFilt(bcuSoc, &socd_pct_bcuSoc, 1);
+        
+        //
+        if (fulFlg)
+        {
+            socd_pct_bcuSoc = socc_pct_battSocUp;
+        }
+        else
+        {
+            socd_pct_bcuSoc = socd_pct_bcuSoc > (socc_pct_battSocUp - 1) ? (socc_pct_battSocUp - 1) : socd_pct_bcuSoc;
+        }
+       //printf("10-----x:[%d-%d-%d],y:[%d-%d-%d],battSOC:%d,bcusoc:%d,socd_pct_bcuSoc:%d\n",x[0],x[1],x[2],y[0],y[1],y[2],socd_pct_battSoc,bcuSoc,socd_pct_bcuSoc);
+    }
+    else
+    {
+        //
+        delSOC = socn_pct_battSoc0 > socn_pct_bcuSoc0 ? (socn_pct_battSoc0 - socn_pct_bcuSoc0) : (socn_pct_bcuSoc0 - socn_pct_battSoc0);
+        coinSoc = (int16_T)((socn_pct_battSoc0 < socn_pct_bcuSoc0 ? socn_pct_battSoc0 : socn_pct_bcuSoc0) - (delSOC > 50 ? 50 : delSOC));
+        
+        x[0] = socc_pct_battSocLow;
+        x[1] = coinSoc < socc_pct_battSocLow + 1 ? socc_pct_battSocLow + 1 : (uint16_T)coinSoc;
+        x[2] = socn_pct_battSoc0 < socc_pct_battSocLow + 2 ? socc_pct_battSocLow + 2 : (uint16_T)socn_pct_battSoc0;
+		
+        y[0] = socc_pct_battSocLow;
+        y[1] = coinSoc < socc_pct_battSocLow + 1 ? socc_pct_battSocLow + 1 : (uint16_T)coinSoc;
+        y[2] = socn_pct_bcuSoc0 < socc_pct_battSocLow + 2 ? socc_pct_battSocLow + 2 : (uint16_T)socn_pct_bcuSoc0;
+        bcuSoc = look1_u16tu16(socd_pct_battSoc, x, y,3);
+        
+        //
+        if (onceFlg_dischrg)
+        {
+            onceFlg_chrg = true;
+            onceFlg_dischrg = false;
+            socd_pct_bcuSoc = bcuSoc;
+        }
+		
+        socd_pct_bcuSoc = DataFilt(bcuSoc, &socd_pct_bcuSoc, 1);
+		
+        //printf("11-----x:[%d-%d-%d],y:[%d-%d-%d],bcusoc:%d,socd_pct_bcuSoc:%d\n",x[0],x[1],x[2],y[0],y[1],y[2],bcuSoc,socd_pct_bcuSoc);
+    }
+	socd_pct_bcuSoc = Saturation_u(socd_pct_bcuSoc, socc_pct_battSocLow, socc_pct_battSocUp);
+    socd_pct_bcuSocEo = socd_pct_bcuSoc;
+
+	//=======================================VCUSOC========================================================================================
+	
+    socd_pct_vcuSoc =  (uint16_T)((uint32_T)((socd_pct_bcuSoc - socc_pct_battSocLow) * 1000) / (socc_pct_battSocUp - socc_pct_battSocLow)); 
+	
+    //================================================================================================
+    //------------------EEsave-------------------------------------------=============================
+    //================================================================================================
+    if ((int16_T)(socd_pct_battSoc - socn_pct_battSoc_save) > 10 || (int16_T)(socd_pct_battSoc - socn_pct_battSoc_save) < -10 || (int16_T)(socd_pct_bcuSoc - socn_pct_bcuSoc_save) > 10 || (int16_T)(socd_pct_bcuSoc - socn_pct_bcuSoc_save) < -10 )
+    {
+        socd_flg_EEsave = 1;
+        socn_pct_battSoc_save = socd_pct_battSoc;
+	    socn_pct_bcuSoc_save  = socd_pct_bcuSoc;
+    }
+    else
+    {
+        socd_flg_EEsave = 0;
+    }
+
+	
+    socd_flg_firstRun = false;
+
+	//printf("\n");
+}
+
+
+
+//===================================================================================================================
+//----------------------------function-------------------------------------------------------------------------------
+//===================================================================================================================
+real_T docvmath(real_T soc)
+{
+    real_T docv;
+    docv = ((((((-1.0936E-13 * pow(soc, 7.0) +3.9249E-11 * pow(soc, 6.0)) +
+            -5.5776E-9 * pow(soc, 5.0)) + 3.996E-7 * pow(soc, 4.0)) +
+            -1.5332E-5 * pow(soc, 3.0)) +soc * soc * 0.0003192) +
+           -0.00371 * soc) +0.02732;
+    return docv;
+}
+
+////
+
+//-------------------------------------------------------------------------
+
+

+ 12 - 0
code/app/bms/SOC.h

@@ -0,0 +1,12 @@
+
+#include <math.h>
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+#include "AppFuncLib.h"
+extern void SOC_Init(void);
+extern void SOC(void);
+//
+extern real_T docvmath(real_T soc );
+
+

+ 42 - 0
code/app/bms/SOE.c

@@ -0,0 +1,42 @@
+#include "SOE.h"
+
+void SOE_Init(void)
+{
+    soed_flg_firstRun = true;
+}
+//-------------------------------------------------------------------------
+void SOE(void)
+{
+    uint32_T soen_V_battOcv;
+    uint16_T i;
+
+	
+	// 满电能量
+    if(soed_flg_firstRun)
+    {
+        soen_V_battOcv = 0;
+        for(i = socc_pct_battSocUp ;i >= socc_pct_battSocLow + 1;i--)
+        {
+            soen_V_battOcv = soen_V_battOcv + look1_u16tu16(i, cmnm_pct_soc, cmnm_V_ocv, 13) * cmnc_num_cellUNum;
+        }
+        soed_E_fullEng = (uint16_T) ( (real_T)(soen_V_battOcv * 0.001) * (real_T)(cmnc_Q_ratedCp * 0.1) * (real_T)(sohd_pct_bcuSoh * 0.1 * 0.01)/1000);
+    }
+	//当前SOC的剩余能量
+    if(socd_pct_battSoc > socc_pct_battSocLow)
+    {
+        soen_V_battOcv = 0;
+        for(i = socd_pct_battSoc;i >= socc_pct_battSocLow + 1;i--)
+        {
+            soen_V_battOcv = soen_V_battOcv + look1_u16tu16(i, cmnm_pct_soc, cmnm_V_ocv, 13)  * cmnc_num_cellUNum;
+        }
+        soed_E_nowEng = (uint16_T) ( (real_T)(soen_V_battOcv * 0.001) * (real_T)(cmnc_Q_ratedCp * 0.1) * (real_T)(sohd_pct_bcuSoh * 0.1 * 0.01) /1000);
+    }
+    else
+    {
+        soed_E_nowEng = 0;
+    }
+    soed_pct_nowStat = (uint16_T)((uint32_T)(soed_E_nowEng * 1000)/soed_E_fullEng);
+    soed_flg_firstRun = false;   
+}
+
+

+ 7 - 0
code/app/bms/SOE.h

@@ -0,0 +1,7 @@
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+
+extern void SOE_Init(void);
+extern void SOE(void);
+

+ 226 - 0
code/app/bms/SOH.c

@@ -0,0 +1,226 @@
+#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;
+}

+ 8 - 0
code/app/bms/SOH.h

@@ -0,0 +1,8 @@
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+
+extern void SOH_Init(void);
+extern void SOH(void);
+//
+

+ 143 - 0
code/app/bms/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);
+    sopn_V_up = (real_T)sfmd_V_cellUAvrg * 0.001 - ocv - (real_T)sfmd_I_curr * 0.1 * Ro;
+    //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);
+	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);
+    
+    
+    //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;
+}
+

+ 9 - 0
code/app/bms/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);
+

+ 65 - 0
code/app/bms/SOR.c

@@ -0,0 +1,65 @@
+#include "SOR.h"
+
+void SOR_Init(void)
+{
+    sord_flg_firstRun = true;
+}
+//-------------------------------------------------------------------------
+void SOR(void)
+{
+    static uint16_T sorn_R_cellEE[cmnc_num_cellUNumMax];
+    static uint16_T sorn_R_cellEEArr[5][cmnc_num_cellUNumMax];
+    uint16_T sorn_ohm_cellRSum[cmnc_num_cellUNumMax];
+	static uint16_T sorn_V_cellU[cmnc_num_cellUNumMax];
+	static uint8_T sorn_num_ctn;
+	static int16_T sorn_I_curr;
+    uint16_T i;
+    uint16_T j;
+	
+    //
+    if(sord_flg_firstRun)
+    {
+        sorn_num_ctn = 0;
+        sorn_I_curr = sfmd_I_curr;
+        memcpy(sorn_V_cellU,sfmv_V_cellU, sizeof(sfmv_V_cellU));
+    }
+    if(sord_flg_firstRun)
+    {
+        if(ArrMax(sorv_R_cellEi, cmnc_num_cellUNum) > 65000)
+        {
+            memset(sorn_R_cellEE,0, sizeof(sorn_R_cellEE));
+        }
+        else
+        {
+            memcpy(sorn_R_cellEE,sorv_R_cellEi, sizeof(sorv_R_cellEi));
+        }
+    }
+
+    
+    if(socd_pct_battSoc >= 550 && socd_pct_battSoc <= 700 && sorn_num_ctn < 5)
+    {
+        if(sfmd_I_curr - sorn_I_curr > 200 || sfmd_I_curr - sorn_I_curr < -200)
+        {
+            for(i = 0;i < cmnc_num_cellUNum;i++)
+            {
+                sorn_R_cellEEArr[sorn_num_ctn][i] = (uint16_T)( ((real_T)(sorn_V_cellU[i] - sfmv_V_cellU[i]) * 0.001) / ((real_T)(sorn_I_curr - sfmd_I_curr) * 0.1) * 1000000 );
+            }
+            sorn_num_ctn = sorn_num_ctn + 1;
+            memset(sorn_ohm_cellRSum,0, sizeof(sorn_ohm_cellRSum));
+            for(i = 0;i < cmnc_num_cellUNum;i++)
+            {
+                for(j = 0;j < sorn_num_ctn;j++)
+                {
+                    sorn_ohm_cellRSum[i] =  sorn_ohm_cellRSum[i] + sorn_R_cellEEArr[j][i];
+                }
+                sorn_R_cellEE[i] = sorn_ohm_cellRSum[i]/sorn_num_ctn;
+            }
+        } 
+    }
+	memcpy(sorv_R_cell,sorn_R_cellEE, sizeof(sorn_R_cellEE));
+    memcpy(sorv_R_cellEo,sorn_R_cellEE, sizeof(sorn_R_cellEE));
+	
+	sorn_I_curr = sfmd_I_curr;
+    memcpy(sorn_V_cellU,sfmv_V_cellU, sizeof(sfmv_V_cellU));
+    sord_flg_firstRun = false;
+}

+ 6 - 0
code/app/bms/SOR.h

@@ -0,0 +1,6 @@
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+extern void SOR_Init(void);
+extern void SOR(void);
+

+ 59 - 0
code/app/bms/SPM.c

@@ -0,0 +1,59 @@
+#include "SPM.h"
+
+void SPM_Init(void)
+{
+  SOH_Init();
+  BLC_Init();
+  CDM_Init();
+  SOC_Init();
+  PIM_Init();
+  SOE_Init();
+  SOR_Init();
+  SOP_Init();
+  spmd_flg_firstRun = true;
+}
+
+void SPM(void)
+{
+  static uint16_T spmn_num_cellNr;
+  uint8_T Feq = 30;
+  if (spmd_flg_firstRun)
+  {
+    spmn_num_cellNr = 0;
+    cand_idx_cellNr = 1;
+  }
+  spmn_num_cellNr = spmn_num_cellNr + 1;
+  if (spmn_num_cellNr % Feq == 0)
+  {
+    cand_idx_cellNr ++;
+  }
+  else if (spmn_num_cellNr > 60000)
+  {
+    spmn_num_cellNr = 0;
+  }
+  if (cand_idx_cellNr > cmnc_num_cellUNum)
+  {
+    cand_idx_cellNr = 1;
+  }
+  //调用SOX算法
+  SOH();
+  BLC();
+  if (ihd_flg_urtRecFlg && sfmd_V_cellUMin != 0)
+  {
+      CDM();
+	  SOC();
+	  PIM();
+	  SOE();
+	  SOR();
+	  SOP();
+  }
+  // 循环发送数组
+  cand_Q_cellCap = sohv_Q_cellCapArrEo[cand_idx_cellNr-1];
+  cand_V_chrgStartStat = sohv_V_chrgStartStatEo[cand_idx_cellNr-1];
+  cand_Q_blcReqCp   = blcv_Q_reqCpEo[cand_idx_cellNr-1];
+  cand_Q_blcTotalCp = blcv_Q_totalCpEo[cand_idx_cellNr-1];
+  
+  spmd_flg_firstRun = false;
+}
+
+

+ 16 - 0
code/app/bms/SPM.h

@@ -0,0 +1,16 @@
+#include "rtwtypes.h"
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "SOH.h"
+#include "SOC.h"
+#include "BLC.h"
+#include "CDM.h"
+#include "SOE.h"
+#include "SOR.h"
+#include "PIM.h"
+#include "SOP.h"
+
+extern void SPM_Init(void);
+extern void SPM(void);
+
+

+ 60 - 0
code/app/bms/TMS.c

@@ -0,0 +1,60 @@
+
+#include "TMS.h"
+
+void TMS_Init(void)
+{
+    tmsd_flg_firstRun = true;
+}
+
+void TMS(void)
+{
+    static uint16_T TminLowNr;
+    static uint16_T TminOverNr;
+    static uint16_T TmaxOverNr;
+
+    //初始值
+    if (tmsd_flg_firstRun)
+    {
+        tmsd_st_heatAct = 0;
+        TminLowNr = 0;
+        TminOverNr = 0;
+        TmaxOverNr = 0;
+    }
+
+    //================================温度判定 开关热管理状态===============================
+    if (tmsd_st_heatAct == 0)
+    {
+        if (JudgeTimeSystem(1, sfmd_T_modTMin < tmsc_T_openThr, &TminLowNr,5) && ((socd_pct_battSoc > tmsc_pct_socOpen && ihd_st_disChrgMosControl == 1 && ihd_st_workStat !=0) || ihd_st_chrgConnect == 1))
+        {
+            tmsd_st_heatAct = 1;
+        }
+    }
+    else
+    {
+        if (JudgeTimeSystem(1, sfmd_T_modTMin >= tmsc_T_closeMinThr, &TminOverNr,5) || JudgeTimeSystem(1, sfmd_T_modTMax >= tmsc_T_closeMaxThr, &TmaxOverNr,5) || (ihd_st_chrgConnect == 0 && (socd_pct_battSoc < tmsc_pct_socClos || ihd_st_disChrgMosControl == 0)))
+        {
+            tmsd_st_heatAct = 0;
+        }
+    }
+    //*/
+	//printf("tmsd_st_heatAct:%d,Tmin:%d,Tmax:%d,ihd_st_workStat:%d,SOC:%d\n\n",tmsd_st_heatAct,sfmd_T_modTMin,sfmd_T_modTMax,ihd_st_workStat,socd_pct_battSoc);
+ 
+    /*/因故障关闭热管理
+    if (((sfmd_st_fltAct >> 4) & 0x01) == 1)
+    {
+        tmsd_st_heatAct = 0;
+    }
+    */
+
+    //强制控制加热回路
+    if (ihd_st_heatForceControl == 1)
+    {
+        tmsd_st_heatAct = 1;
+    }
+    if (ihd_st_heatForceControl == 2)
+    {
+        tmsd_st_heatAct = 0;
+    }
+
+    tmsd_flg_firstRun = false;
+}

+ 6 - 0
code/app/bms/TMS.h

@@ -0,0 +1,6 @@
+#include "rtwtypes.h"
+#include "BCUCal.h"
+#include "BCUDisp.h"
+#include "funlib.h"
+extern void TMS_Init(void);
+extern void TMS(void);

+ 2 - 0
code/app/bms/funlib.c

@@ -0,0 +1,2 @@
+#include "funlib.h"
+#define PI 3.14159265358979

+ 4 - 0
code/app/bms/funlib.h

@@ -0,0 +1,4 @@
+#include "rtwtypes.h"
+#include <math.h>
+#include "string.h"
+#include "AppFuncLib.h"

+ 22 - 31
code/app/lib/rtwtypes.h → code/app/bms/rtwtypes.h

@@ -14,11 +14,11 @@
 /* Logical type definitions */
 #if (!defined(__cplusplus))
 #ifndef false
-#define false (0U)
+#define false                          (0U)
 #endif
 
 #ifndef true
-#define true (1U)
+#define true                           (1U)
 #endif
 #endif
 
@@ -67,68 +67,59 @@ typedef char_T byte_T;
  *===========================================================================*/
 #define CREAL_T
 
-typedef struct
-{
+typedef struct {
   real32_T re;
   real32_T im;
 } creal32_T;
 
-typedef struct
-{
+typedef struct {
   real64_T re;
   real64_T im;
 } creal64_T;
 
-typedef struct
-{
+typedef struct {
   real_T re;
   real_T im;
 } creal_T;
 
 #define CINT8_T
 
-typedef struct
-{
+typedef struct {
   int8_T re;
   int8_T im;
 } cint8_T;
 
 #define CUINT8_T
 
-typedef struct
-{
+typedef struct {
   uint8_T re;
   uint8_T im;
 } cuint8_T;
 
 #define CINT16_T
 
-typedef struct
-{
+typedef struct {
   int16_T re;
   int16_T im;
 } cint16_T;
 
 #define CUINT16_T
 
-typedef struct
-{
+typedef struct {
   uint16_T re;
   uint16_T im;
 } cuint16_T;
 
 #define CINT32_T
 
-typedef struct
-{
+typedef struct {
   int32_T re;
   int32_T im;
 } cint32_T;
 
 #define CUINT32_T
 
-typedef struct
-{
+typedef struct {
   uint32_T re;
   uint32_T im;
 } cuint32_T;
@@ -138,20 +129,20 @@ typedef struct
  *   int8_T, int16_T, int32_T     - signed 8, 16, or 32 bit integers     *
  *   uint8_T, uint16_T, uint32_T  - unsigned 8, 16, or 32 bit integers   *
  *=======================================================================*/
-#define MAX_int8_T ((int8_T)(127))
-#define MIN_int8_T ((int8_T)(-128))
-#define MAX_uint8_T ((uint8_T)(255U))
-#define MAX_int16_T ((int16_T)(32767))
-#define MIN_int16_T ((int16_T)(-32768))
-#define MAX_uint16_T ((uint16_T)(65535U))
-#define MAX_int32_T ((int32_T)(2147483647))
-#define MIN_int32_T ((int32_T)(-2147483647 - 1))
-#define MAX_uint32_T ((uint32_T)(0xFFFFFFFFU))
+#define MAX_int8_T                     ((int8_T)(127))
+#define MIN_int8_T                     ((int8_T)(-128))
+#define MAX_uint8_T                    ((uint8_T)(255U))
+#define MAX_int16_T                    ((int16_T)(32767))
+#define MIN_int16_T                    ((int16_T)(-32768))
+#define MAX_uint16_T                   ((uint16_T)(65535U))
+#define MAX_int32_T                    ((int32_T)(2147483647))
+#define MIN_int32_T                    ((int32_T)(-2147483647-1))
+#define MAX_uint32_T                   ((uint32_T)(0xFFFFFFFFU))
 
 /* Block D-Work pointer type */
-typedef void *pointer_T;
+typedef void * pointer_T;
 
-#endif /* RTWTYPES_H */
+#endif                                 /* RTWTYPES_H */
 
 /*
  * File trailer for generated code.

+ 0 - 29
code/app/lib/AppFuncLib.c

@@ -891,9 +891,6 @@ void fft(real_T *S, uint16_T N, real_T freq, real_T *returnFreq, real_T *returnP
 	creal_T X[SIZE_FFT];
 	creal_T W[SIZE_FFT];
 	real_T Y1[SIZE_FFT];
-
-//	real_T Y2[SIZE_FFT / 2 + 1];
-//	real_T F[SIZE_FFT / 2 + 1];
 	fft_type fft_data[SIZE_FFT / 2 + 1];
     uint16_T i = 0;
     uint16_T j = 0;
@@ -949,32 +946,6 @@ void fft(real_T *S, uint16_T N, real_T freq, real_T *returnFreq, real_T *returnP
     	fft_data[i].freq = freq * i / N;
     }
     // 从大到小 排序
-//    real_T temp;
-//    uint16_T temp_idx;
-//    uint16_T idx[N / 2 + 1];
-//    for (i = 0; i < N / 2 + 1; i++)
-//    {
-//        idx[i] = i;
-//    }
-//
-//    for (j = 0; j < N / 2 + 1; j++) // 比较n-1轮
-//    {
-//        for (k = 0; k < N / 2 - j; k++) // 每轮比较n-1-i次,
-//        {
-//
-//            if (Y2[k] < Y2[k + 1]) // 从大到小
-//            {
-//                temp = Y2[k];
-//                Y2[k] = Y2[k + 1];
-//                Y2[k + 1] = temp;
-//
-//                temp_idx = idx[k];
-//                idx[k] = idx[k + 1];
-//                idx[k + 1] = temp_idx;
-//            }
-//        }
-//    }
-//    // 输出前5个
     qsort(fft_data,sizeof(fft_data) / sizeof(fft_data[0]),sizeof(fft_data[0]),fft_cmp);
     for (i = 0; i < 5; i++)
     {

+ 18 - 9
code/app/lib/AppFuncLib.h

@@ -10,23 +10,32 @@
 
 #ifndef APPFUNCLIB_H_
 #define APPFUNCLIB_H_
-#include "hal_adapter.h"
 #include <stdarg.h>
 #include "stdio.h"
 #include <math.h>
+#include "rtwtypes.h"
 #ifndef va_copy
 #define va_copy(dst, src) memcpy(&(dst), &(src), sizeof(va_list))
 #endif
-uint16 GetErrorNum(uint16 *ErrorArray, uint8 Errorlen);
-uint8 PutErrorNum(uint16 *ErrorArray, uint8 Errorlen, uint16 ErrorNum);
-uint16 ATstrdel(char *str);
-uint16 mstrlen(const char *s);
+#ifndef min
+#define min(A, B) ((A) <= (B) ? (A) : (B))
+#endif
+#ifndef max
+#define max(A, B) ((A) < (B) ? (B) : (A))
+#endif
+#define getbit(x, y) ((x) >> (y)&1) // 获取x的第y位的数值
+#define setbit(x, y) x |= (1 << y)  // x的第y位置1
+#define clrbit(x, y) x &= ~(1 << y) // x的第y位置0
+uint16_t GetErrorNum(uint16_t *ErrorArray, uint8_t Errorlen);
+uint8_t PutErrorNum(uint16_t *ErrorArray, uint8_t Errorlen, uint16_t ErrorNum);
+uint16_t ATstrdel(char *str);
+uint16_t mstrlen(const char *s);
 int mstrncmp(const char *s1, const char *s2, int n);
 unsigned char HexToChar(unsigned char bHex);
 unsigned char CharToHex(unsigned char bChar);
-uint8 AtStrCompare(const char *a, const char *b);
+uint8_t AtStrCompare(const char *a, const char *b);
 unsigned short CRC16_Modbus(unsigned char *pdata, int len);
-uint8 bcc_chk(uint8 *data, uint16 length);
+uint8_t bcc_chk(uint8_t *data, uint16_t length);
 char *Myitoa(int value, char *result, int base);
 // 整数转字符串
 int _itoa(int num, char buf[32]);
@@ -42,7 +51,7 @@ int __ftoa(double val, char buf[32], int eps);
 // 替代sprintf
 int _sprintf(char *dst, const char *format, ...);
 // 串口校验
-uint16 crc_chk(uint8 *data, uint8 length);
+uint16_t crc_chk(uint8_t *data, uint8_t length);
 
 /*********************************************************************************************/
 #define SIZE_FFT 64
@@ -51,7 +60,7 @@ typedef struct _fft_Freq
 	real_T freq;
 	real_T amp;
 }fft_type;
-extern uint16_T ArrMax(uint16_T *Data, uint16_T m);
+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);

+ 0 - 2
code/hal/Hal_Wdg.c

@@ -52,13 +52,11 @@ static void HAL_1msPeriod(void)
 void vTimer1msCallback(TimerHandle_t pxTimer)
 {
 	uint32 ulTimerID;
-//	Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_ON);
 	ulTimerID = (uint32)pvTimerGetTimerID(pxTimer);
 	if(ulTimerID==0)
 	{
 		HAL_1msPeriod();
 	}
-//	Dio_WriteChannel(DioConf_DioChannel_PTE8_GPIO_OUT_MCU_LED4, STD_OFF);
 }
 
 

+ 17 - 236
code/hal/hal_adapter.c

@@ -12,7 +12,6 @@
 /********************************/
 #include "Icu.h"
 #include "Gpt.h"
-
 uint8_t __attribute__((section(".non_cacheable_data"))) RX_Buffer[3][BUFFER_SIZE];
 uint32_t bufferIdx[3] = {0};
 volatile uint32 VarNotification_0 = 0;
@@ -58,30 +57,6 @@ sint8 AtcmdDelayRecvFunc(uint8 recvChannel,char *ResultStrPtr,uint16 delayTime)
 	}
 	return outValue;
 }
-#if 0
-	uint16 myPrintf(const char *fmt, ...)
-	{
-		int n;
-		uint8 databuffer[512]={0};
-		va_list args;
-		va_start(args, fmt);
-		n = vsprintf((char *)databuffer, fmt, args);
-		va_end(args);
-	    if( (printfRingBuffer.bw + n) <= printfRingBuffer.length  )
-	    {
-	        memcpy(printfRingBuffer.source + printfRingBuffer.bw, databuffer, n);
-	        UART_Send_Data(UART_LPUART0, printfRingBuffer.source + printfRingBuffer.bw, n, 10);
-	        printfRingBuffer.bw = printfRingBuffer.bw + n;
-	    }
-	    else
-	    {
-	    	printfRingBuffer.bw = 0;
-	    	memcpy(printfRingBuffer.source + printfRingBuffer.bw, databuffer, n);
-	    	UART_Send_Data(UART_LPUART0, printfRingBuffer.source + printfRingBuffer.bw, n, 10);
-	    }
-		return n;
-	}
-#endif
 void create_ringBuffer(ringbuffer_t *ringBuf, uint8_t *buf, uint32_t buf_len)
 {
     ringBuf->br         = 0;
@@ -110,28 +85,6 @@ uint32_t write_ringBuffer(uint8_t *buffer, uint16_t size, ringbuffer_t *ringBuf,
     ringBuf->bw = (ringBuf_bw + size + 1) % ringBuf_len;//数据长度不变,起始地址移位1
     ringBuf->btoRead += size;
     *uartDataAddr = (uint32)(ringBuf->source + ringBuf->bw - size - 1);
-/*
-    if(ringBuf->br!=0)
-    {
-        memcpy(ringBuf_source, buffer, size);
-        ringBuf->br = 0;
-    }
-*/
-/*
-    if( (ringBuf_bw + size) <= ringBuf_len  )
-    {
-        memcpy(ringBuf_source + ringBuf_bw, buffer, size);
-    }
-    else
-    {
-        len = ringBuf_len - ringBuf_bw;
-        memcpy(ringBuf_source + ringBuf_bw, buffer, len);
-        memcpy(ringBuf_source, buffer + ringBuf_bw, size - len);
-    }
-    ringBuf->bw = (ringBuf->bw + size) % ringBuf_len;
-    ringBuf->btoRead += size;
-*/
-
     return size;
 }
 uint32_t read_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf)
@@ -143,19 +96,6 @@ uint32_t read_ringBuffer(uint8_t *buffer, uint32_t size, ringbuffer_t *ringBuf)
 
     memcpy(buffer, ringBuf_source, size);
     ringBuf->br = size;
-//    if( (ringBuf_br + size ) <= ringBuf_len )
-//    {
-//        memcpy(buffer, ringBuf_source + ringBuf_br, size);
-//    }
-//    else
-//    {
-//        len = ringBuf_len - ringBuf_br;
-//        memcpy(buffer, ringBuf_source + ringBuf_br, len);
-//        memcpy(buffer + len, ringBuf_source, size - len);
-//    }
-//    ringBuf->br = (ringBuf->br + size) % ringBuf_len;
-//    ringBuf->btoRead -= size;
-
     return size;
 }
 Std_ReturnType UART_Query_Data(uint8 transChannel, uint8 recvChannel, uint8 *txBuffer, uint16 sendLength, uint8 *rxBuffer, uint16 *rxlen, uint32 T_timeout)
@@ -393,181 +333,6 @@ Std_ReturnType UART_Send_Data(uint8 transChannel, const uint8 *txBuffer, uint32
 	 }
 
  }
-//
-//Std_ReturnType UART_Query_Data(uint8 transChannel, uint8 recvChannel, const uint8 *txBuffer, uint32 sendLength, uint8 *rxBuffer, uint16 *rxlen, uint32 T_timeout)
-//{
-//    volatile Std_ReturnType R_Uart_Status;
-//    volatile Std_ReturnType T_Uart_Status;
-//    volatile Uart_StatusType Uart_ReceiveStatus = UART_STATUS_TIMEOUT;
-//    volatile Uart_StatusType Uart_TransmitStatus = UART_STATUS_TIMEOUT;
-//    uint32 T_bytesRemaining;
-//    uint32 R_bytesRemaining;
-//    uint32 timeout = T_timeout;
-//    uint32 retVal = E_NOT_OK;
-//    bufferIdx[recvChannel] = 0;
-//    switch (recvChannel)
-//    {
-//    case 0:
-//        IP_LPUART0->CTRL |= LPUART_CTRL_ILIE(1);
-//        break;
-//    case 1:
-//        IP_LPUART1->CTRL |= LPUART_CTRL_ILIE(1);
-//        break;
-//    case 2:
-//        IP_LPUART2->CTRL |= LPUART_CTRL_ILIE(1);
-//        break;
-//    default:
-//        break;
-//    }
-//    if (txBuffer == NULL || rxBuffer == NULL)
-//    {
-//        return retVal;
-//    }
-//
-//    /* Uart_AsyncSend transmit data */
-//    Uart_SetBuffer(transChannel, txBuffer, sendLength, UART_SEND);
-//    T_Uart_Status = Uart_AsyncSend(transChannel, txBuffer, sendLength);
-//    if (E_OK != T_Uart_Status)
-//    {
-//        Uart_Abort(transChannel, UART_SEND);
-//        return E_NOT_OK;
-//    }
-//    Uart_SetBuffer(recvChannel, &RX_Buffer[recvChannel][0], DMA_SIZE, UART_RECEIVE);
-//    R_Uart_Status = Uart_AsyncReceive(recvChannel, rxBuffer, DMA_SIZE);
-//    if (E_OK != R_Uart_Status)
-//    {
-//        Uart_Abort(recvChannel, UART_RECEIVE);
-//        return E_NOT_OK;
-//    }
-//    /* Check for no on-going transmission */
-//    do
-//    {
-//        if (Uart_TransmitStatus != UART_STATUS_NO_ERROR)
-//        {
-//            Uart_TransmitStatus = Uart_GetStatus(transChannel, &T_bytesRemaining, UART_SEND);
-//        }
-//        if (Uart_ReceiveStatus != UART_STATUS_NO_ERROR)
-//        {
-//            Uart_ReceiveStatus = Uart_GetStatus(recvChannel, &R_bytesRemaining, UART_RECEIVE);
-//        }
-//        vTaskDelay(pdMS_TO_TICKS(1));
-//    } while (((UART_STATUS_NO_ERROR != Uart_TransmitStatus || UART_STATUS_NO_ERROR != Uart_ReceiveStatus) && 0 < --timeout));
-//    if ((UART_STATUS_NO_ERROR != Uart_TransmitStatus))
-//    {
-//        Uart_Abort(transChannel, UART_SEND);
-//        retVal = E_NOT_OK;
-//    }
-//    else
-//    {
-//        retVal = E_OK;
-//    }
-//    if ((UART_STATUS_NO_ERROR != Uart_ReceiveStatus))
-//    {
-//        Uart_Abort(recvChannel, UART_RECEIVE);
-//        *rxlen = bufferIdx[recvChannel];
-//        retVal = E_NOT_OK;
-//    }
-//    else
-//    {
-//        *rxlen = bufferIdx[recvChannel];
-//        retVal = E_OK;
-//    }
-//    return retVal;
-//}
-//
-//Std_ReturnType UART_Send_Data(uint8 transChannel, const uint8 *txBuffer, uint32 sendLength, uint32 T_timeout)
-//{
-//
-//    volatile Std_ReturnType T_Uart_Status;
-//    volatile Uart_StatusType Uart_TransmitStatus = UART_STATUS_TIMEOUT;
-//    uint32 T_bytesRemaining;
-//    uint32 timeout = T_timeout;
-//    uint32 retVal = E_NOT_OK;
-//    if (txBuffer == NULL)
-//    {
-//        return retVal;
-//    }
-//
-//    /* Uart_AsyncSend transmit data */
-//    T_Uart_Status = Uart_AsyncSend(transChannel, txBuffer, sendLength);
-//    if (E_OK != T_Uart_Status)
-//    {
-//        Uart_Abort(transChannel, UART_SEND);
-//        return E_NOT_OK;
-//    }
-//    /* Check for no on-going transmission */
-//    do
-//    {
-//        Uart_TransmitStatus = Uart_GetStatus(transChannel, &T_bytesRemaining, UART_SEND);
-//        vTaskDelay(pdMS_TO_TICKS(1));
-//    } while ((UART_STATUS_NO_ERROR != Uart_TransmitStatus && 0 < --timeout));
-//
-//    if ((UART_STATUS_NO_ERROR != Uart_TransmitStatus))
-//    {
-//        retVal = E_NOT_OK;
-//    }
-//    else
-//    {
-//        retVal = E_OK;
-//    }
-//    return retVal;
-//}
-//
-//Std_ReturnType UART_Receive_Data(uint8 recvChannel, uint8 *rxBuffer, uint16 *rxlen, sint32 T_timeout)
-//{
-//    volatile Std_ReturnType R_Uart_Status = E_NOT_OK;
-//    volatile Uart_StatusType Uart_ReceiveStatus = UART_STATUS_TIMEOUT;
-//    uint32 T_bytesRemaining = 0;
-//    uint32 retVal = E_NOT_OK;
-//    //    uint8 Rx_Buffer[MSG_LEN];
-//    bufferIdx[recvChannel] = 0;
-//    *rxlen = 0;
-//    if (rxBuffer == NULL)
-//    {
-//        return retVal;
-//    }
-//    /* Uart_AsyncReceive transmit data */
-//    switch (recvChannel)
-//    {
-//    case 0:
-//        IP_LPUART0->CTRL |= LPUART_CTRL_ILIE(1);
-//        break;
-//    case 1:
-//        IP_LPUART1->CTRL |= LPUART_CTRL_ILIE(1);
-//        break;
-//    case 2:
-//        IP_LPUART2->CTRL |= LPUART_CTRL_ILIE(1);
-//        break;
-//    default:
-//        break;
-//    }
-//    Uart_SetBuffer(recvChannel, rxBuffer, DMA_SIZE, UART_RECEIVE);
-//    R_Uart_Status = Uart_AsyncReceive(recvChannel, rxBuffer, DMA_SIZE);
-//    if (E_OK != R_Uart_Status)
-//    {
-//        Uart_Abort(recvChannel, UART_RECEIVE);
-//        return E_NOT_OK;
-//    }
-//    /* Check for no on-going transmission */
-//    do
-//    {
-//        Uart_ReceiveStatus = Uart_GetStatus(recvChannel, &T_bytesRemaining, UART_RECEIVE);
-//        vTaskDelay(pdMS_TO_TICKS(1));
-//
-//    } while ((UART_STATUS_NO_ERROR != Uart_ReceiveStatus) && 0 < T_timeout--);
-//    if ((UART_STATUS_NO_ERROR != Uart_ReceiveStatus))
-//    {
-//        Uart_Abort(recvChannel, UART_RECEIVE);
-//        *rxlen = bufferIdx[recvChannel];
-//        retVal = E_NOT_OK;
-//    }
-//    else
-//    {
-//        *rxlen = bufferIdx[recvChannel];
-//        retVal = E_OK;
-//    }
-//    return retVal;
-//}
 extern Lpuart_Uart_Ip_StateStructureType *Lpuart_Uart_Ip_apStateStructuresArray[LPUART_UART_IP_NUMBER_OF_INSTANCES];
 void UART_Callback(uint32 hwInstance, Lpuart_Uart_Ip_EventType event)
 {
@@ -662,7 +427,6 @@ Std_ReturnType CanIf_SendMessage(uint8 ControllerId, Can_Msg_Type CanMsg)
             u8TimeOut--;
         }
     }
-
     if (CanIf_bTxFlag == TRUE)
     {
         retVal = E_OK;
@@ -1207,3 +971,20 @@ void displayResetReasonWithLED(void)
 	Mcu_ResetType bootreason;
 	bootreason = Mcu_GetResetReason();
 }
+#define APPNAME "S32K146_4G"
+#define HARDWARE_VERSION "V1.0.0"
+#define SOFTWARE_VERSION "V0.0.1"
+#include "SEGGER_SYSVIEW.h"
+#include "cm_backtrace.h"
+void debugInit(void)
+{
+#ifdef SEGGER_SYSTEMVIEW
+	SEGGER_SYSVIEW_Conf();
+	SEGGER_SYSVIEW_Start();
+#endif
+#ifdef SEGGER_RTT_PRINTF
+	SEGGER_RTT_Init();
+	cm_backtrace_init(APPNAME, HARDWARE_VERSION, SOFTWARE_VERSION);
+	SEGGER_RTT_printf("boot\n");
+#endif
+}

+ 2 - 10
code/hal/hal_adapter.h

@@ -56,15 +56,7 @@ typedef signed long INT32;
 
 #define CAN0 0
 #define CAN1 1
-#ifndef min
-#define min(A, B) ((A) <= (B) ? (A) : (B))
-#endif
-#ifndef max
-#define max(A, B) ((A) < (B) ? (B) : (A))
-#endif
-#define getbit(x, y) ((x) >> (y)&1) // 获取x的第y位的数值
-#define setbit(x, y) x |= (1 << y)  // x的第y位置1
-#define clrbit(x, y) x &= ~(1 << y) // x的第y位置0
+
 #define UART_LPUART0 0
 #define UART_LPUART1 1
 #define UART_LPUART2 2
@@ -259,5 +251,5 @@ void SystemDeinit(void);
 void MCUSleep(void);
 void MCUEnterSleep(void);
 void displayResetReasonWithLED(void);
-
+void debugInit(void);
 #endif /* HAL_ADAPTER_H_ */

+ 8 - 20
code/main.c

@@ -55,41 +55,29 @@
 #include <string.h>
 #include "hal_adapter.h"
 #include "Lpuart_Uart_Ip.h"
-
 #include "AppTaskMain.h"
 #include "AppTaskUart0.h"
 #include "AppTaskUart1.h"
 #include "AppTaskCan.h"
 #include "AppTaskGps.h"
+#include "BCU.h"
 #include "Hal_Fls.h"
-#include "SEGGER_SYSVIEW.h"
-#include "cm_backtrace.h"
-#define APPNAME "S32K146_4G"
-#define HARDWARE_VERSION "V1.0.0"
-#define SOFTWARE_VERSION "V0.0.1"
 int main(void)
 {
 	volatile int exit_code = 0;
+	taskENTER_CRITICAL();//以下为临界区,不允许中断打断
 	coreInit();
 	SystemModulesInit();
-	displayResetReasonWithLED();
-#ifdef SEGGER_SYSTEMVIEW
-	SEGGER_SYSVIEW_Conf();
-	SEGGER_SYSVIEW_Start();
-#endif
-#ifdef SEGGER_RTT_PRINTF
-	SEGGER_RTT_Init();
-	cm_backtrace_init(APPNAME, HARDWARE_VERSION, SOFTWARE_VERSION);
-	SEGGER_RTT_printf("boot\n");
-#endif
+	debugInit();
 	UartInit();
-	xTaskCreate(MainTask, (const char *const)"MainTask", 4096, (void *)0, main_TASK_PRIORITY + 6, MainTask_Handle);
+	xTaskCreate(MainTask, (const char *const)"MainTask", 128, (void *)0, main_TASK_PRIORITY + 6, &MainTask_Handle);
 	//xTaskCreate(Uart0Task, (const char *const)"Uart0_Bms_Task", 512, (void *)0, main_TASK_PRIORITY + 2, Uart0Task_Handle);
-	xTaskCreate(CanTask, (const char *const)"CanTask", 512, (void *)0, main_TASK_PRIORITY + 2, &CanTask_Handle);
+	xTaskCreate(CanTask, (const char *const)"CanTask", 256, (void *)0, main_TASK_PRIORITY + 2, &CanTask_Handle);
 	xTaskCreate(GpsTask, (const char *const)"GpsTask", 2048, (void *)0, main_TASK_PRIORITY + 1, &GpsTask_Handle);
-	xTaskCreate(Uart_4G_Task, (const char *const)"Uart_4G_Task", 2048, (void *)0, main_TASK_PRIORITY + 0, &Uart_4G_Task_Handle);
+	xTaskCreate(Uart_4G_Task, (const char *const)"Uart_4G_Task", 1024, (void *)0, main_TASK_PRIORITY + 0, &Uart_4G_Task_Handle);
+	xTaskCreate(BCU,(const char *const)"Bcu_Task",2048,(void *)0,main_TASK_PRIORITY + 3,&BcuTask_Handle);
 	vTaskStartScheduler();
-
+	taskEXIT_CRITICAL();
 	for (;;)
 	{
 		if (exit_code != 0)