/* * mppt_control.c * * Created on: 2024年6月29日 * Author: psx */ #include "mppt_control.h" #include "collect_Conversion.h" #include "pwm.h" #include "inflash.h" #include "gpio.h" #include "sl_protocol.h" #include "task.h" #include "uart_dev.h" #include "parameter.h" static void ConstantCurrentCharge(void); static void ConstantVoltageCharge(void); static void FloatingCharge(void); /** * @brief 恒定输入电压 * @param * @retval * */ void mppt_constantVoltage(float InVoltage) { static float_t kp = 0.005; static float_t ki = 0.00001; float_t pv1Volt = g_otherParameter.Solar_In_Circuit_Voltage; float_t error = pv1Volt - InVoltage; float_t stepPwm = kp * error + ki * pv1Volt; g_controlParameter.dutyRatio += stepPwm; Set_duty_ratio(&g_controlParameter.dutyRatio); } /** * @brief 恒定输出电压(电池) * @param * @retval * */ void mppt_constantVoltageB(float OutVoltage) { static float_t kp = 0.005; static float_t ki = 0.00001; float_t outVolt = g_otherParameter.Battery_Voltage; float_t error = OutVoltage - outVolt; float_t stepPwm = kp * error + ki * outVolt; g_controlParameter.dutyRatio += stepPwm; Set_duty_ratio(&g_controlParameter.dutyRatio); } /** * @brief 恒定输出电压(输出检测端,没有电池时) * @param * @retval * */ void mppt_constantVoltageNoBatteryO(float OutVoltage) { static float_t kp = 0.005; static float_t ki = 0.00001; float_t outVolt = g_otherParameter.Output_Voltage; float_t error = OutVoltage - outVolt; float_t stepPwm = kp * error + ki * outVolt; g_controlParameter.dutyRatio += stepPwm; Set_duty_ratio(&g_controlParameter.dutyRatio); } /** * @brief 恒定输出电压(输出检测端) * @param * @retval * */ float_t lastVolt = 0; float_t lastStepPwm = 0; float_t lastDutyRatio = 0; void mppt_constantVoltageO(float OutVoltage) { static float_t kp = 0.005; static float_t ki = 0.00001; // static uint8_t flag = 0; float_t outVolt = g_otherParameter.Output_Voltage; float_t error = OutVoltage - outVolt; float_t StepPwm = kp * error + ki * outVolt; /* 当有电池时,输出电压的曲线是先上升后下降 */ if (lastDutyRatio >= g_controlParameter.dutyRatio) { // if (lastVolt >= outVolt) { g_controlParameter.dutyRatio += StepPwm; // } else { // g_controlParameter.dutyRatio -= StepPwm; // } } else { // if (lastVolt >= outVolt) { // g_controlParameter.dutyRatio -= StepPwm; // } else { // g_controlParameter.dutyRatio += StepPwm; // } 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; } lastVolt = outVolt; lastStepPwm = StepPwm; lastDutyRatio = g_controlParameter.dutyRatio; Set_duty_ratio(&g_controlParameter.dutyRatio); } /** * @brief 通过扰动干扰法追踪最大功率点 * @param * @retval * */ float_t lastPower = 0; float_t lastSolarInCircuitVoltage = 0; void mppt_readJust(void) { static float_t step1 = 0.01; static float_t step2 = 0.005; static float_t tempV = 0.1; static uint16_t flag = 0; flag++; if (flag < 600) { 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; } else { g_controlParameter.dutyRatio += step1; } } else { if (voltageDifference > tempV) { g_controlParameter.dutyRatio -= step2; } else { g_controlParameter.dutyRatio -= step1; } } } else { if (lastSolarInCircuitVoltage <= SolarInCircuitVoltage) { if (voltageDifference > tempV) { g_controlParameter.dutyRatio -= step2; } else { g_controlParameter.dutyRatio -= step1; } } else { if (voltageDifference > tempV) { g_controlParameter.dutyRatio += step2; } else { g_controlParameter.dutyRatio += step1; } } } lastPower = power; lastSolarInCircuitVoltage = SolarInCircuitVoltage; /* 过温保护 */ 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); } /** * @brief 恒流充电(大电流充电),mppt最大功率充电 * @param * @retval * */ void ConstantCurrentCharge(void) { // mppt_constantVoltage(18); mppt_readJust(); } /** * @brief 恒压充电 * @param * @retval * */ void ConstantVoltageCharge(void) { mppt_constantVoltageO(g_controlParameter.constantVoltageChargeV); } /** * @brief 浮充充电 * @param * @retval * */ void FloatingCharge(void) { mppt_constantVoltageO(g_controlParameter.FloatV); } /** * @brief mppt控制模式的确定 * @param * @retval * */ void MpptContorlChoice(void) { switch(g_otherParameter.MPPT_Mode) { case CONSTANTCURRENT: ConstantCurrentCharge(); break; case CONSTANTVOLTAGE: ConstantVoltageCharge(); break; case FLOAT: FloatingCharge(); break; default: break; } } /** * @brief mppt模式的确定 * @param * @retval * */ void MpptModeChoice(void) { /* 太阳能板输出电压小于一定值且充电电流也小于一定值时mppt停止工作 */ if ((g_otherParameter.Input_Voltage < g_controlParameter.stopSolarOpenCircuitV && g_otherParameter.Charg_Current < 0.1) ){ // && g_otherParameter.MPPT_Mode != NoWork) { g_otherParameter.MPPT_Mode = NoWork; TIM_Cmd(TIM3, DISABLE); TIM_SetCompare4(TIM4, 0); g_controlParameter.dutyRatio = 0; TimeSliceOffset_Register(&g_startMpptControl, Task_startMpptControl , startMpptControl_reloadVal, startMpptControl_offset); TimeSliceOffset_Unregister(&g_collectOpenCircuitVoltage); return; } /* 流向电池的电流小于一定值或者电压过大或者过小采用浮充输出 */ if ((g_otherParameter.Charg_BatteryCurrent < 0.05 && g_otherParameter.Charg_BatteryCurrent > -0.05) || g_otherParameter.Battery_Voltage > 16 || g_otherParameter.Battery_Voltage < 8) { g_otherParameter.MPPT_Mode = FLOAT; g_otherParameter.batteryState = 0; return; } /* */ if ((g_controlParameter.constantVoltageV - 0.2) >= g_otherParameter.Battery_Voltage && g_otherParameter.Charg_Current > 0.1) { g_otherParameter.MPPT_Mode = CONSTANTCURRENT; return; } if ((g_controlParameter.constantVoltageV < g_otherParameter.Battery_Voltage) // && (g_controlParameter.floatI + 0.1 <= g_otherParameter.Charg_Current)) { && ((g_controlParameter.floatI + 0.1 <= g_otherParameter.Charg_BatteryCurrent) || (g_controlParameter.floatI + 0.1 <= -g_otherParameter.Charg_Current))) { g_otherParameter.MPPT_Mode = CONSTANTVOLTAGE; return; } if ((((g_controlParameter.constantVoltageV < g_otherParameter.Battery_Voltage) && (g_controlParameter.floatI > g_otherParameter.Charg_Current)) && (g_controlParameter.floatI > g_otherParameter.Discharg_Current))) { g_otherParameter.MPPT_Mode = FLOAT; return; } } /** * @brief mppt的控制 * @param * @retval * */ void MpptContorl(void) { g_otherParameter.Output_Voltage = get_PV_VOLT_OUT(); g_otherParameter.Solar_In_Circuit_Voltage = get_PV1_VOLT_IN(); // /* 出现adc采集出错全为0,退出本次中断 */ // if (g_otherParameter.Discharg_Current == 0 && g_otherParameter.Charg_Current == 0) { // return; // } g_otherParameter.Charg_BatteryCurrent = g_otherParameter.Charg_Current - g_otherParameter.Discharg_Current; MpptModeChoice(); /* 无电池时,恒压输出 */ if (!g_otherParameter.batteryState) { if (!g_otherParameter.overTemperature) { // mppt_constantVoltageNoBatteryO(g_controlParameter.FloatV); mppt_constantVoltageO(g_controlParameter.FloatV); } return; } // /* 有电池时 */ // if (!g_otherParameter.overTemperature) { // MpptModeChoice(); // MpptContorlChoice(); // } MpptContorlChoice(); }