diff --git a/APP/businessLogic/Src/bl_chargControl.c b/APP/businessLogic/Src/bl_chargControl.c index ccd7a09..8de5c67 100644 --- a/APP/businessLogic/Src/bl_chargControl.c +++ b/APP/businessLogic/Src/bl_chargControl.c @@ -2,6 +2,8 @@ #include "bl_chargControl.h" #include "parameter.h" #include "comm_types.h" +#include "FM_GPIO.h" + static void stopChargWork(void); static BOOL stopChargConditions(void); @@ -11,6 +13,378 @@ static BOOL constantVChargConditions(void); static void mpptCharge(void); static void constantVoltageCharge(void); static void floatCharge(void); +static void mppt_constantVoltage(float InVoltage); +static void mppt_constantVoltageNoBatteryO(float OutVoltage); +static void mppt_constantVoltageO(float OutVoltage); + +/** + * @brief 恒定输入电压 + * @param InVoltage 需要控制到的输入电压 + * @retval + * + */ +void mppt_constantVoltage(float InVoltage) +{ + static float kp = 0.005; + static float ki = 0.00001; + static float solarInCircuitVoltage; + static float error; + static float stepPwm; + + + solarInCircuitVoltage = getSolarInCircuitVoltage(); + error = solarInCircuitVoltage - InVoltage; +// float error = InVoltage - g_otherParameter.Solar_In_Circuit_Voltage; + stepPwm = kp * error + ki * solarInCircuitVoltage; + + setDutyRatio((getDutyRatio() + stepPwm)); + set_pwmDutyRatio(getDutyRatio()); +} + +/** + * @brief 恒定输出电压(无电池) + * @param + * @retval + * + */ +void mppt_constantVoltageNoBatteryO(float OutVoltage) +{ + static float kp = 0.005; + static float ki = 0.00001; + static float outVolt; + static float error; + static float stepPwm; + + outVolt = getOutputVoltage(); + error = OutVoltage - outVolt; + stepPwm = kp * error + ki * outVolt; + + setDutyRatio((getDutyRatio() + stepPwm)); + set_pwmDutyRatio(getDutyRatio()); +} + +/** + * @brief 恒定输出电压(输出检测端) + * @param + * @retval + * + */ +void mppt_constantVoltageO(float OutVoltage) +{ + // static float lastVolt = 0; + // static float lastStepPwm = 0; + static float lastDutyRatio = 0; + static float kp = 0.005; + static float ki = 0.00001; + static float outVolt; + static float error; + static float StepPwm; + + outVolt = getOutputVoltage(); + error = OutVoltage - outVolt; + StepPwm = kp * error + ki * outVolt; + + /* 当有电池时,输出电压的曲线是先上升后下降 */ + if (lastDutyRatio >= getDutyRatio()) { +// if (lastVolt >= outVolt) { + setDutyRatio((getDutyRatio() - StepPwm)); +// } else { +// g_controlParameter.dutyRatio -= StepPwm; +// } + } else { +// if (lastVolt >= outVolt) { +// g_controlParameter.dutyRatio -= StepPwm; +// } else { +// g_controlParameter.dutyRatio += StepPwm; +// } + setDutyRatio((getDutyRatio() + StepPwm)); + } + + // lastVolt = outVolt; + // lastStepPwm = StepPwm; + lastDutyRatio = getDutyRatio(); + set_pwmDutyRatio(getDutyRatio()); +} + +/** + * @brief 通过扰动干扰法追踪最大功率点 + * @param + * @retval + * + */ +void mppt_readJust(void) +{ + /* 调节占空比 */ +// static float_t step1 = 0.01; +// static float_t step2 = 0.003; +// static float_t tempV = 0.2; +// static float_t i = 0.005; +// static uint16_t flag = 0; +// static float_t lastSolarInCircuitVoltage = 0; +// static float_t lastPower = 0; +// flag++; +// if (flag < 500) { +// return; +// } +// flag = 0; +// +// float_t SolarInCircuitVoltage = get_PV1_VOLT_IN(); +// float_t power = g_otherParameter.Output_Voltage * g_otherParameter.Charg_Current; +// +// float_t voltageDifference = SolarInCircuitVoltage - lastSolarInCircuitVoltage; +// +// /* 输出电压随占空比增加电压减小 */ +// if (power <= lastPower) { +// if (lastSolarInCircuitVoltage <= SolarInCircuitVoltage) { +// if (voltageDifference > tempV) { +// g_controlParameter.dutyRatio += step2 + voltageDifference / i; +// } else { +// g_controlParameter.dutyRatio += step1 + voltageDifference / i; +// } +// } else { +// if (voltageDifference < -tempV) { +// g_controlParameter.dutyRatio -= step2 + voltageDifference / i; +// } else { +// g_controlParameter.dutyRatio -= step1 + voltageDifference / i; +// } +// } +// } else { +// if (lastSolarInCircuitVoltage <= SolarInCircuitVoltage) { +// if (voltageDifference > tempV) { +// g_controlParameter.dutyRatio -= step2 - voltageDifference / i; +// } else { +// g_controlParameter.dutyRatio -= step1 - voltageDifference / i; +// } +// } else { +// if (voltageDifference < -tempV) { +// g_controlParameter.dutyRatio += step2 - voltageDifference / i; +// } else { +// g_controlParameter.dutyRatio += step1 - voltageDifference / i; +// } +// } +// } +// +// lastPower = power; +// lastSolarInCircuitVoltage = SolarInCircuitVoltage; +// +// Set_duty_ratio(&g_controlParameter.dutyRatio); + + + /* 调节电压,变步长调节 */ +// static float_t Power3 = 0; //上上次功率 +// static float_t Power2 = 0; //上次功率 +// static float_t Power1 = 0; //当前功率 +// static float_t power23 = 0; //上次和上上次功率的绝对值 +// static float_t power12 = 0; //当前功率和上次功率的绝对值 +//// static float_t SolarInCircuitVoltage3 = 0; //上上次太阳能板电压 +// static float_t SolarInCircuitVoltage2 = 0; //上次太阳能板电压 +// static float_t SolarInCircuitVoltage1 = 0; //当前太阳能板电压 +// static float_t SolarInCircuitVoltage12 = 0; //当前太阳能板电压和上次太阳能板电压的绝对值 +// SolarInCircuitVoltage1 = get_PV1_VOLT_IN(); +// Power1 = g_otherParameter.Output_Voltage * g_otherParameter.Charg_Current; +// static float_t power12Abs = 0; +// static float_t power23Abs = 0; +// static float_t SolarInCircuitVoltage12Abs = 0; +// static float_t dk = 0; //变步长因子 +// static float_t stepV = 0; +// static float_t SolarInCircuitV = 18; //控制太阳能板的输出电压稳定在该值 +// +// static float_t kp = 0.005; +// static float_t ki = 0.00001; +// +// /* 延时一段时间才判断 */ +// static uint16_t flag = 0; +// flag++; +// if (flag < 1000) { +//// float_t pv1Volt = g_otherParameter.Solar_In_Circuit_Voltage; +// float_t pv1Volt = SolarInCircuitVoltage1; +// float_t error = pv1Volt - SolarInCircuitV; +// float_t stepPwm = kp * error + ki * pv1Volt; +// +// g_controlParameter.dutyRatio += stepPwm; +// +// /* 过温保护 */ +// if (g_otherParameter.overTemperature == 0) { +// +// } else if (g_otherParameter.overTemperature == 1) { +// g_controlParameter.dutyRatio -= 0.1; +// } else if (g_otherParameter.overTemperature == 2) { +// g_controlParameter.dutyRatio -= 0.2; +// } else if (g_otherParameter.overTemperature == 3) { +// g_controlParameter.dutyRatio -= 0.3; +// } +// +// Set_duty_ratio(&g_controlParameter.dutyRatio); +// +// return; +// } +// flag = 0; +// +// power23 = Power2 - Power3; +// if (power23 < 0) { +// power23Abs = -power23; +// } else { +// power23Abs = power23; +// } +// +// power12 = Power1 - Power2; +// if (power12 < 0) { +// power12Abs = -power12; +// } else { +// power12Abs = power12; +// } +// +//// SolarInCircuitVoltage23 = SolarInCircuitVoltage2 - SolarInCircuitVoltage3; +// +// SolarInCircuitVoltage12 = SolarInCircuitVoltage1 - SolarInCircuitVoltage2; +// +// dk = power12Abs / power23Abs; +// stepV = dk * SolarInCircuitVoltage12Abs; +// +//// printf(" dk : %d/10000 \n", (int)(dk * 10000)); +// +// if (power12 > 0) { +// if (SolarInCircuitVoltage12 > 0) { +// SolarInCircuitV = SolarInCircuitVoltage1 + stepV; +// } else { +// SolarInCircuitV = SolarInCircuitVoltage1 - stepV; +// } +// } else { +// if (SolarInCircuitVoltage12 > 0) { +// SolarInCircuitV = SolarInCircuitVoltage1 - stepV; +// } else { +// SolarInCircuitV = SolarInCircuitVoltage1 + stepV; +// } +// } +// +// printf(" SolarInCircuitV : %d/100 \n", (int)(SolarInCircuitV * 100)); +// +// if (SolarInCircuitV > 21) { +// SolarInCircuitV = 21; +// } +// else if (SolarInCircuitV < 15) { +// SolarInCircuitV = 15; +// } +// +// printf(" SolarInCircuitV : %d/100 \n", (int)(SolarInCircuitV * 100)); +// +// Power3 = Power2; +// Power2 = Power1; +//// SolarInCircuitVoltage3 = SolarInCircuitVoltage2; +// SolarInCircuitVoltage2 = SolarInCircuitVoltage1; +// +//// float_t pv1Volt = g_otherParameter.Solar_In_Circuit_Voltage; +// float_t pv1Volt = SolarInCircuitVoltage1; +// float_t error = pv1Volt - SolarInCircuitV; +// float_t stepPwm = kp * error + ki * pv1Volt; +// +// g_controlParameter.dutyRatio += stepPwm; +// +// /* 过温保护 */ +// if (g_otherParameter.overTemperature == 0) { +// +// } else if (g_otherParameter.overTemperature == 1) { +// g_controlParameter.dutyRatio -= 0.1; +// } else if (g_otherParameter.overTemperature == 2) { +// g_controlParameter.dutyRatio -= 0.2; +// } else if (g_otherParameter.overTemperature == 3) { +// g_controlParameter.dutyRatio -= 0.3; +// } +// +// Set_duty_ratio(&g_controlParameter.dutyRatio); +// +// return; + + /* 调节电压,两个电压步调节 */ + static float Power = 0; + Power = getOutputVoltage() * getChargCurrent(); + static float lPower = 0; +// static float lLPower = 0; +// static float lLLPower = 0; + + static float SolarInCircuitV = 17; //控制太阳能板的输出电压稳定在该值,初始为17V + // static float kp = 0.005; + // static float ki = 0.00001; + + static float stepV1 = 0.5; + static float stepV2 = 0.2; + + static uint8_t flag1 = 0; //表明上次运算是加还是减 + + /* 延时一段时间才判断 */ + static uint16_t flag = 0; + flag++; + if (flag < 150) { + // float pv1Volt = getSolarInCircuitVoltage(); + // float error = pv1Volt - SolarInCircuitV; + // float stepPwm = kp * error + ki * pv1Volt; + + // setDutyRatio((getDutyRatio() + stepPwm)); + // set_pwmDutyRatio(getDutyRatio()); + + mppt_constantVoltage(SolarInCircuitV); + + return; + } + flag = 0; + + static float powerT = 0; + powerT = Power - lPower; + if (powerT < 0) { + powerT = -powerT; + } + +// if ((lPower + 0.7 < Power) && (lLPower + 0.7 < Power) && (lLLPower + 0.7 < Power)) { +// if ((lPower + 0.7 < Power) && (lLPower + 0.7 < Power)) { + if ((lPower + 0.3f < Power)) { + if (powerT > 5) { + if (flag1) { + SolarInCircuitV += stepV1; + flag1 = 1; + } else { + SolarInCircuitV -= stepV1; + flag1 = 0; + } + } else { + if (flag1) { + SolarInCircuitV += stepV2; + flag1 = 1; + } else { + SolarInCircuitV -= stepV2; + flag1 = 0; + } + } +// } else if ((lPower - 0.7 > Power) && (lLPower - 0.7 > Power) && (lLLPower - 0.7 > Power)) { +// } else if ((lPower - 0.7 > Power) && (lLPower - 0.7 > Power)) { + } else if ((lPower - 0.3f > Power)) { + if (powerT > 5) { + if (flag1) { + SolarInCircuitV -= stepV1; + flag1 = 0; + } else { + SolarInCircuitV += stepV1; + flag1 = 1; + } + } else { + if (flag1) { + SolarInCircuitV -= stepV2; + flag1 = 0; + } else { + SolarInCircuitV += stepV2; + flag1 = 1; + } + } + } + + if (SolarInCircuitV > 18.5f) { + SolarInCircuitV = 18.5f; + } + else if (SolarInCircuitV < 16.0f) { + SolarInCircuitV = 16.0f; + } + + lPower = Power; +} /** * @brief 停止充电 @@ -20,7 +394,8 @@ static void floatCharge(void); */ void stopChargWork(void) { - + EN_PWMOUT_Diseable(); + pwm_Stop(); } /** @@ -32,7 +407,10 @@ void stopChargWork(void) */ BOOL stopChargConditions(void) { - + if (getSolarInCircuitVoltage() < g_cfgParameter.stopSolarOpenCircuitV + && getChargCurrent() < 0.1f) { + return TRUE; + } return FALSE; } @@ -46,7 +424,12 @@ BOOL stopChargConditions(void) */ BOOL floatChargConditions(void) { - + if (g_cfgParameter.constantVoltageChargeV < getBatteryVoltage() + && g_cfgParameter.floatI > getChargCurrent()) { + return TRUE; + } + + return FALSE; } @@ -121,7 +504,10 @@ void getCVData(void) */ void judgeYNBattery(void) { - + if (getBatteryVoltage() > 16 || getBatteryVoltage() < 10) { + setBatteryState(FALSE); + return; + } } /** @@ -132,7 +518,7 @@ void judgeYNBattery(void) */ void noBatteryChargControl(void) { - + mppt_constantVoltageNoBatteryO(g_cfgParameter.FloatV); } /** @@ -143,7 +529,7 @@ void noBatteryChargControl(void) */ void mpptCharge(void) { - + mppt_readJust(); } /** @@ -154,8 +540,7 @@ void mpptCharge(void) */ void constantVoltageCharge(void) { - - + mppt_constantVoltageO(g_cfgParameter.constantVoltageChargeV); } /** @@ -166,7 +551,7 @@ void constantVoltageCharge(void) */ void floatCharge(void) { - + mppt_constantVoltageO(g_cfgParameter.FloatV); } /** diff --git a/APP/functionalModule/Src/FM_TIM.c b/APP/functionalModule/Src/FM_TIM.c index c1e5989..9401923 100644 --- a/APP/functionalModule/Src/FM_TIM.c +++ b/APP/functionalModule/Src/FM_TIM.c @@ -18,7 +18,9 @@ void tim_Init(void) PWM_RESOLUTION = HAL_RCC_GetHCLKFreq() / 100000; HD_controlTim_Init(); + HD_taskBaseTim_Init(); + HD_checkAbnormalTim_Init(); HD_time_Init(); @@ -34,11 +36,12 @@ void pwm_Stop(void) { // 设置PWM脉冲宽度为0, effectively停止PWM信号输出 set_pwmPulse(0); + HAL_TIM_Base_Stop_IT(&htim15); // HAL_TIM_OC_MspDeInit(&htim3); // 调用HAL库函数进行PWM相关的硬件资源De初始化 - HAL_TIM_PWM_MspDeInit(&htim3); + // HAL_TIM_PWM_MspDeInit(&htim3); } /**