diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_dma.c b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_dma.c
index 7a85299..f6bb6fd 100644
--- a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_dma.c
+++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_dma.c
@@ -95,16 +95,76 @@ void DMA_Sim_Transfer(DMA_TypeDef* DMAx, uint32_t stream)
stream_sim->current_index++;
- // Проверяем завершение передачи
+ // Определяем какой регистр использовать (LISR или HISR) в зависимости от потока
+ volatile uint32_t* lisr_reg = NULL;
+ volatile uint32_t* hisr_reg = NULL;
+ uint32_t tcif_mask = 0;
+ uint32_t htif_mask = 0;
+
+ // Настраиваем маски флагов в зависимости от потока
+ if (DMAx == DMA1) {
+ lisr_reg = &DMA1->LISR;
+ hisr_reg = &DMA1->HISR;
+ }
+#ifdef DMA2
+ else if (DMAx == DMA2) {
+ lisr_reg = &DMA2->LISR;
+ hisr_reg = &DMA2->HISR;
+ }
+#endif
+
+ // Устанавливаем маски для конкретного потока
+ switch (stream) {
+ case 0:
+ case 4:
+ tcif_mask = DMA_FLAG_TCIF0_4; htif_mask = DMA_FLAG_HTIF0_4; break;
+ case 1:
+ case 5:
+ tcif_mask = DMA_FLAG_TCIF1_5; htif_mask = DMA_FLAG_HTIF1_5; break;
+ case 2:
+ case 6:
+ tcif_mask = DMA_FLAG_TCIF2_6; htif_mask = DMA_FLAG_HTIF2_6; break;
+ case 3:
+ case 7:
+ tcif_mask = DMA_FLAG_TCIF3_7; htif_mask = DMA_FLAG_HTIF3_7; break;
+ };
+
+ // Проверяем и выставляем флаги
+ if (stream_sim->current_index == stream_sim->buffer_size / 2) {
+ // Половинное заполнение - выставляем флаг HTIF
+ if (stream < 4) {
+ *lisr_reg |= htif_mask; // Потоки 0-3 в LISR
+ }
+ else {
+ *hisr_reg |= htif_mask; // Потоки 4-7 в HISR
+ }
+
+ // Вызываем обработчик прерывания
+ //DMA_Call_IRQHandller(DMAx, stream); //todo
+ }
+
if (stream_sim->current_index >= stream_sim->buffer_size) {
+ // Полное заполнение - выставляем флаг TCIF
+ if (stream < 4) {
+ *lisr_reg |= tcif_mask; // Потоки 0-3 в LISR
+ }
+ else {
+ *hisr_reg |= tcif_mask; // Потоки 4-7 в HISR
+ }
+
stream_sim->transfer_complete = 1;
+
if (stream_sim->circular_mode) {
stream_sim->current_index = 0;
- } else {
+ // В циклическом режиме не сбрасываем флаги - они должны быть сброшены программно
+ }
+ else {
stream_sim->transfer_enabled = 0;
stream_sim->enabled = 0;
- DMA_Call_IRQHandller(DMAx, stream);
}
+
+ // Вызываем обработчик прерывания
+ DMA_Call_IRQHandller(DMAx, stream);
}
}
diff --git a/MATLAB/app_wrapper/app_io.c b/MATLAB/app_wrapper/app_io.c
index fa2bff6..8a51993 100644
--- a/MATLAB/app_wrapper/app_io.c
+++ b/MATLAB/app_wrapper/app_io.c
@@ -84,6 +84,12 @@ void Write_PowerMonitor(real_T* Buffer, int ind_port)
WriteOutputArray(upp.pm.measured.final.I[2], ind_port, nn++);
WriteOutputArray(upp.pm.measured.final.Fmean, ind_port, nn++);
}
+
+ { //20-21
+ WriteOutputArray(upp.pm.isr_cnt, ind_port, nn++);
+ WriteOutputArray(upp.pm.slow_cnt, ind_port, nn++);
+ }
+
}
@@ -123,7 +129,7 @@ void app_readInputs(const real_T* Buffer) {
MB_INTERNAL.param.angle.PID_Kp = ReadInputArray(1, 4) * 10000;
MB_INTERNAL.param.angle.PID_Ki = ReadInputArray(1, 5) * 10000;
MB_INTERNAL.param.angle.PID_Kd = ReadInputArray(1, 6) * 10000;
- MB_INTERNAL.param.angle.PID_ExpAlpha = ReadInputArray(1, 7) * 65535;
+ MB_DATA.HoldRegs.pui_params.Tnt = ReadInputArray(1, 7) * 1000;
MB_INTERNAL.param.nominal.U = ReadInputArray(1, 8) * 10;
MB_INTERNAL.param.nominal.I = ReadInputArray(1, 9) * 10;
diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx
index 3864d75..1e5c793 100644
Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ
diff --git a/UPP/AllLibs/MyLibs b/UPP/AllLibs/MyLibs
index 513f56f..30fdbc3 160000
--- a/UPP/AllLibs/MyLibs
+++ b/UPP/AllLibs/MyLibs
@@ -1 +1 @@
-Subproject commit 513f56fe7dbf0fa8e6a075c22e138c908a01d33f
+Subproject commit 30fdbc35ddb1a72a5102aece8863921af0e4078d
diff --git a/UPP/AllLibs/PeriphGeneral b/UPP/AllLibs/PeriphGeneral
index 11c00f1..c0733a1 160000
--- a/UPP/AllLibs/PeriphGeneral
+++ b/UPP/AllLibs/PeriphGeneral
@@ -1 +1 @@
-Subproject commit 11c00f1e0c94ebd2cae77e17453005e32dfe5a3c
+Subproject commit c0733a1d31ebd7b334dee6b1a8c2b00767fdbfca
diff --git a/UPP/Core/Configs/mylibs_config.h b/UPP/Core/Configs/mylibs_config.h
index 11c8233..b92e13c 100644
--- a/UPP/Core/Configs/mylibs_config.h
+++ b/UPP/Core/Configs/mylibs_config.h
@@ -97,12 +97,14 @@
#define BENCH_TIME_ENABLE ///< Включить бенч времени
-#define BENCH_TIME_MAX_CHANNELS 5 ///< Максимальное количество каналов измерения
+#define BENCH_TIME_MAX_CHANNELS 6 ///< Максимальное количество каналов измерения
-#define BT_SLOWCALC 0
-#define BT_ADC 1
-#define BT_PWM 2
-#define BT_SYSTICK 3
+#define BT_SLOWCALC_PRD 0
+#define BT_SLOWCALC 1
+#define BT_ADC 2
+#define BT_ADC_PRD 3
+#define BT_PWM 4
+#define BT_SYSTICK 5
/** GEN_CONFIG
* @}
*/
diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h
index 94aae73..aac2abc 100644
--- a/UPP/Core/Configs/upp_config.h
+++ b/UPP/Core/Configs/upp_config.h
@@ -62,6 +62,7 @@
/* Параметры ПУИ */
#define PUI_Iref_PERCENT_DEFAULT 1.5
#define PUI_Tnt_MS_DEFAULT 300
+#define PUI_Tnt_CalcAlpha(...) FilterExp_CalcAlpha95(__VA_ARGS__) ///< Уровень в процентах, до куда нарастет ток за время Tnt
#define PUI_Umin_PERCENT_DEFAULT 0.8
#define PUI_Umax_PERCENT_DEFAULT 1.2
#define PUI_Imax_PERCENT_DEFAULT 0.99
@@ -83,7 +84,6 @@
#define ANGLE_PID_KP_COEF_DEFAULT 0.0001
#define ANGLE_PID_KI_COEF_DEFAULT 0.0001
#define ANGLE_PID_KD_COEF_DEFAULT 0
-#define ANGLE_REF_TAU_COEF_DEFAULT 20.0
/* Параметри мониторинга сети */
#define PM_EXP_TAU_COEF_DEFAULT 0.05
@@ -99,8 +99,9 @@
#define ZERO_CROSS_DEBOUNCE_CNT_DEFAULT 2*100 // (2.5 * 100 = 2.5 мс)
/* Параметры ШИМ для тиристоров */
-#define PWM_THYR_FREQUENCY_HZ_DEFAULT 5000
-#define PWM_THYR_PULSE_NUMBER_DEFAULT 5
+#define PWM_THYR_FREQUENCY_HZ_DEFAULT 16000
+#define PWM_THYR_DUTY_PERCENT_DEFAULT 0.5
+#define PWM_THYR_PULSE_NUMBER_DEFAULT 20
/** //UPP_PARAMS_DEFAULT
* @}
@@ -115,11 +116,11 @@
*/
/* Периоды обновления всякого */
-#define PM_ADC_PERIOD_US 30 ///< Период опроса АЦП в мкс
-#define PM_SLOW_PERIOD_US 500 ///< Период обновления медленных расчетов в мкс (чтобы делилось на @ref PM_ADC_PERIOD_US)
-#define PM_TEMP_SLOW_PERIOD_MS 1000 ///< Период опроса АЦП в мс
-#define PM_F_SLOW_PERIOD_MS 40 ///< Период обновления частоты в мс
-#define UPP_INIT_BEFORE_READY_MS 2000 ///< Сколько сканировать сеть, перед выставлением состояния готовности
+#define PM_ADC_PERIOD_US 25 ///< Период опроса АЦП в мкс
+#define PM_SLOW_PERIOD_US 500 ///< Период обновления медленных расчетов в мкс (чтобы делилось на @ref PM_ADC_PERIOD_US)
+#define PM_TEMP_SLOW_PERIOD_MS 1000 ///< Период обновлениия (фильтрации) датчиков температуры в мс
+#define PM_F_SLOW_PERIOD_MS 40 ///< Период обновления (фильтрации) частоты в мс
+#define UPP_INIT_BEFORE_READY_MS 2000 ///< Сколько сканировать сеть, перед выставлением состояния готовности
/* Частоты таймеров в МГц*/
#define PWM_TIM1_FREQ_MHZ 180 ///< Частота тиков таймера ШИМ (1-4 каналы)
@@ -128,19 +129,32 @@
#define ADC_TIM3_FREQ_MZH 90 ///< Частота тиков таймера АЦП
#define ANGLE_TIM2_FREQ_MHZ 90 ///< Частота тиков таймера отсчета угла открытия тиристоров
+/** //UPP_COMPILED_PARAMS
+ * @}
+ */
// ===== ОТЛАДОЧНЫЕ ШТУКИ ДЛЯ 417 ======
#if defined(STM32F417xx)
+
+// У старой платы УПП другие диапазоны датчиков
+#undef ADC_U_MAX_V_DEFAULT
+#undef ADC_I_MAX_A_DEFAULT
+
+#define ADC_U_MAX_V_DEFAULT 707.11
+#define ADC_I_MAX_A_DEFAULT 424.26
+
+
+
+// У 417 меньше частота поэтому меняем прескалер
#undef PWM_TIM1_FREQ_MHZ
#undef PWM_TIM8_FREQ_MHZ
#undef US_TIM5_FREQ_MHZ
#undef ADC_TIM3_FREQ_MZH
#undef ANGLE_TIM2_FREQ_MHZ
-// У 417 меньше частота поэтому меняем прескалер
#define PWM_TIM1_FREQ_MHZ 168 ///< Частота тиков таймера ШИМ (1-4 каналы)
#define PWM_TIM8_FREQ_MHZ 168 ///< Частота тиков таймера ШИМ (5-6 каналы)
#define US_TIM5_FREQ_MHZ 84 ///< Частота тиков микросекундного таймера
@@ -148,9 +162,10 @@
#define ANGLE_TIM2_FREQ_MHZ 84 ///< Частота тиков таймера отсчета угла открытия тиристоров
#define HAL_PWREx_EnableOverDrive() HAL_ERROR
-#endif
-// ===== ОТЛАДОЧНЫЕ ШТУКИ ДЛЯ MATLAB ======
+#endif //defined(STM32F417xx)
+
+// ===== ОТЛАДОЧНЫЕ ШТУКИ ДЛЯ MATLAB ======
#if defined(MATLAB)
#undef UPP_INIT_BEFORE_READY_MS
@@ -158,8 +173,5 @@
#define UPP_INIT_BEFORE_READY_MS 100 ///< Сколько сканировать сеть, перед выставлением состояния готовности
-#endif
-/** //UPP_COMPILED_PARAMS
- * @}
- */
+#endif //defined(MATLAB)
#endif //_UPP_CONFIG_H_
diff --git a/UPP/Core/Configs/upp_defs.h b/UPP/Core/Configs/upp_defs.h
index dd055dc..c0afca5 100644
--- a/UPP/Core/Configs/upp_defs.h
+++ b/UPP/Core/Configs/upp_defs.h
@@ -158,8 +158,7 @@ typedef struct {
/* Перерасчеты в тики */
#define ANGLE_PERIOD_MS(_freq_) (((float)1/(_freq_*2))*1000) ///< Период обновления частоты в тиках @ref PM_SLOW_PERIOD_CNT
-/* Расчет коэффициента альфа для экспоненциального фильтра */
-#define CALC_TAU_COEF(tau, TsUs) (((float)TsUs/1000000) / (((float)TsUs/1000000) + (tau)))
+#define SQRT2 1.4142135
/* Дефайны для "удобного" доступа к структурам */
#define PARAM_INTERNAL MB_INTERNAL.param
diff --git a/UPP/Core/PowerMonitor/adc_tools.c b/UPP/Core/PowerMonitor/adc_tools.c
index f959c46..a84dfc9 100644
--- a/UPP/Core/PowerMonitor/adc_tools.c
+++ b/UPP/Core/PowerMonitor/adc_tools.c
@@ -104,7 +104,7 @@ HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, float PeriodUs)
HAL_TIM_Base_Stop(adc->htim);
// Запускаем таймер который будет запускать опрос АЦП с заданным периодом
- __HAL_TIM_SET_AUTORELOAD_FORCE(adc->htim, TIM_MicrosToTick(PeriodUs, ADC_TIM3_FREQ_MZH-1));
+ __HAL_TIM_SET_AUTORELOAD_FORCE(adc->htim, TIM_MicrosToTick(PeriodUs, ADC_TIM3_FREQ_MZH));
res = HAL_TIM_Base_Start(adc->htim);
if(res != HAL_OK)
diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c
index 9c82526..1f70473 100644
--- a/UPP/Core/PowerMonitor/power_monitor.c
+++ b/UPP/Core/PowerMonitor/power_monitor.c
@@ -162,15 +162,17 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
/* Средниее напряжение фазы */
uphase_mean = fabsf(meas->slow.U[i]);
- meas->final.U[i] = Filter_Process(&hpm->exp[EXP_UBA+i], uphase_mean);
+ uphase_mean = Filter_Process(&hpm->exp[EXP_UBA+i], uphase_mean);
+ meas->final.U[i] = uphase_mean*PI/2/SQRT2; /*PI/2 - получить амплитудное, SQRT2 - получить действующее */
/* Средний ток фазы */
iphase_mean = fabsf(meas->slow.I[i]);
- meas->final.I[i] = Filter_Process(&hpm->exp[EXP_IC+i], iphase_mean);
+ iphase_mean = Filter_Process(&hpm->exp[EXP_IC+i], iphase_mean)*PI/2;
+ meas->final.I[i] = iphase_mean*PI/2/SQRT2; /*PI/2 - получить амплитудное, SQRT2 - получить действующее */
/* Реальные единицы измерения (Вольты/Амперы) */
- meas->real.I[i] = meas->slow.I[i]*i_base;
- meas->real.U[i] = meas->slow.U[i]*u_base;
+ meas->real.I[i] = meas->final.I[i]*i_base;
+ meas->real.U[i] = meas->final.U[i]*u_base;
}
/* Получение средней частоты по трем фазам */
meas->final.Fmean = fmean / 3;
@@ -186,12 +188,13 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
/* Расчет амплитуд трехфазной сети */
- float uamp = vector_abs_linear_calc(meas->slow.U[U_BA], meas->slow.U[U_AC]);
- float iamp = vector_abs_phase_calc(meas->slow.I[I_A], meas->slow.I[I_C]);
+ float uamp = vector_abs_linear_calc(meas->slow.U[U_BA], meas->slow.U[U_AC])/SQRT2; /* SQRT2 - получить действующее */
+ float iamp = vector_abs_phase_calc(meas->slow.I[I_A], meas->slow.I[I_C])/SQRT2; /* SQRT2 - получить действующее */
meas->final.Uamp = Filter_Process(&hpm->exp[EXP_U], uamp);
meas->final.Iamp = Filter_Process(&hpm->exp[EXP_I], iamp);
-
+
+ hpm->slow_cnt++;
}
/**
diff --git a/UPP/Core/PowerMonitor/power_monitor.h b/UPP/Core/PowerMonitor/power_monitor.h
index ee343ff..b0a4872 100644
--- a/UPP/Core/PowerMonitor/power_monitor.h
+++ b/UPP/Core/PowerMonitor/power_monitor.h
@@ -80,11 +80,11 @@ typedef struct
float I[3]; ///< Ток
}slow;
- /** @brief Реальные величины - обновляются кто где, и содержат значения в В/А */
+ /** @brief Реальные величины - обновляются в main в @ref PowerMonitor_SlowCalc, и содержат значения в В/А */
struct
{
- float U[3]; ///< Напряжение (обновляется в прерывании АЦП)
- float I[3]; ///< Ток (обновляется в прерывании АЦП)
+ float U[3]; ///< Напряжение (Действующее)
+ float I[3]; ///< Ток (Действующее)
}real;
}PowerMonitor_Measured_t;
@@ -104,6 +104,7 @@ typedef struct
PowerMonitor_Flags_t f; ///< Флаги мониторинга
uint32_t isr_cnt;
+ uint32_t slow_cnt;
}PowerMonitor_t;
extern PowerMonitor_t pm;
diff --git a/UPP/Core/Src/main.c b/UPP/Core/Src/main.c
index 64019f9..e231ae7 100644
--- a/UPP/Core/Src/main.c
+++ b/UPP/Core/Src/main.c
@@ -80,6 +80,7 @@ int main(void)
__HAL_FREEZE_TIM8_DBGMCU();
__HAL_FREEZE_TIM11_DBGMCU();
__HAL_FREEZE_TIM12_DBGMCU();
+ __HAL_FREEZE_TIM14_DBGMCU();
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
diff --git a/UPP/Core/Src/stm32f4xx_it.c b/UPP/Core/Src/stm32f4xx_it.c
index 526ec8a..974357c 100644
--- a/UPP/Core/Src/stm32f4xx_it.c
+++ b/UPP/Core/Src/stm32f4xx_it.c
@@ -238,6 +238,10 @@ void TIM2_IRQHandler(void)
void TIM8_TRG_COM_TIM14_IRQHandler(void)
{
/* USER CODE BEGIN TIM8_TRG_COM_TIM14_IRQn 0 */
+ if (__HAL_TIM_GET_FLAG(&htim8, TIM_FLAG_UPDATE) != RESET) {
+ UPP_PWM_Handle();
+ }
+
#ifndef MATLAB // в матлабе нет htim14, т.к. это систем тики
/* USER CODE END TIM8_TRG_COM_TIM14_IRQn 0 */
HAL_TIM_IRQHandler(&htim8);
@@ -253,11 +257,14 @@ void TIM8_TRG_COM_TIM14_IRQHandler(void)
void DMA2_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream0_IRQn 0 */
-
+ // Вторая половина буфера (Transfer Complete)
+ if (DMA2->LISR & DMA_LISR_TCIF0) {
+ UPP_ADC_Handle();
+ }
/* USER CODE END DMA2_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc3);
/* USER CODE BEGIN DMA2_Stream0_IRQn 1 */
- UPP_ADC_Handle();
+
/* USER CODE END DMA2_Stream0_IRQn 1 */
}
diff --git a/UPP/Core/Src/tim.c b/UPP/Core/Src/tim.c
index 97a009e..1f5a7d0 100644
--- a/UPP/Core/Src/tim.c
+++ b/UPP/Core/Src/tim.c
@@ -209,7 +209,7 @@ void MX_TIM3_Init(void)
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
- sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
+ sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
{
Error_Handler();
diff --git a/UPP/Core/UPP/angle_control.c b/UPP/Core/UPP/angle_control.c
index 1d4e3ff..6efb442 100644
--- a/UPP/Core/UPP/angle_control.c
+++ b/UPP/Core/UPP/angle_control.c
@@ -21,12 +21,6 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle)
hangle->htim = &angletim;
- // Инициализация ПИД
- float kp = to_float(PARAM_INTERNAL.angle.PID_Kp, 10000);
- float ki = to_float(PARAM_INTERNAL.angle.PID_Ki, 10000);
- float kd = to_float(PARAM_INTERNAL.angle.PID_Kd, 10000);
- float ref_alpha = to_float(PARAM_INTERNAL.angle.PID_ExpAlpha, 65535);
- Angle_PID_Init(hangle, kp, ki, kd, ref_alpha);
// Инициализация каналов
HAL_TIM_OC_Start_IT(hangle->htim, ANGLE_CHANNEL_1);
@@ -43,7 +37,14 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle)
float angle_min = to_float(PARAM_INTERNAL.angle.Angle_Min, 65535);
hangle->f.Initialized = 1;
- return HAL_OK;
+
+ // Инициализация ПИД
+ float kp = to_float(PARAM_INTERNAL.angle.PID_Kp, 10000);
+ float ki = to_float(PARAM_INTERNAL.angle.PID_Ki, 10000);
+ float kd = to_float(PARAM_INTERNAL.angle.PID_Kd, 10000);
+ float ref_alpha = PUI_Tnt_CalcAlpha(to_float(PARAM_PUI.Tnt, 1000), PM_SLOW_PERIOD_US);
+
+ return Angle_PID_Init(hangle, kp, ki, kd, ref_alpha);;
}
@@ -52,10 +53,10 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle)
* @param hangle Указатель на таймер
* @param kp, ki kd Коэффициенты регулятора
*/
-void Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float alpha)
+HAL_StatusTypeDef Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float alpha)
{
if(assert_upp(hangle))
- return;
+ return HAL_ERROR;
// Сам ПИД регулятор
hangle->pid.Kp = kp;
@@ -67,6 +68,8 @@ void Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float
FilterExp_Init(&hangle->refFilter, alpha);
Filter_Start(&hangle->refFilter);
Filter_Process(&hangle->refFilter, 0);
+
+ return HAL_OK;
}
/**
diff --git a/UPP/Core/UPP/angle_control.h b/UPP/Core/UPP/angle_control.h
index 9b72f8b..6017e54 100644
--- a/UPP/Core/UPP/angle_control.h
+++ b/UPP/Core/UPP/angle_control.h
@@ -44,7 +44,7 @@ typedef struct
/* Инициализация Таймера для рассчета угла открытия. */
HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle);
/* Инициализация ПИД регулятора. */
-void Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float alpha);
+HAL_StatusTypeDef Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float alpha);
// ====== УПРАВЛЕНИЕ ==========
/* Управление углом через ПИД регулятор */
diff --git a/UPP/Core/UPP/pwm_thyristors.c b/UPP/Core/UPP/pwm_thyristors.c
index dc47ed3..e9f8245 100644
--- a/UPP/Core/UPP/pwm_thyristors.c
+++ b/UPP/Core/UPP/pwm_thyristors.c
@@ -59,7 +59,10 @@ HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm)
PWM_SetHalfWave(hpwm, UPP_PHASE_B, UPP_WAVE_UNKNOWED);
PWM_SetHalfWave(hpwm, UPP_PHASE_C, UPP_WAVE_UNKNOWED);
- PWM_SetConfig(hpwm, PARAM_INTERNAL.pwm.PhaseMask, PARAM_INTERNAL.pwm.Frequency, PARAM_INTERNAL.pwm.PulseNumber);
+ PWM_SetConfig(hpwm, PARAM_INTERNAL.pwm.PhaseMask,
+ PARAM_INTERNAL.pwm.Frequency,
+ to_float(PARAM_INTERNAL.pwm.Duty, 100),
+ PARAM_INTERNAL.pwm.PulseNumber);
HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_1);
HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_2);
@@ -154,7 +157,6 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_
{
// в первую очередь выключаем канал, потом выставим режим каналов
__HAL_TIM_MOE_DISABLE(&hpwm1);
- // в первую очередь выключаем канал, потом выставим режим каналов
__HAL_TIM_MOE_DISABLE(&hpwm2);
@@ -197,7 +199,7 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_
* @param Frequency Частота в ГЦ
* @return HAL Status.
*/
-HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, uint8_t PulseNumber)
+HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, uint8_t PulseNumber)
{
if(assert_upp(hpwm))
return HAL_ERROR;
@@ -210,16 +212,19 @@ HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t
hpwm->Config.PhaseMask.all = PhaseMask;
hpwm->Config.PulseNumber = PulseNumber;
hpwm->Config.Frequency = Frequency;
+ hpwm->Config.Duty = Duty;
// Высставление периодов
__HAL_TIM_SET_AUTORELOAD(&hpwm1, TIM_FreqToTick(Frequency, PWM_TIM1_FREQ_MHZ-1));
__HAL_TIM_SET_AUTORELOAD(&hpwm2, TIM_FreqToTick(Frequency, PWM_TIM8_FREQ_MHZ-1));
- // Скважности 50/50
- __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_1, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2);
- __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_2, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2);
- __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_3, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2);
- __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_4, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2);
- __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_5, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2);
- __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_6, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2);
+ // Скважности
+ uint32_t pwm1_duty_ccr = (float)__HAL_TIM_GET_AUTORELOAD(&hpwm1)*(1-Duty);
+ uint32_t pwm2_duty_ccr = (float)__HAL_TIM_GET_AUTORELOAD(&hpwm2)*(1-Duty);
+ __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_1, pwm1_duty_ccr);
+ __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_2, pwm1_duty_ccr);
+ __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_3, pwm1_duty_ccr);
+ __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_4, pwm1_duty_ccr);
+ __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_5, pwm2_duty_ccr);
+ __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_6, pwm2_duty_ccr);
// Сброс счетчиков таймера и запуск заного
diff --git a/UPP/Core/UPP/pwm_thyristors.h b/UPP/Core/UPP/pwm_thyristors.h
index c35c208..ee1075b 100644
--- a/UPP/Core/UPP/pwm_thyristors.h
+++ b/UPP/Core/UPP/pwm_thyristors.h
@@ -74,6 +74,7 @@ typedef struct {
}PhaseMask; ///< Какими каналами управлять
uint8_t PulseNumber; ///< Сколько импульсов отправить в пакете для открытия тиристоров
uint16_t Frequency; ///< Частота импульсов
+ float Duty; ///< Скважность импульсов
} PWM_ThyrConfig_t;
/**
@@ -100,7 +101,7 @@ HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase);
/* Остановить ШИМ. */
HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop_all);
/* Установка частоты ШИМ. */
-HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, uint8_t PulseNumber);
+HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, uint8_t PulseNumber);
/* Установка полуволны для слежения. */
HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave);
/* Установка полярности шим. */
diff --git a/UPP/Core/UPP/upp_errors.c b/UPP/Core/UPP/upp_errors.c
index 0afb1c0..d5a269b 100644
--- a/UPP/Core/UPP/upp_errors.c
+++ b/UPP/Core/UPP/upp_errors.c
@@ -19,7 +19,7 @@
UPP_Errors_t errors;
static UPP_ErrorType_t UPP_SelectCommonError(void);
-static int setError(int condition, int flag, int *timer, int delay);
+__STATIC_FORCEINLINE int setError(int condition, int flag, int *timer, int delay);
void UPP_Errors_Program(void);
void UPP_Errors_Power(void);
void UPP_Errors_Ranges(void);
@@ -225,7 +225,7 @@ static UPP_ErrorType_t UPP_SelectCommonError(void)
}
-static int setError(int condition, int flag, int *timer, int delay)
+__STATIC_FORCEINLINE int setError(int condition, int flag, int *timer, int delay)
{
if (condition) {
if (*timer < delay)
diff --git a/UPP/Core/UPP/upp_errors.h b/UPP/Core/UPP/upp_errors.h
index 96d2985..c314ffc 100644
--- a/UPP/Core/UPP/upp_errors.h
+++ b/UPP/Core/UPP/upp_errors.h
@@ -145,6 +145,7 @@ typedef struct
struct
{
+ uint16_t angle_reinit_err;
uint16_t adc_reinit_err;
uint16_t zc_reinit_err;
uint16_t pwm_reinit_err;
diff --git a/UPP/Core/UPP/upp_io.c b/UPP/Core/UPP/upp_io.c
index 529fad7..41aa5ce 100644
--- a/UPP/Core/UPP/upp_io.c
+++ b/UPP/Core/UPP/upp_io.c
@@ -29,7 +29,7 @@ static void UPP_DO5_Write(int state);
*/
void UPP_IO_Init(void)
{
- /* Дискретне выходы */
+ /* Дискретные выходы */
UPP_DO.CEN = &UPP_CEN_Write;
UPP_DO.Ready = &UPP_RDO3_Write;
UPP_DO.Work = &UPP_RDO2_Write;
diff --git a/UPP/Core/UPP/upp_io.h b/UPP/Core/UPP/upp_io.h
index 7d369d6..3fecb4b 100644
--- a/UPP/Core/UPP/upp_io.h
+++ b/UPP/Core/UPP/upp_io.h
@@ -10,7 +10,10 @@
#define _UPP_IO_H
#include "mylibs_include.h"
-
+#define DIN_Pusk_GPIO_Port DIN1_GPIO_Port
+#define DIN_Pusk_Pin DIN1_Pin
+#define DIN_MestDist_GPIO_Port DIN2_GPIO_Port
+#define DIN_MestDist_Pin DIN2_Pin
typedef struct
{
diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c
index 87e0742..36a4ed5 100644
--- a/UPP/Core/UPP/upp_main.c
+++ b/UPP/Core/UPP/upp_main.c
@@ -16,7 +16,7 @@
UPP_t upp;
HAL_StatusTypeDef res; // сюда сохраняется результат от выполения всяких функций
float dbg_iref = 2;
-int dbg_polarity = 0;
+int dbg_polarity = 1;
/**
* @brief Инициализация УПП.
@@ -60,17 +60,12 @@ int UPP_App_Init(void)
* @return 0 - если ОК, >1 если ошибка.
*/
int UPP_PreWhile(void)
-{
- UPP_Params_ControlInternal();
-
- if(Angle_SetRange(&upp.hangle, 0.0, 0.8) != HAL_OK)
- return 1;
+{
+ UPP_Params_Control();
if(PowerMonitor_Start(&upp.pm) != HAL_OK)
return 1;
-
-
UPP_DO.CEN(ENABLE);
return 0;
}
@@ -86,19 +81,26 @@ int UPP_While(void)
if(upp.pm.f.runSlow)
{
static uint32_t slow_cnt = 0;
+ 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);
+ res = HAL_IWDG_Refresh(&hiwdg); // если не вызываются медленные расчеты - что-то не то сбрасываемся по watchdog
// Медленные расчеты
- PowerMonitor_SlowCalc(&upp.pm);
+ PowerMonitor_SlowCalc(&upp.pm);
#ifdef UPP_SIMULATE_I // симулируем токи
- upp.pm.measured.final.Iamp = upp.hangle.Iref/2;
+ upp.pm.measured.final.Iamp = upp.hangle.Iref/2;
// Защиты // При симуляции тока не включаем его проверку
PowerMonitor_Protect(&upp.pm, 0);
#else
// Защиты // Определенные защиты по току включаем только в после разгона
PowerMonitor_Protect(&upp.pm, (fabsf(upp.hangle.Iref - dbg_iref) < 0.1));
#endif
+ // Обрабока ошибок и выставление итоговой Ошибки
+ UPP_Errors_Handle();
+ // Контроль парамеров
+ UPP_Params_Control();
+
+
#ifndef UPP_DISABLE_ERROR_BLOCK
@@ -224,13 +226,10 @@ int UPP_While(void)
*/
void UPP_Tick(void)
{
+ // Начинаем все проверять только после того как уйдем из режима инициализации
if(upp.workmode == UPP_Init)
return;
- // Обрабока ошибок и выставление итоговой Ошибки
- UPP_Errors_Handle();
- //
- UPP_Params_ControlInternal();
if(GPIO_Read_Switch(&UPP_DIN.Pusk))
{
@@ -244,10 +243,16 @@ void UPP_Tick(void)
-// ПРЕРЫВАНИЯ stm32f4xx_it.c
+//================ ПРЕРЫВАНИЯ stm32f4xx_it.c ===================
+/**
+ * @brief @ref DMA2_Stream0_IRQHandler
+ */
void UPP_ADC_Handle(void)
{
+ upp.Timings.isr_adc_prd_us = BenchTime_Period(BT_ADC_PRD, angletim.Instance->CNT, HAL_MAX_DELAY)/ANGLE_TIM2_FREQ_MHZ;
BenchTime_Start(BT_ADC, angletim.Instance->CNT, HAL_MAX_DELAY);
+
+
if(upp.pm.f.inIsr)
{
ERR_PRIVATE.overrun_fast_calc = 1;
@@ -282,6 +287,9 @@ void UPP_ADC_Handle(void)
upp.Timings.isr_adc_us = BenchTime_End(BT_ADC, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ;
upp.pm.f.inIsr = 0;
}
+/**
+ * @brief @ref TIM1_UP_TIM10_IRQHandler @ref
+ */
void UPP_PWM_Handle(void)
{
BenchTime_Start(BT_PWM, angletim.Instance->CNT, HAL_MAX_DELAY);
@@ -289,6 +297,9 @@ void UPP_PWM_Handle(void)
upp.Timings.isr_pwm_us = BenchTime_End(BT_PWM, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ;
}
+/**
+ * @brief @ref HAL_TIM_OC_DelayElapsedCallback
+ */
void UPP_Angle_Handle(void)
{
UPP_Phase_t phase = Angle_Handle(&upp.hangle);
@@ -315,7 +326,9 @@ void UPP_Angle_Handle(void)
}
}
-// Callback по совпадению CCRx
+/**
+ * @brief Callback по совпадению CCRx c CNT
+ */
void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim)
{
if (htim == upp.hangle.htim)
@@ -323,6 +336,9 @@ void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim)
UPP_Angle_Handle();
}
}
+/**
+ * @brief @ref HAL_TIM_PeriodElapsedCallback
+ */
void HAL_IncTick(void)
{
BenchTime_Start(BT_SYSTICK, angletim.Instance->CNT, HAL_MAX_DELAY);
diff --git a/UPP/Core/UPP/upp_main.h b/UPP/Core/UPP/upp_main.h
index 22a261c..112354d 100644
--- a/UPP/Core/UPP/upp_main.h
+++ b/UPP/Core/UPP/upp_main.h
@@ -39,7 +39,9 @@ typedef struct
struct
{
+ uint32_t slow_calc_prd_us;
uint32_t slow_calc_us;
+ uint32_t isr_adc_prd_us;
uint32_t isr_adc_us;
uint32_t isr_pwm_us;
uint32_t isr_systick_us;
diff --git a/UPP/Core/UPP/upp_params.c b/UPP/Core/UPP/upp_params.c
index c0377ed..b37e83a 100644
--- a/UPP/Core/UPP/upp_params.c
+++ b/UPP/Core/UPP/upp_params.c
@@ -1,26 +1,105 @@
/**
******************************************************************************
* @file upp_params.c
-* @brief Модуль определябщий поведение УПП
+* @brief Модуль проверяющий параметры УПП
******************************************************************************
* @details
-******************************************************************************/
+* ИНСТРУКЦИЯ ПО ДОБАВЛЕНИЮ НОВЫХ ПАРАМЕТРОВ:
+*
+* 1. Добавить новый параметр в соответствующую структуру в файле параметров:
+* - PARAM_PUI для параметров от ПУИ (пульт управления и индикации)
+* - PARAM_INTERNAL для внутренних параметров УПП
+*
+* 2. В функции UPP_Params_ControlInternal() или UPP_Params_ControlPUI():
+* a. Объявить временную переменную для хранения текущего значения
+* b. Проверить изменение параметра (можно с помощью __CheckParamX() функции)
+* c. Обновить параметр в соответствующем модуле новым параметром если он изменился
+*
+* 3. В функции UPP_Params_SetDefault() добавить установку значения по умолчанию
+*
+* 4. При необходимости добавить сатурацию параметра в UPP_Params_Saturate()
+*
+* Пример добавления простого параметра:
+*
+* // В UPP_Params_ControlInternal():
+* float new_param = module.param;
+* if(__CheckParamF(&new_param, PARAM_INTERNAL.new_param, 1000))
+* {
+* module_update = 1;
+* }
+*
+* // В блоке обновления модуля:
+* if(module_update)
+* {
+* if(Module_SetParam(&module, new_param) == HAL_OK)
+* module_update = 0;
+* }
+*
+* // В UPP_Params_SetDefault():
+* PARAM_INTERNAL.new_param = NEW_PARAM_DEFAULT * 1000;
+*
+******************************************************************************
+*/
#include "upp_main.h" // всё остальное по работе с УПП
+#define SATURATE_U16(value, min, max) \
+ value = ((value) < (min) ? (min) : ((value) > (max) ? (max) : (value)))
-static int __CheckSimpleParamF(float *paramDist, uint16_t paramSrc, float Coef);
-static int __CheckSimpleParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef);
-static int __CheckSimpleParamU16(uint16_t *paramDist, uint16_t paramSrc);
-static int __CheckSimpleParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef);
+static int __CheckParamF(float *paramDist, uint16_t paramSrc, float Coef);
+static int __CheckParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef);
+static int __CheckParamU16(uint16_t *paramDist, uint16_t paramSrc);
+static int __CheckParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef);
static void __AngleSetLimit(void);
+
+/**
+ * @brief Контроль параметров УПП.
+ * @return HAL Status.
+ */
+void UPP_Params_Control(void)
+{
+ /* Проверяем параметры на корректный диапазон */
+ UPP_Params_Saturate();
+ /* Чекаем изменились ли параметры от ПУИ */
+ UPP_Params_ControlPUI();
+ /* Чекаем изменились ли внутренние параметры */
+ UPP_Params_ControlInternal();
+}
+/**
+ * @brief Контроль параметров от ПУИ.
+ * @return HAL Status.
+ */
+void UPP_Params_ControlPUI(void)
+{
+ if(upp.call->go) // при запущеном УПП ничего не меняем
+ return;
+
+ /* Tnt Уставка на скорость нарастания пускового тока Iref */
+ float angle_ref_alphaPUI = PUI_Tnt_CalcAlpha(to_float(PARAM_PUI.Tnt, 1000), PM_SLOW_PERIOD_US);
+ float angle_ref_alpha = upp.hangle.refFilter.alpha;
+ if(angle_ref_alpha != angle_ref_alphaPUI)
+ {
+ angle_ref_alpha = angle_ref_alphaPUI;
+ if(Angle_PID_Init(&upp.hangle,
+ upp.hangle.pid.Kp,
+ upp.hangle.pid.Ki,
+ upp.hangle.pid.Kd,
+ angle_ref_alpha) != HAL_OK)
+ ERR_PRIVATE_CNT.angle_reinit_err++;
+ }
+
+
+}
+
+
+
+
/**
* @brief Контроль внутренних параметров УПП.
* @return HAL Status.
*/
void UPP_Params_ControlInternal(void)
{
- __AngleSetLimit();
if(upp.call->go) // при запущеном УПП ничего не меняем
return;
@@ -36,7 +115,6 @@ void UPP_Params_ControlInternal(void)
float angle_pid_kp = upp.hangle.pid.Kp;
float angle_pid_ki = upp.hangle.pid.Ki;
float angle_pid_kd = upp.hangle.pid.Kd;
- float angle_ref_alpha = upp.hangle.refFilter.alpha;
// временная переменная для параметров каналов АЦП
float adc_channel_max[ADC_NUMB_OF_REGULAR_CHANNELS] = {0};
uint16_t adc_channel_zero[ADC_NUMB_OF_REGULAR_CHANNELS] = {0};
@@ -46,6 +124,7 @@ void UPP_Params_ControlInternal(void)
// временная переменная для параметров ШИМ
uint8_t pwm_phase_mask = upp.hpwm.Config.PhaseMask.all;
uint16_t pwm_freq = upp.hpwm.Config.Frequency;
+ float pwm_duty = upp.hpwm.Config.Duty;
uint8_t pwm_pulse_num = upp.hpwm.Config.PulseNumber;
// временная переменная для параметров Мониторинга сети
float pm_alpha = upp.pm.exp[0].alpha;
@@ -53,31 +132,26 @@ void UPP_Params_ControlInternal(void)
// Параметры регулятора Угла открытия
- if(__CheckSimpleParamF(&angle_max, PARAM_INTERNAL.angle.Angle_Max, 65535))
+ if(__CheckParamF(&angle_max, PARAM_INTERNAL.angle.Angle_Max, 65535))
{
alpha_update = 1;
}
- if(__CheckSimpleParamF(&angle_min, PARAM_INTERNAL.angle.Angle_Min, 65535))
+ if(__CheckParamF(&angle_min, PARAM_INTERNAL.angle.Angle_Min, 65535))
{
alpha_update = 1;
}
- if(__CheckSimpleParamF(&angle_pid_kp, PARAM_INTERNAL.angle.PID_Kp, 10000))
+ if(__CheckParamF(&angle_pid_kp, PARAM_INTERNAL.angle.PID_Kp, 10000))
{
alpha_update = 1;
}
- if(__CheckSimpleParamF(&angle_pid_ki, PARAM_INTERNAL.angle.PID_Ki, 10000))
+ if(__CheckParamF(&angle_pid_ki, PARAM_INTERNAL.angle.PID_Ki, 10000))
{
alpha_update = 1;
}
- if(__CheckSimpleParamF(&angle_pid_kd, PARAM_INTERNAL.angle.PID_Kd, 10000))
+ if(__CheckParamF(&angle_pid_kd, PARAM_INTERNAL.angle.PID_Kd, 10000))
{
alpha_update = 1;
- }
- if(__CheckSimpleParamF(&angle_ref_alpha, PARAM_INTERNAL.angle.PID_ExpAlpha, 65535))
- {
- alpha_update = 1;
- }
-
+ }
// Параметры АЦП
@@ -87,56 +161,72 @@ void UPP_Params_ControlInternal(void)
adc_channel_zero[i] = upp.pm.adc.Coefs[i].lZero;
// Максимальное измеряемое напряжение
- if(__CheckSimpleParamF(&adc_channel_max[i], PARAM_INTERNAL.adc.ADC_Max[i], 10))
+ if(__CheckParamF(&adc_channel_max[i], PARAM_INTERNAL.adc.ADC_Max[i], 10))
{
adc_channel_update[i] = 1;
}
// Значение АЦП при нулевом входе
- if(__CheckSimpleParamU16(&adc_channel_zero[i], PARAM_INTERNAL.adc.ADC_Zero[i]))
+ if(__CheckParamU16(&adc_channel_zero[i], PARAM_INTERNAL.adc.ADC_Zero[i]))
{
adc_channel_update[i] = 1;
}
}
// Параметры алгоритма перехода через ноль
- if(__CheckSimpleParamF(&zc_hysteresis, PARAM_INTERNAL.zc.Hysteresis, 10000))
+ if(__CheckParamF(&zc_hysteresis, PARAM_INTERNAL.zc.Hysteresis, 10000))
{
zc_update = 1;
}
- if(__CheckSimpleParamU16(&zc_debounce, PARAM_INTERNAL.zc.DebouneCouner))
+ if(__CheckParamU16(&zc_debounce, PARAM_INTERNAL.zc.DebouneCouner))
{
zc_update = 1;
}
// Параметры ШИМ токов
- if(__CheckSimpleParamU8(&pwm_phase_mask, PARAM_INTERNAL.pwm.PhaseMask, 1))
+ if(__CheckParamU8(&pwm_phase_mask, PARAM_INTERNAL.pwm.PhaseMask, 1))
{
pwm_update = 1;
}
- if(__CheckSimpleParamU16(&pwm_freq, PARAM_INTERNAL.pwm.Frequency))
+ if(__CheckParamU16(&pwm_freq, PARAM_INTERNAL.pwm.Frequency))
{
pwm_update = 1;
}
- if(__CheckSimpleParamU8(&pwm_pulse_num, PARAM_INTERNAL.pwm.PulseNumber, 1))
+ if(__CheckParamF(&pwm_duty, PARAM_INTERNAL.pwm.Duty, 100))
{
pwm_update = 1;
- }
+ }
+ if(__CheckParamU8(&pwm_pulse_num, PARAM_INTERNAL.pwm.PulseNumber, 1))
+ {
+ pwm_update = 1;
+ }
+
// Параметры мониторинга
- if(__CheckSimpleParamF(&pm_alpha, PARAM_INTERNAL.pm.mean_alpha, 65535))
+ if(__CheckParamF(&pm_alpha, PARAM_INTERNAL.pm.mean_alpha, 65535))
{
for(int i = 0; i < EXP_ALL; i++)
{
Filter_ReInit(&upp.pm.exp[i], pm_alpha);
+ Filter_Start(&upp.pm.exp[i]);
}
}
// Обновление регулятора угла открытия
+ __AngleSetLimit();
if(alpha_update)
{
- Angle_SetRange(&upp.hangle, angle_min, angle_max);
- Angle_PID_Init(&upp.hangle, angle_pid_kp, angle_pid_ki, angle_pid_kd, angle_ref_alpha);
+ if(Angle_SetRange(&upp.hangle, angle_min, angle_max) == HAL_OK)
+ {
+ if(Angle_PID_Init(&upp.hangle, angle_pid_kp, angle_pid_ki, angle_pid_kd, upp.hangle.refFilter.alpha) == HAL_OK)
+ {
+ alpha_update = 0;
+ }
+ else
+ ERR_PRIVATE_CNT.angle_reinit_err++;
+ }
+ else
+ ERR_PRIVATE_CNT.angle_reinit_err++;
}
// Обновление АЦП конфигов
for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
@@ -160,7 +250,7 @@ void UPP_Params_ControlInternal(void)
// Обновление ШИМ конфигов
if(pwm_update)
{
- if(PWM_SetConfig(&upp.hpwm, pwm_phase_mask, pwm_freq, pwm_pulse_num) == HAL_OK)
+ if(PWM_SetConfig(&upp.hpwm, pwm_phase_mask, pwm_freq, pwm_duty, pwm_pulse_num) == HAL_OK)
{
pwm_update = 0;
}
@@ -178,6 +268,46 @@ void UPP_Params_ControlInternal(void)
*/
void UPP_Params_Saturate(void)
{
+ SATURATE_U16(PARAM_PUI.Iref, 100, 500);
+// SATURATE_U16(PARAM_PUI.Tnt, 50, 5000);
+ SATURATE_U16(PARAM_PUI.Umin, 5, 99);
+ SATURATE_U16(PARAM_PUI.Umax, 100, 120);
+ SATURATE_U16(PARAM_PUI.Imax, 5, 99);
+ SATURATE_U16(PARAM_PUI.Imin, 0, 40);
+ SATURATE_U16(PARAM_PUI.TiMax, 500, 10000);
+ SATURATE_U16(PARAM_PUI.Tdelay, 5, 60);
+ SATURATE_U16(PARAM_PUI.Interlace, 0, 1);
+
+ SATURATE_U16(PARAM_INTERNAL.setpoints.TemperatureWarn, 0, 90);
+ SATURATE_U16(PARAM_INTERNAL.setpoints.TemperatureErr, 0, 90);
+
+ SATURATE_U16(PARAM_INTERNAL.nominal.PhaseNumber, 0, 3);
+ SATURATE_U16(PARAM_INTERNAL.nominal.U, 0, ADC_U_MAX_V_DEFAULT*10);
+ SATURATE_U16(PARAM_INTERNAL.nominal.U_deviation_plus, 0, 100*100);
+ SATURATE_U16(PARAM_INTERNAL.nominal.U_deviation_minus, 0, 100*100);
+ SATURATE_U16(PARAM_INTERNAL.nominal.F, 40*100, 60*100);
+ SATURATE_U16(PARAM_INTERNAL.nominal.F_deviation_plus, 0, 100*100);
+ SATURATE_U16(PARAM_INTERNAL.nominal.F_deviation_minus, 0, 100*100);
+ SATURATE_U16(PARAM_INTERNAL.nominal.I, 0, ADC_I_MAX_A_DEFAULT*10);
+
+ SATURATE_U16(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UBA], 0, ADC_U_MAX_V_DEFAULT*10);
+ SATURATE_U16(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UAC], 0, ADC_U_MAX_V_DEFAULT*10);
+ SATURATE_U16(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IC], 0, ADC_I_MAX_A_DEFAULT*10);
+ SATURATE_U16(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IA], 0, ADC_I_MAX_A_DEFAULT*10);
+ SATURATE_U16(PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UBA], 1848, 2248);
+ SATURATE_U16(PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UAC], 1848, 2248);
+ SATURATE_U16(PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IC], 1848, 2248);
+ SATURATE_U16(PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IA], 1848, 2248);
+
+ SATURATE_U16(PARAM_INTERNAL.pwm.PhaseMask, 0, 7);
+ SATURATE_U16(PARAM_INTERNAL.pwm.Frequency, 1000, 40000);
+ SATURATE_U16(PARAM_INTERNAL.pwm.PulseNumber, 1, 50);
+
+ SATURATE_U16(PARAM_INTERNAL.zc.Hysteresis, 0, 0.1*100);
+ SATURATE_U16(PARAM_INTERNAL.zc.DebouneCouner, 0, 1000);
+
+
+ SATURATE_U16(PARAM_INTERNAL.angle.PulseLengthReserve, 50, 1000);
}
/**
@@ -215,7 +345,7 @@ void UPP_Params_SetDefault(int pui_default, int internal_default)
PARAM_INTERNAL.nominal.F_deviation_minus = NOM_F_DEVIATION_MINUS_PERCENT_DEFAULT*100;
PARAM_INTERNAL.nominal.I = NOM_I_A_DEFAULT*10;
- PARAM_INTERNAL.pm.mean_alpha = CALC_TAU_COEF(PM_EXP_TAU_COEF_DEFAULT,PM_SLOW_PERIOD_US)*65535;
+ PARAM_INTERNAL.pm.mean_alpha = FilterExp_CalcAlpha(PM_EXP_TAU_COEF_DEFAULT,PM_SLOW_PERIOD_US)*65535;
PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UBA] = ADC_U_MAX_V_DEFAULT*10;
PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UAC] = ADC_U_MAX_V_DEFAULT*10;
@@ -226,9 +356,10 @@ void UPP_Params_SetDefault(int pui_default, int internal_default)
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IC] = ADC_I_ZERO_DEFAULT;
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IA] = ADC_I_ZERO_DEFAULT;
- PARAM_INTERNAL.pwm.PhaseMask = 7; // (все три фазы)
- PARAM_INTERNAL.pwm.Frequency = (float)PWM_THYR_FREQUENCY_HZ_DEFAULT;
- PARAM_INTERNAL.pwm.PulseNumber = PWM_THYR_PULSE_NUMBER_DEFAULT;
+ PARAM_INTERNAL.pwm.PhaseMask = 7; // (все три фазы)
+ PARAM_INTERNAL.pwm.Frequency = PWM_THYR_FREQUENCY_HZ_DEFAULT;
+ PARAM_INTERNAL.pwm.Duty = PWM_THYR_DUTY_PERCENT_DEFAULT*100;
+ PARAM_INTERNAL.pwm.PulseNumber = PWM_THYR_PULSE_NUMBER_DEFAULT;
PARAM_INTERNAL.zc.Hysteresis = ZERO_CROSS_HYSTERESIS_PERCENT_DEFAULT*100;
PARAM_INTERNAL.zc.DebouneCouner = ZERO_CROSS_DEBOUNCE_CNT_DEFAULT;
@@ -237,7 +368,6 @@ void UPP_Params_SetDefault(int pui_default, int internal_default)
PARAM_INTERNAL.angle.PID_Kp = ANGLE_PID_KP_COEF_DEFAULT*10000;
PARAM_INTERNAL.angle.PID_Ki = ANGLE_PID_KI_COEF_DEFAULT*10000;
PARAM_INTERNAL.angle.PID_Kd = ANGLE_PID_KD_COEF_DEFAULT*10000;
- PARAM_INTERNAL.angle.PID_ExpAlpha = CALC_TAU_COEF(ANGLE_REF_TAU_COEF_DEFAULT,PM_SLOW_PERIOD_US)*65535;
PARAM_INTERNAL.angle.Angle_Max = ANGLE_MAX_PERCENT_DEFAULT*65535;
PARAM_INTERNAL.angle.Angle_Min = ANGLE_MIN_PERCENT_DEFAULT*65535;
PARAM_INTERNAL.angle.PulseLengthReserve = ANGLE_PULSE_LENGTH_RESERVE_PERCENT_DEFAULT*100;
@@ -266,7 +396,7 @@ static void __AngleSetLimit(void)
* @param Coef Коэффициент для приведения float к uint16_t: uint16_t = float*coef, float = uint16_t/coef
* @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
*/
-static int __CheckSimpleParamF(float *paramDist, uint16_t paramSrc, float Coef)
+static int __CheckParamF(float *paramDist, uint16_t paramSrc, float Coef)
{
if(paramDist == NULL)
return 0;
@@ -289,7 +419,7 @@ static int __CheckSimpleParamF(float *paramDist, uint16_t paramSrc, float Coef)
* @param Coef Коэффициент для приведения uint32_t к uint16_t: uint16_t = uint32_t*coef, uint32_t = uint16_t/coef
* @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
*/
-static int __CheckSimpleParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef)
+static int __CheckParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef)
{
if(paramDist == NULL)
return 0;
@@ -311,7 +441,7 @@ static int __CheckSimpleParamU32(uint32_t *paramDist, uint16_t paramSrc, float C
* @param paramSrc Значение для сравнения с uint16_t параметром
* @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
*/
-static int __CheckSimpleParamU16(uint16_t *paramDist, uint16_t paramSrc)
+static int __CheckParamU16(uint16_t *paramDist, uint16_t paramSrc)
{
if(paramDist == NULL)
return 0;
@@ -335,7 +465,7 @@ static int __CheckSimpleParamU16(uint16_t *paramDist, uint16_t paramSrc)
* @param Coef Коэффициент для приведения uint32_t к uint16_t: uint16_t = uint8_t*coef, uint8_t = uint16_t/coef
* @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
*/
-static int __CheckSimpleParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef)
+static int __CheckParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef)
{
if(paramDist == NULL)
return 0;
diff --git a/UPP/Core/UPP/upp_params.h b/UPP/Core/UPP/upp_params.h
index 22a3db6..82684a1 100644
--- a/UPP/Core/UPP/upp_params.h
+++ b/UPP/Core/UPP/upp_params.h
@@ -65,9 +65,10 @@ typedef struct
/* Параметры ШИМ */
struct
{
- uint16_t PhaseMask; ///< Битовяя маска на какие фазы подавать ШИМ: 0 бит - a, 1 бит - b, 2 бит - c
- uint16_t Frequency; ///< Частота ШИМ для пачки импульсов на тиристоры [Герцы]
- uint16_t PulseNumber; ///< Количесво импульсов в пачке [Количество]
+ uint16_t PhaseMask; ///< Битовяя маска на какие фазы подавать ШИМ: 0 бит - a, 1 бит - b, 2 бит - c
+ uint16_t Frequency; ///< Частота ШИМ для пачки импульсов на тиристоры [Герцы]
+ uint16_t Duty; ///< Скважность ШИМ для пачки импульсов на тиристоры [Проценты]
+ uint16_t PulseNumber; ///< Количесво импульсов в пачке [Количество]
}pwm;
/* Параметры Угла */
@@ -87,16 +88,20 @@ typedef struct
uint16_t PID_Kp; ///< Пропорциональный коэфициент ПИ регулятора угла [x 10000]
uint16_t PID_Ki; ///< Интегральный коэфициент ПИ регулятора угла [x 10000]
uint16_t PID_Kd; ///< Интегральный коэфициент ПИ регулятора угла [x 10000]
- uint16_t PID_ExpAlpha; ///< Коэффициент сглаживающего фильтра задания регулятора [0..1 x 65535]
}angle;
}UPP_PrvtParams_t;
-
+/* Контроль параметров УПП. */
+void UPP_Params_Control(void);
+/* Контроль параметров от ПУИ. */
+void UPP_Params_ControlPUI(void);
/* Контроль внутренних параметров УПП. */
void UPP_Params_ControlInternal(void);
+/* Контроль параметров УПП на корректные значения. */
+void UPP_Params_Saturate(void);
/* Установка параметров на дефолтные значения */
void UPP_Params_SetDefault(int pui_default, int internal_default);
diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx
index 2702d77..3504953 100644
--- a/UPP/MDK-ARM/UPP.uvoptx
+++ b/UPP/MDK-ARM/UPP.uvoptx
@@ -322,59 +322,10 @@
0
ST-LINKIII-KEIL_SWO
- -U005600373433510237363934 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131123 -TC168000000 -TT10000000 -TP21 -TDS800D -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F417ZGTx$CMSIS\Flash\STM32F4xx_1024.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2
+ -U005600373433510237363934 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131123 -TC168000000 -TT10000000 -TP21 -TDS800D -TDT1 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F417ZGTx$CMSIS\Flash\STM32F4xx_1024.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2
-
-
- 0
- 0
- 407
- 1
- 134233766
- 0
- 0
- 0
- 0
- 0
- 1
- ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c
-
- \\Debug_F417\../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c\407
-
-
- 1
- 0
- 136
- 1
- 134256344
- 0
- 0
- 0
- 0
- 0
- 1
- ../Core/Src/stm32f4xx_it.c
-
- \\Debug_F417\../Core/Src/stm32f4xx_it.c\136
-
-
- 2
- 0
- 27
- 1
- 0
- 0
- 0
- 0
- 0
- 0
- 0
- .\startup_stm32f417xx.s
-
-
-
-
+
0
@@ -456,6 +407,21 @@
1
\\Debug_F417\../Core/UPP/upp_io.c\UPP_DIN.Pusk.Sw_FilterDelay
+
+ 16
+ 1
+ hadc3
+
+
+ 17
+ 1
+ upp.hangle.Iref
+
+
+ 18
+ 1
+ upp.pm.measured.final.U[0]
+
@@ -466,7 +432,7 @@
1
2
- MB_DATA
+ MB_DATA,0x0A
2
@@ -523,6 +489,11 @@
2
upp.pm.measured.slow.U[0]
+
+ 13
+ 2
+ upp,0x0A
+
0
@@ -530,7 +501,7 @@
0
1
- 1
+ 0
0
0
0
@@ -569,41 +540,17 @@
0
- `upp.pm.zc.Channel[0].HalfWave
- 0000000000000000000000000000000000000040000000000000000000000000000000007570702E706D2E7A632E4368616E6E656C5B305D2E48616C66576176650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000001000000000000000000F03F1400000000000000000000000000000000000000FC9E0008
+ `upp.pm.measured.final.U[0]
+ 008000000000000000000000000000000000F03F000000000000000000000000000000007570702E706D2E6D656173757265642E66696E616C2E555B305D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000001000000000000000000F03F140000000000000000000000000000000000000020B20008
- System Viewer\DBG
- 35902
-
-
- System Viewer\GPIOE
- 35898
-
-
- System Viewer\GPIOG
- 35899
-
-
- System Viewer\TIM1
- 35901
-
-
- System Viewer\TIM14
- 35903
-
-
- System Viewer\TIM2
- 35900
-
-
- System Viewer\TIM5
+ System Viewer\ADC3
35905
- System Viewer\TIM8
+ System Viewer\DMA2
35904
@@ -1227,7 +1174,7 @@
MyLibs
- 0
+ 1
0
0
0
@@ -1515,7 +1462,7 @@
PeriphGeneral
- 1
+ 0
0
0
0
diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx
index 45f9920..70d41f4 100644
--- a/UPP/MDK-ARM/UPP.uvprojx
+++ b/UPP/MDK-ARM/UPP.uvprojx
@@ -1122,11 +1122,11 @@
0
1
1
- 4101
+ 4096
1
BIN\UL2CM3.DLL
-
+ "" ()
diff --git a/UPP/UPP.ioc b/UPP/UPP.ioc
index 322dd2f..5d60256 100644
--- a/UPP/UPP.ioc
+++ b/UPP/UPP.ioc
@@ -488,7 +488,7 @@ TIM2.OCMode_2=TIM_OCMODE_TIMING
TIM2.OCMode_3=TIM_OCMODE_TIMING
TIM3.IPParameters=TIM_MasterSlaveMode,TIM_MasterOutputTrigger
TIM3.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE
-TIM3.TIM_MasterSlaveMode=TIM_MASTERSLAVEMODE_ENABLE
+TIM3.TIM_MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE
TIM5.IPParameters=Prescaler
TIM5.Prescaler=90-1
TIM8.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3