#include "protect_check.h" #include "math_tools.h" #include "gpio.h" #include "hall_sensor.h" #include "eeprom_24c02.h" #include "log_save.h" /*****************************全局变量定义*******************************/ //过流保护检测参数 FlagStatus MC_Protect_OverCurrentTrig_Flag = RESET; /******************************局部函数定义******************************/ //低压保护检测 void MC_Protect_UnderVoltage_Process(uint16_t BusVoltage, uint8_t DesignVoltage, uint16_t UV_TH, MC_ErrorCode_Struct_t* p_MC_ErrorCode) { static uint32_t uvTimeCnt = 0; static uint32_t uvFaultTimeCnt = 0; uint16_t UV_Voltage = 0; //根据额定电压更新保护阈值 switch(DesignVoltage) { case 24: { UV_Voltage = UV_TH * 7;//低压保护时,电芯电压为3100mV break; } case 36: { UV_Voltage = UV_TH * 10;//低压保护时,电芯电压为3100mV break; } case 48: { UV_Voltage = UV_TH * 13;//低压保护时,电芯电压为3100mV break; } default: { UV_Voltage = BusVoltage; break; } } if(p_MC_ErrorCode->ERROR_Bit.Protect_UnderVoltage == 0) { //低压保护判断 if(BusVoltage >= UV_Voltage) { uvTimeCnt = HAL_GetTick(); } if((HAL_GetTick() - uvTimeCnt) > 5000) { p_MC_ErrorCode->ERROR_Bit.Protect_UnderVoltage = 1; //记录故障日志 MC_ErrorLogSaveInfo.NotesInfo1 = BusVoltage; ErrorLogSave_Update(&MC_ErrorLogSaveInfo); IsErrorLogSaveInfoUpdateFlag = TRUE; //存储故障次数 MC_RunLog1.UV_ProtectCnt++; RunLogSaveIndex = 1; } uvFaultTimeCnt = HAL_GetTick(); } else { //低压保护恢复 if(BusVoltage < (UV_Voltage + 500)) { uvFaultTimeCnt = HAL_GetTick(); } if((HAL_GetTick() - uvFaultTimeCnt) > 5000) { p_MC_ErrorCode->ERROR_Bit.Protect_UnderVoltage = 0; } } } //过压保护检测 void MC_Protect_OverVoltage_Process(uint16_t BusVoltage, uint16_t DesignVoltage, MC_ErrorCode_Struct_t* p_MC_ErrorCode) { static uint32_t ovTimeCnt = 0; static uint32_t ovFaultTimeCnt = 0; uint16_t OV_Voltage = 0; //根据额定电压更新保护阈值 switch(DesignVoltage) { case 24: { OV_Voltage = 4500 * 7;//过压保护时,电芯电压为4500mV break; } case 36: { OV_Voltage = 4500 * 10;//过压保护时,电芯电压为4500mV break; } case 48: { OV_Voltage = 4500 * 13;//过压保护时,电芯电压为4500mV break; } default: { OV_Voltage = BusVoltage; break; } } if(p_MC_ErrorCode->ERROR_Bit.Protect_OverVoltage == 0) { //过压保护判断 if(BusVoltage <= OV_Voltage) { ovTimeCnt = HAL_GetTick(); } if((HAL_GetTick() - ovTimeCnt) > 5000) { p_MC_ErrorCode->ERROR_Bit.Protect_OverVoltage = 1; //记录故障日志 ErrorLogSave_Update(&MC_ErrorLogSaveInfo); IsErrorLogSaveInfoUpdateFlag = TRUE; //存储故障次数 MC_RunLog1.OV_ProtectCnt++; RunLogSaveIndex = 1; } ovFaultTimeCnt = HAL_GetTick(); } else { //过压保护恢复 if(BusVoltage > (OV_Voltage - 500)) { ovFaultTimeCnt = HAL_GetTick(); } if((HAL_GetTick() - ovFaultTimeCnt) > 5000) { p_MC_ErrorCode->ERROR_Bit.Protect_OverVoltage = 0; } } } //堵转保护检测 void MC_Protect_RotorLock_Process(uint16_t BusCurrent, TrueOrFalse_Flag_Struct_t IsStopFlag, MC_ErrorCode_Struct_t* p_MC_ErrorCode) { static uint32_t Protect_1st_TimeCnt = 0; static uint32_t Protect_2st_TimeCnt = 0; static uint32_t FaultTimeCnt = 0; if(p_MC_ErrorCode->ERROR_Bit.Protect_LockRotor == 0) { //堵转保护检测 //一级电流堵转:电流大于2.5A,超时8s //二级电流堵转:电流大于7.5A,超时3s if(IsStopFlag == FALSE) { Protect_1st_TimeCnt = HAL_GetTick(); Protect_2st_TimeCnt = HAL_GetTick(); } else { if(BusCurrent < 2500) { Protect_1st_TimeCnt = HAL_GetTick(); Protect_2st_TimeCnt = HAL_GetTick(); } else if(BusCurrent < 7500) { Protect_2st_TimeCnt = HAL_GetTick(); } } if(((HAL_GetTick() - Protect_1st_TimeCnt) > 8000) || ((HAL_GetTick() - Protect_2st_TimeCnt) > 3000)) { p_MC_ErrorCode->ERROR_Bit.Protect_LockRotor = 1; //记录故障日志 ErrorLogSave_Update(&MC_ErrorLogSaveInfo); IsErrorLogSaveInfoUpdateFlag = TRUE; //存储故障次数 MC_RunLog1.LockRotor_ProtectCnt++; RunLogSaveIndex = 1; FaultTimeCnt = HAL_GetTick(); } } else { //堵转保护恢复 if((HAL_GetTick() - FaultTimeCnt) > 5000) { if((MC_ControlCode.GearSt == MC_GearSt_OFF) && //关闭助力 (ADC_SensorData.TorqueSensor < 10) && //无踩踏力矩 (ADC_SensorData.GasSensor < 10) && //指拨为0 (MC_CadenceResult.IsStopFlag == TRUE)) //踏频停止 { p_MC_ErrorCode->ERROR_Bit.Protect_LockRotor = 0; } } } } //过热保护检测 void MC_Protect_OverHeat_Process(uint8_t T_MCU, uint8_t T_PCB, uint8_t T_Coil, uint8_t TH, MC_ErrorCode_Struct_t* p_MC_ErrorCode) { static uint32_t OT_Set_TimeCnt = 0; static uint32_t OT_Reset_TimeCnt = 0; if(HAL_GetTick() < 3000) { OT_Set_TimeCnt = HAL_GetTick(); OT_Reset_TimeCnt = HAL_GetTick(); } if(p_MC_ErrorCode->ERROR_Bit.Protect_OverTemp == 0) { //温度传感器相互比较,差值在允许范围内进行处理 if(((T_MCU < (50 + T_PCB)) || (T_PCB < (50 + T_MCU))) && //PCB温度和MCU温度差值小于50度 ((T_MCU < (100 + T_Coil)) || (T_Coil < (100 + T_MCU)))) //绕组温度和MCU温度差值小于100度 { if((T_PCB < (TH - 20)) && (T_Coil < (TH + 15))) { OT_Set_TimeCnt = HAL_GetTick(); } } else { if(T_MCU < (TH - 20)) { OT_Set_TimeCnt = HAL_GetTick(); } } //过热保护判断 if((HAL_GetTick() - OT_Set_TimeCnt) > 5000) { OT_Reset_TimeCnt = HAL_GetTick(); p_MC_ErrorCode->ERROR_Bit.Protect_OverTemp = 1; //记录故障日志 ErrorLogSave_Update(&MC_ErrorLogSaveInfo); IsErrorLogSaveInfoUpdateFlag = TRUE; //存储故障次数 MC_RunLog1.OT_ProtectCnt++; RunLogSaveIndex = 1; } } else { //过热保护恢复 if((((T_PCB < (TH - 20)) && (T_Coil < (TH - 20))) || (T_MCU < (TH - 40))) && ((HAL_GetTick() - OT_Reset_TimeCnt) > 300000)) { p_MC_ErrorCode->ERROR_Bit.Protect_OverTemp = 0; OT_Set_TimeCnt = HAL_GetTick(); } } } //电压波动异常保护检测 void MC_Protect_VoltageChange_Process(uint16_t Voltage, uint16_t Current, MC_ErrorCode_Struct_t* p_MC_ErrorCode) { static uint32_t PeriodTimeCnt = 0; uint32_t DiffSqrtResult = 0; static uint8_t TrigCnt = 0; static uint16_t Array[10] = {0}; uint16_t i; if((HAL_GetTick() - PeriodTimeCnt) >= 100) { for(i=0; i<(sizeof(Array) / 2 - 1); i++) { Array[i] = Array[i + 1]; } Array[sizeof(Array) / 2 - 1] = Voltage; DiffSqrtResult = GetStandardDeviation(Array, sizeof(Array) >> 1); //保护判断 if(p_MC_ErrorCode->ERROR_Bit.Protect_VoltageChange == 0) { if((Current < 50) && (DiffSqrtResult > 1000)) { if(TrigCnt > 50) // 5s { p_MC_ErrorCode->ERROR_Bit.Protect_VoltageChange = 1; //记录故障日志 MC_ErrorLogSaveInfo.NotesInfo1 = DiffSqrtResult / 256; MC_ErrorLogSaveInfo.NotesInfo2 = GetMaxData(Array, sizeof(Array) >> 1); MC_ErrorLogSaveInfo.NotesInfo3 = GetMinData(Array, sizeof(Array) >> 1); ErrorLogSave_Update(&MC_ErrorLogSaveInfo); IsErrorLogSaveInfoUpdateFlag = TRUE; //存储故障次数 MC_RunLog2.VoltageChange_FaultCnt++; RunLogSaveIndex = 2; } } else { TrigCnt = 0; } } else { //恢复判断 if(DiffSqrtResult <= 1000) { p_MC_ErrorCode->ERROR_Bit.Protect_VoltageChange = 0; } } } } /******************************全局函数定义******************************/ #define OC_CLEARFLAG_DELAYTIME 15 //过流标志间隔清零延时,单位ms #define OC_COUNTER_TH 100 //过流保护计数判断阈值 //过流保护检测 /* 检测原理: 1、过流触发后,OverCurrentTrigFlag置位,封波2个周期后再次发波; 2、在过流触发计数达到OC_COUNTER_TH 次之前,如果存在两次过流触发间隔时间超过OC_CLEARFLAG_DELAYTIME ms,清除过流触发计数; 3、如果每两次过流触发间隔时间都不超过OC_CLEARFLAG_DELAYTIME ms,当过流触发计数达到OC_COUNTER_TH 次,则进入过流保护; 4、进入过流保护后,超时5s解除。 */ void MC_Protect_OverCurrent_Process(FlagStatus* OverCurrentTrigFlag, MC_ErrorCode_Struct_t* p_MC_ErrorCode) { static uint8_t OffPwmCnt = 0; //过流信号触发后,关闭PWM延时计数 static uint8_t StarPwmCnt = 0; //关闭PWM后启动PWM延时计数 static uint16_t ocCnt = 0; //过流信号触发计数 static uint32_t ocTimeCnt = 0; //过流信号触发计时 static uint32_t ocFaultTimeCnt = 0; //过流保护后计时 if(p_MC_ErrorCode->ERROR_Bit.Protect_OverCurrent == 0) { if(*OverCurrentTrigFlag == RESET) { //关闭PWM计数清零 OffPwmCnt = 0; //两次过流触发间隔超时OC_CLEARFLAG_DELAYTIME ms,过流次数未达到OC_COUNTER_TH 次,过流计数清零 if(ocCnt < OC_COUNTER_TH) { if((HAL_GetTick() - ocTimeCnt) >= OC_CLEARFLAG_DELAYTIME) { ocTimeCnt = HAL_GetTick(); ocCnt = 0; } } //开启PWM if(StarPwmCnt == 0) { StarPwmCnt++; Enable_PwmGpio_Out(); } } else { //开启PWM计数清零 StarPwmCnt = 0; //关闭PWM Disable_PwmGpio_Out(); //2个PWM周期后,过流触发标志复位 if(OffPwmCnt >= 1) { *OverCurrentTrigFlag = RESET; } //过流次数计数 if(ocCnt < OC_COUNTER_TH) { ocCnt++; } //过流标志计数次数达到OC_COUNTER_TH 次,启动过流保护 else { ocCnt = 0; p_MC_ErrorCode->ERROR_Bit.Protect_OverCurrent = 1; ocFaultTimeCnt = HAL_GetTick(); //记录故障日志 ErrorLogSave_Update(&MC_ErrorLogSaveInfo); IsErrorLogSaveInfoUpdateFlag = TRUE; //存储故障次数 MC_RunLog1.OC_ProtectCnt++; RunLogSaveIndex = 1; } OffPwmCnt++; ocTimeCnt = HAL_GetTick(); } } else { //过流恢复 if((HAL_GetTick() - ocFaultTimeCnt) > 5000) { MC_ErrorCode.ERROR_Bit.Protect_OverCurrent = 0; ocFaultTimeCnt = HAL_GetTick(); *OverCurrentTrigFlag = RESET; } } } //保护判断 void MC_Protect_Check_Process(void) { //低压保护检测 MC_Protect_UnderVoltage_Process(((IsComOK_BMS.IsOK_Flag == TRUE) ? BMS_RunInfo.Voltage : MC_RunInfo.BusVoltage), MC_MotorParam.Rate_Voltage, ((MC_ConfigParam1.UV_Protect_TH == 0) ? 3100 : MC_ConfigParam1.UV_Protect_TH), &MC_ErrorCode); //过压保护检测 MC_Protect_OverVoltage_Process(MC_RunInfo.BusVoltage, MC_MotorParam.Rate_Voltage, &MC_ErrorCode); //堵转保护检测 MC_Protect_RotorLock_Process(MC_RunInfo.BusCurrent, MC_HallSensorData.IsStopFlag, &MC_ErrorCode); //过热保护检测 MC_Protect_OverHeat_Process(MC_RunInfo.T_MCU, MC_RunInfo.T_PCB, MC_RunInfo.T_Coil, MC_ConfigParam1.TempTH_Protect, &MC_ErrorCode); //电压波动异常保护检测 MC_Protect_VoltageChange_Process(MC_RunInfo.BusVoltage, MC_RunInfo.BusCurrent, &MC_ErrorCode); }