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