diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c index 95453a7..c801263 100644 --- a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c +++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.c @@ -120,7 +120,18 @@ void Channels_Simulation(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS) CC_PWM_Ch3_Simulation(TIMx, TIMS); CC_PWM_Ch4_Simulation(TIMx, TIMS); - Write_OC_to_GPIO(TIMx, TIMS); + if ((TIMx == TIM1) || (TIMx == TIM8)) + { + if (TIMx->BDTR & TIM_BDTR_MOE) + { + Write_OC_to_GPIO(TIMx, TIMS); + } + } + else + { + Write_OC_to_GPIO(TIMx, TIMS); + } + } //-----------------CAPTURE COPMARE & PWM FUNCTIONS------------------// /* Выбор режима CaptureCompare или PWM и симуляция для каждого канала */ diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx index d98ecbc..b607c74 100644 Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h index b960297..35d0cb0 100644 --- a/UPP/Core/Configs/upp_config.h +++ b/UPP/Core/Configs/upp_config.h @@ -98,9 +98,10 @@ #define PUI_Interlace_EN_DEFAULT 5000 /* Время задержки перед выставлением ошибки */ -#define ERRORS_DELAY_MS_UAMP_ERR 1500 // todo -#define ERRORS_DELAY_MS_F_ERR 5000 -#define ERRORS_DELAY_MS_DEFAULT 0.1f +#define ERRORS_DELAY_MS_UAMP_ERR 1500 // todo +#define ERRORS_DELAY_MS_F_ERR 5000 +#define ERRORS_DELAY_MS_CRITICAL_ERR 0.0f +#define ERRORS_DELAY_MS_DEFAULT 0.1f /* Параметры регулятора угла */ diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c index d6abab1..beb12c7 100644 --- a/UPP/Core/PowerMonitor/power_monitor.c +++ b/UPP/Core/PowerMonitor/power_monitor.c @@ -214,7 +214,10 @@ void PowerMonitor_FastCalc(PowerMonitor_t *hpm) meas->final.PhaseSequence = UPP_Sequence_BAC; } } - } + } + + if(hpm->f.isI) + Protect_Fast(&hpm->measured, u2f(PARAM_INTERNAL->pm.lImaxAmp, 100)); /* Вообще фильтры должны рабтоать синхронно, но на всякий синхронизация */ //__SynchAvgFilters(hpm); @@ -225,7 +228,6 @@ void PowerMonitor_FastCalc(PowerMonitor_t *hpm) meas->slow.I[I_C] = Filter_Process(&hpm->avg[AVG_IC], meas->fast.I[I_C]); meas->slow.I[I_A] = Filter_Process(&hpm->avg[AVG_IA], meas->fast.I[I_A]); - /* Запускаем медленную обработку через slow_period прерываний */ // if(hpm->isr_cnt == PM_SLOW_PERIOD_CNT) /* Запускаем медленную когда фильтры среднего зациклились */ @@ -274,7 +276,7 @@ int PowerMonitor_Protect(PowerMonitor_t *hpm, uint8_t Running) if(Running) { /*=============== ЗАЩИТЫ ПО ТОКУ ==================*/ - hpm->f.isI = Protect_Currents(measure, params, nominal); + hpm->f.isI = Protect_Currents(measure, params, nominal); } /*=============== ЗАЩИТЫ ВСЯКИЕ ДРУГИЕ ==================*/ diff --git a/UPP/Core/PowerMonitor/power_protect.c b/UPP/Core/PowerMonitor/power_protect.c index ea9ce19..9b75079 100644 --- a/UPP/Core/PowerMonitor/power_protect.c +++ b/UPP/Core/PowerMonitor/power_protect.c @@ -72,8 +72,8 @@ int Protect_Currents(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, } else { - ERR_PRIVATE->iamp_max = 0; - ERR_PRIVATE->iamp_min = 0; +// ERR_PRIVATE->iamp_max = 0; +// ERR_PRIVATE->iamp_min = 0; } /* Ток по фазам */ @@ -87,8 +87,8 @@ int Protect_Currents(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, } else { - ERR_PRIVATE->ia_max = 0; - ERR_PRIVATE->ia_min = 0; +// ERR_PRIVATE->ia_max = 0; +// ERR_PRIVATE->ia_min = 0; } if(measure->final.I[I_B] > lImax) @@ -101,8 +101,8 @@ int Protect_Currents(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, } else { - ERR_PRIVATE->ib_max = 0; - ERR_PRIVATE->ib_min = 0; +// ERR_PRIVATE->ib_max = 0; +// ERR_PRIVATE->ib_min = 0; } if(measure->final.I[I_C] > lImax) @@ -115,14 +115,42 @@ int Protect_Currents(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, } else { - ERR_PRIVATE->ic_max = 0; - ERR_PRIVATE->ic_min = 0; +// ERR_PRIVATE->ic_max = 0; +// ERR_PRIVATE->ic_min = 0; } return (ERR_PRIVATE->iamp_min == 0); } +/** + * @brief Проверяет быстрые защиты. + * @note Заполняет флаги prvt ошибок (приватные). + * Потом в @ref UPP_ErrorsHandle исходя из них заполняются ошибки для ПУИ + */ +void Protect_Fast(PowerMonitor_Measured_t *measure, float lImaxAmp) +{ +// /* Переводим уставки ПУИ в удобный вид */ +// float lImaxAmp = u2f(params->Imax, 100) * 50 / u2f(nominal->I, 10) *1.41; // Амплитудное значение Imax + + + /* Ток по фазам */ + if(measure->fast.I[I_A] > lImaxAmp) + { + ERR_PRIVATE->ia_max = 1; + } + + if(measure->fast.I[I_B] > lImaxAmp) + { + ERR_PRIVATE->ib_max = 1; + } + + if(measure->fast.I[I_C] > lImaxAmp) + { + ERR_PRIVATE->ic_max = 1; + } +} + /** * @brief Проверяет всякие другие защиты (частота, температура). diff --git a/UPP/Core/PowerMonitor/power_protect.h b/UPP/Core/PowerMonitor/power_protect.h index 06114d9..d54e6d6 100644 --- a/UPP/Core/PowerMonitor/power_protect.h +++ b/UPP/Core/PowerMonitor/power_protect.h @@ -13,6 +13,8 @@ int Protect_Voltages(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, UPP_ParamsNominal_t *nominal); /* Проверяет защиты по току. */ int Protect_Currents(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, UPP_ParamsNominal_t *nominal); -/* Проверяет всякие другие защиты (частота, температура). */ +/* Проверяет быстрые защиты. */ +void Protect_Fast(PowerMonitor_Measured_t *measure, float lImaxAmp); +/* Проверяет всякие другие защиты (частота, температура). */ void Protect_Misc(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *params, UPP_ParamsNominal_t *nominal); #endif /* _POWER_PROTECT_H_ */ diff --git a/UPP/Core/UPP/angle_control.c b/UPP/Core/UPP/angle_control.c index d3af143..29deae4 100644 --- a/UPP/Core/UPP/angle_control.c +++ b/UPP/Core/UPP/angle_control.c @@ -76,7 +76,11 @@ void Angle_PID(Angle_Handle_t *hangle, float setpoint, float measurement, float /* Плавное нарастание уставки */ hangle->Iref = Filter_Process(&hangle->refFilter, setpoint); - hangle->Imeas = measurement; + hangle->f.RazgonDone = (fabsf(hangle->Iref - u2f(PARAM_PUI->Iref, 100)) < 0.1);; + + + hangle->Imeas = measurement; + /* Ошибка регулирования = уставка - измеренное */ float err = hangle->Iref - hangle->Imeas; @@ -115,7 +119,8 @@ void Angle_PID_Reset(Angle_Handle_t *hangle) return; hangle->Iref = 0; - hangle->Imeas = 0; + hangle->Imeas = 0; + hangle->f.RazgonDone = 0; /* Вычисляем выход PID */ arm_pid_reset_f32(&hangle->pid); @@ -126,6 +131,7 @@ void Angle_PID_Reset(Angle_Handle_t *hangle) Angle_SetAlpha(hangle, 1, 30); // максимально закрываем + Angle_Reset(hangle, UPP_PHASE_A); Angle_Reset(hangle, UPP_PHASE_B); Angle_Reset(hangle, UPP_PHASE_C); diff --git a/UPP/Core/UPP/angle_control.h b/UPP/Core/UPP/angle_control.h index d957c96..fe27daa 100644 --- a/UPP/Core/UPP/angle_control.h +++ b/UPP/Core/UPP/angle_control.h @@ -37,8 +37,9 @@ typedef struct FilterExp_t refFilter; ///< Фильтр для плавного нарастания регулирования struct { - unsigned Initialized : 1; ///< Структура инициализирована - unsigned Running : 3; ///< Сколько каналов запущено сейчас + unsigned Initialized : 1; ///< Структура инициализирована + unsigned Running : 3; ///< Сколько каналов запущено сейчас + unsigned RazgonDone : 1; ///< Флаг что идет разгон Iref } f; ///< Флаги }Angle_Handle_t; diff --git a/UPP/Core/UPP/pwm_thyristors.c b/UPP/Core/UPP/pwm_thyristors.c index ff3c946..38ee66a 100644 --- a/UPP/Core/UPP/pwm_thyristors.c +++ b/UPP/Core/UPP/pwm_thyristors.c @@ -127,13 +127,13 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_ if(force_stop_all) { // в первую очередь выключаем канал, потом выставим режим каналов - __HAL_TIM_MOE_DISABLE(&hpwm1); - __HAL_TIM_MOE_DISABLE(&hpwm2); + __HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(&hpwm1); + __HAL_TIM_MOE_DISABLE_UNCONDITIONALLY(&hpwm2); - // выставляем все каналы в FORCE MODE for(int ch = 0; ch < 6; ch++) { + hpwm->AllPhases[ch].State = PWM_THYR_DISABLED; __PWM_SetOutputState(&hpwm->AllPhases[ch], PWM_DISABLE); } return HAL_OK; @@ -141,7 +141,6 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_ // Если НЕ force_stop_all - сбрасываем ТОЛЬКО заданный канал else { - // Если не force_stop_all - сбрасываем только текущий канал __PWM_SetOutputState(hpwm->Phase[Phase], PWM_DISABLE); return HAL_OK; } @@ -294,7 +293,7 @@ HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm, float PeriodMs) break; case PWM_THYR_TIM_DONE: // пачка импульсов отправлена - отключение - hPhase->State = PWM_THYR_TIM_WAIT; + hPhase->State = PWM_THYR_DISABLED; if(hpwm->f.Running) hpwm->f.Running--; break; diff --git a/UPP/Core/UPP/upp_errors.c b/UPP/Core/UPP/upp_errors.c index 936a308..7454baf 100644 --- a/UPP/Core/UPP/upp_errors.c +++ b/UPP/Core/UPP/upp_errors.c @@ -77,7 +77,7 @@ void UPP_Errors_Power(void) void UPP_Errors_Ranges(void) { /* Преобразуем уставки в нормальные тики */ - float ticksTiMax = u2f(PARAM_PUI->TiMax, 1)/PM_SLOW_PERIOD_US; + float ticksTiMax = PARAM_PUI->TiMax/PM_SLOW_PERIOD_US; /* Счетчики для отсчитывания задержки выставления ошибки */ static int IMaxCnt = 0; static int UMaxCnt = 0; @@ -235,8 +235,8 @@ __STATIC_FORCEINLINE int setError(int condition, int flag, int *timer, int delay } else { if (*timer > 0) (*timer)--; - else - flag = 0; +// else +// flag = 0; } return flag; diff --git a/UPP/Core/UPP/upp_errors.h b/UPP/Core/UPP/upp_errors.h index ba3e32b..9baae7a 100644 --- a/UPP/Core/UPP/upp_errors.h +++ b/UPP/Core/UPP/upp_errors.h @@ -16,37 +16,41 @@ */ static const uint8_t UPP_ErrorPriority[] = { - [Err_None] = 255, + [Err_None] = 255, - /* Фатальные ошибки */ - [Err_LossPhaseAll] = 1, - [Err_OverCurrent] = 2, - [Err_OverVoltage] = 3, - [Err_OverTemperature] = 4, - [Err_Power_24V] = 5, - [Err_Power_Digit_5V] = 6, - [Err_Power_DIO_24V] = 7, - [Err_Power_Analog_5V] = 8, + /* Фатальные ошибки */ + [Err_OverCurrent] = 1, + [Err_OverVoltage] = 2, + [Err_UnderVoltage] = 3, + [Err_OverFrequency] = 4, + [Err_UnderFrequency] = 5, - /* Критичные */ - [Err_LossPhaseA] = 10, - [Err_LossPhaseB] = 11, - [Err_LossPhaseC] = 12, - [Err_LongStart] = 13, - [Err_Interlace] = 14, + [Err_Power_24V] = 4, + [Err_Power_Digit_5V] = 5, + [Err_Power_DIO_24V] = 6, + [Err_Power_Analog_5V] = 7, - /* Пограничные параметры */ - [Err_UnderVoltage] = 20, - [Err_OverFrequency] = 21, - [Err_UnderFrequency] = 22, - /* Внутренние */ - [Err_Internal_1] = 40, - [Err_Internal_2] = 41, - [Err_Internal_3] = 42, - [Err_Internal_4] = 43, - [Err_Internal_5] = 44, - [Err_Internal_6] = 45, + + /* Просто ошибки */ + [Err_LongStart] = 21, + [Err_Interlace] = 22, + [Err_OverTemperature] = 23, + + + /* Внутренние */ + [Err_Internal_1] = 41, + [Err_Internal_2] = 42, + [Err_Internal_3] = 43, + [Err_Internal_4] = 44, + [Err_Internal_5] = 45, + [Err_Internal_6] = 46, + + /* Если ток потерян и других ошибок нет - фаза потеряна */ + [Err_LossPhaseAll] = 24, + [Err_LossPhaseA] = 25, + [Err_LossPhaseB] = 26, + [Err_LossPhaseC] = 27, }; diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c index df03fa9..1122afc 100644 --- a/UPP/Core/UPP/upp_main.c +++ b/UPP/Core/UPP/upp_main.c @@ -94,20 +94,19 @@ int UPP_While(void) upp.Timings.slow_calc_prd_us = BenchTime_Period(BT_SLOWCALC_PRD, angletim.Instance->CNT, HAL_MAX_DELAY)/ANGLE_TIM2_FREQ_MHZ; BenchTime_Start(BT_SLOWCALC, angletim.Instance->CNT, HAL_MAX_DELAY); res = HAL_IWDG_Refresh(&hiwdg); // если не вызываются медленные расчеты - что-то не то сбрасываемся по watchdog - - int razgon_done = (fabsf(upp.hangle.Iref - u2f(PARAM_PUI->Iref, 100)) < 0.1); - + // Медленные расчеты PowerMonitor_SlowCalc(&upp.pm); + // Защиты // Защиты по току включаем только после разгона и в режиме работы + PowerMonitor_Protect(&upp.pm, upp.hangle.f.RazgonDone /*&& (upp.workmode == UPP_Work)*/); + #ifdef UPP_SIMULATE_I // симулируем токи upp.pm.measured.final.Iamp = upp.hangle.Iref/2; // При симуляции тока не включаем его проверку razgon_done = 0; #endif - // Защиты // Определенные защиты по току включаем только после разгона - PowerMonitor_Protect(&upp.pm, razgon_done); // Обрабока ошибок и выставление итоговой Ошибки UPP_Errors_Handle(); // Контроль парамеров @@ -282,7 +281,6 @@ void UPP_ADC_Handle(void) upp.pm.f.inIsr = 1; PowerMonitor_FastCalc(&upp.pm); - for(int phase = 0; phase < 3; phase++) { @@ -297,8 +295,8 @@ void UPP_ADC_Handle(void) UPP_HalfWave_t curr_halfwave = ZC_GetHalfWave(&upp.pm.zc, phase); res = PWM_SetHalfWave(&upp.hpwm, phase, curr_halfwave); // Начинаем отсчитывать угол - int voltage_halfwave_period = 1.0f/(upp.pm.measured.final.F[phase]*2)*1000; - res = Angle_Start(&upp.hangle, phase, voltage_halfwave_period); + int voltage_halfwave_period_ms = 1.0f/(upp.pm.measured.final.F[phase]*2)*1000; + res = Angle_Start(&upp.hangle, phase, voltage_halfwave_period_ms); if(res != HAL_OK) __NOP(); } @@ -306,7 +304,8 @@ void UPP_ADC_Handle(void) } // ШИМим ключи - res = PWM_Handle(&upp.hpwm, 10); + int voltage_halfwave_period_ms_mean = 1.0f/(upp.pm.measured.final.Fmean*2)*1000; + res = PWM_Handle(&upp.hpwm, voltage_halfwave_period_ms_mean); upp.Timings.isr_adc_us = BenchTime_End(BT_ADC, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ; upp.pm.f.inIsr = 0; diff --git a/UPP/Core/UPP/upp_params.c b/UPP/Core/UPP/upp_params.c index 7bea2bd..05333bf 100644 --- a/UPP/Core/UPP/upp_params.c +++ b/UPP/Core/UPP/upp_params.c @@ -220,6 +220,7 @@ void UPP_Params_ControlInternal(void) } + PARAM_INTERNAL->pm.lImaxAmp = ((u2f(PARAM_PUI->Imax, 100) * 50 / u2f(PARAM_INTERNAL->nominal.I, 10)) *1.41)*100; // Амплитудное значение Imax // Обновление регулятора угла открытия if(alpha_update) { diff --git a/UPP/Core/UPP/upp_params.h b/UPP/Core/UPP/upp_params.h index 06caf58..a944f25 100644 --- a/UPP/Core/UPP/upp_params.h +++ b/UPP/Core/UPP/upp_params.h @@ -66,8 +66,9 @@ typedef struct /* Параметры Мониторинга напряжения */ struct { - uint16_t rms_window_size; ///< Адрес 1030: Размер окна для RMS - uint16_t rms_exp_alpha; ///< Адрес 1031: Постоянная времени для сглаживания RMS + uint16_t lImaxAmp; ///< Адрес 1031: Амплитудное значение максимально допустимого тока (рассчитывается само) + uint16_t rms_window_size; ///< Адрес 1032: Размер окна для RMS + uint16_t rms_exp_alpha; ///< Адрес 1033: Постоянная времени для сглаживания RMS }pm; /* Параметры ШИМ */ diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx index 2f1f9f3..9c4b273 100644 --- a/UPP/MDK-ARM/UPP.uvoptx +++ b/UPP/MDK-ARM/UPP.uvoptx @@ -335,24 +335,7 @@ UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024 -FS08000000 -FL0100000 -FP0($$Device:STM32F417ZGTx$CMSIS\Flash\STM32F4xx_1024.FLM)) - - - 0 - 0 - 38 - 1 -
134219914
- 0 - 0 - 0 - 0 - 0 - 1 - ..\Core\PowerMonitor\adc_tools.c - - \\Debug_F417\../Core/PowerMonitor/adc_tools.c\38 -
-
+ 0 @@ -394,6 +377,11 @@ 1 phase_table + + 8 + 1 + hbt,0x0A + 0 diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx index 1757519..eef2e93 100644 --- a/UPP/MDK-ARM/UPP.uvprojx +++ b/UPP/MDK-ARM/UPP.uvprojx @@ -1750,6 +1750,57 @@ power_protect.c 1 ..\Core\PowerMonitor\power_protect.c + + + 2 + 0 + 0 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + 11 + + + 1 + + + + 2 + 5 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 0 + 2 + 2 + 2 + 2 + 2 + 0 + 0 + 2 + 2 + 2 + 2 + 2 + + + + + + + + + power_protect.h diff --git a/MATLAB/calc_filt.m b/Информация для программиста (УПП СП СЭД)/CALC/calc_filt.m similarity index 100% rename from MATLAB/calc_filt.m rename to Информация для программиста (УПП СП СЭД)/CALC/calc_filt.m diff --git a/MATLAB/calc_pi.m b/Информация для программиста (УПП СП СЭД)/CALC/calc_pi.m similarity index 100% rename from MATLAB/calc_pi.m rename to Информация для программиста (УПП СП СЭД)/CALC/calc_pi.m