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 4c2c92a..4e4ea46 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
@@ -18,24 +18,33 @@ void TIM_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
// Выбор режима работы таймера
-switch (TIMx->SMCR & TIM_SMCR_SMS) // TIMER MODE
-{
- // обычный счет
- case(TIM_SLAVEMODE_DISABLE):// NORMAL MODE counting
- TIMx_Count(TIMx, TIMS);
- Channels_Simulation(TIMx, TIMS); // CaptureCompare and PWM channels simulation
- Write_TRGO(TIMx, TIMS);
- break;
+ switch (TIMx->SMCR & TIM_SMCR_SMS) // TIMER MODE
+ {
+ // обычный счет
+ case(TIM_SLAVEMODE_DISABLE):// NORMAL MODE counting
+ TIMx_Count(TIMx, TIMS);
+ Channels_Simulation(TIMx, TIMS); // CaptureCompare and PWM channels simulation
+ Write_TRGO(TIMx, TIMS);
+ break;
- // включение слейв таймера по ивенту
- case(TIM_SLAVEMODE_TRIGGER): // SLAVE MODE: TRIGGER MODE
- Slave_Mode_Check_Source(TIMx, TIMS);
- TIMx_Count(TIMx, TIMS);
- Channels_Simulation(TIMx, TIMS); // CaptureCompare and PWM channels simulation
- Write_TRGO(TIMx, TIMS);
- break;
-}
+ // включение слейв таймера по ивенту
+ case(TIM_SLAVEMODE_TRIGGER): // SLAVE MODE: TRIGGER MODE
+ Slave_Mode_Check_Source(TIMx, TIMS);
+ TIMx_Count(TIMx, TIMS);
+ Channels_Simulation(TIMx, TIMS); // CaptureCompare and PWM channels simulation
+ Write_TRGO(TIMx, TIMS);
+ break;
+ }
+
+ // EGR
+ TIM_EGR_Simulation(TIMx);
+
+ // Прерывание если какое-то выставлено
+ if (TIMx->SR & (TIM_SR_UIF | TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF))
+ {
+ TIM_Call_IRQHandller(TIMx); // call HANDLER
+ }
}
/* Счет таймера за один такт */
@@ -68,7 +77,9 @@ void Overflow_Check(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS)
if(TIMS->tx_step > TIMS->RELOAD)
TIMS->tx_cnt = 0;
- TIM_Call_IRQHandller(TIMx); // call HANDLER
+ if (TIMx->DIER & TIM_DIER_UIE) {
+ TIMx->SR |= TIM_SR_UIF;
+ }
}
}
}
@@ -134,12 +145,10 @@ void CC_PWM_Ch1_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
if (((TIMS->tx_cnt - TIMS->tx_step) < TIMx->CCR1) && (TIMS->tx_cnt >= TIMx->CCR1))
{
TIMx->SR |= TIM_SR_CC1IF;
- TIM_Call_IRQHandller(TIMx);
}
else if (((TIMS->tx_cnt - TIMS->tx_step) > TIMx->CCR1) && (TIMS->tx_cnt <= TIMx->CCR1))
{
TIMx->SR |= TIM_SR_CC1IF;
- TIM_Call_IRQHandller(TIMx);
}
}
}
@@ -188,12 +197,10 @@ void CC_PWM_Ch2_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
if (((TIMS->tx_cnt - TIMS->tx_step) < TIMx->CCR2) && (TIMS->tx_cnt >= TIMx->CCR2))
{
TIMx->SR |= TIM_SR_CC2IF;
- TIM_Call_IRQHandller(TIMx);
}
else if (((TIMS->tx_cnt - TIMS->tx_step) > TIMx->CCR2) && (TIMS->tx_cnt <= TIMx->CCR2))
{
TIMx->SR |= TIM_SR_CC2IF;
- TIM_Call_IRQHandller(TIMx);
}
}
}
@@ -242,12 +249,10 @@ void CC_PWM_Ch3_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
if (((TIMS->tx_cnt - TIMS->tx_step) < TIMx->CCR3) && (TIMS->tx_cnt >= TIMx->CCR3))
{
TIMx->SR |= TIM_SR_CC3IF;
- TIM_Call_IRQHandller(TIMx);
}
else if (((TIMS->tx_cnt - TIMS->tx_step) > TIMx->CCR3) && (TIMS->tx_cnt <= TIMx->CCR3))
{
TIMx->SR |= TIM_SR_CC3IF;
- TIM_Call_IRQHandller(TIMx);
}
}
}
@@ -296,12 +301,10 @@ void CC_PWM_Ch4_Simulation(TIM_TypeDef *TIMx, struct TIM_Sim *TIMS)
if (((TIMS->tx_cnt - TIMS->tx_step) < TIMx->CCR4) && (TIMS->tx_cnt >= TIMx->CCR4))
{
TIMx->SR |= TIM_SR_CC4IF;
- TIM_Call_IRQHandller(TIMx);
}
else if (((TIMS->tx_cnt - TIMS->tx_step) > TIMx->CCR4) && (TIMS->tx_cnt <= TIMx->CCR4))
{
TIMx->SR |= TIM_SR_CC4IF;
- TIM_Call_IRQHandller(TIMx);
}
}
}
@@ -456,6 +459,42 @@ void Write_TRGO(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS)
//--------------------MISC (temporary) FUNCTIONS--------------------//
+void TIM_EGR_Simulation(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS)
+{
+ // Update
+ if (TIMx->EGR & TIM_EGR_UG) {
+ TIMx->EGR &= ~TIM_EGR_UG;
+ if (TIMx->DIER & TIM_DIER_UIE) {
+ TIMx->SR |= TIM_SR_UIF;
+ }
+ }
+ // Channels
+ if (TIMx->EGR & TIM_EGR_CC1G) {
+ TIMx->EGR &= ~TIM_EGR_CC1G;
+ if (TIMx->DIER & TIM_IT_CC1) {
+ TIMx->SR |= TIM_SR_CC1IF;
+ }
+ }
+ if (TIMx->EGR & TIM_EGR_CC2G) {
+ TIMx->EGR &= ~TIM_EGR_CC2G;
+ if (TIMx->DIER & TIM_IT_CC2) {
+ TIMx->SR |= TIM_SR_CC2IF;
+ }
+ }
+ if (TIMx->EGR & TIM_EGR_CC3G) {
+ TIMx->EGR &= ~TIM_EGR_CC3G;
+ if (TIMx->DIER & TIM_IT_CC3) {
+ TIMx->SR |= TIM_SR_CC3IF;
+ }
+ }
+ if (TIMx->EGR & TIM_EGR_CC4G) {
+ TIMx->EGR &= ~TIM_EGR_CC4G;
+ if (TIMx->DIER & TIM_IT_CC4) {
+ TIMx->SR |= TIM_SR_CC4IF;
+ }
+ }
+}
+
/* Определение источника для запуска таймера в SLAVE MODE */
void Slave_Mode_Check_Source(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS)
{
diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.h b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.h
index bca554e..9314aec 100644
--- a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.h
+++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_tim.h
@@ -108,6 +108,8 @@ void Write_TRGO(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS);
//--------------------MISC (temporary) FUNCTIONS--------------------//
+
+void TIM_Call_IRQHandller(TIM_TypeDef* TIMx);
/* Определение источника для запуска таймера в SLAVE MODE */
void Slave_Mode_Check_Source(TIM_TypeDef* TIMx, struct TIM_Sim* TIMS);
//------------------------------------------------------------------//
diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx
index aa05084..0af3141 100644
Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ
diff --git a/UPP/Core/Configs/modbus_data.h b/UPP/Core/Configs/modbus_data.h
index 985af13..34d385c 100644
--- a/UPP/Core/Configs/modbus_data.h
+++ b/UPP/Core/Configs/modbus_data.h
@@ -52,7 +52,7 @@
#define _MODBUS_DATA_H_
#include "upp_defs.h"
-#include "upp_control.h"
+#include "upp_params.h"
#include "stdint.h"
diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h
index 97f0a05..af6a373 100644
--- a/UPP/Core/Configs/upp_config.h
+++ b/UPP/Core/Configs/upp_config.h
@@ -97,6 +97,12 @@
* @brief Параметры устанавливаемые на этапе компиляции. Без перепрошивки их не поменять
* @{
*/
+
+//#if defined(STM32F417xx)
+
+//#endif
+
+
/* Периоды вызова всякого */
#define PM_ADC_PERIOD_US 10 ///< Период опроса АЦП в мкс
#define PM_SLOW_PERIOD_CNT 50 ///< Период обновления медленных расчетов тиках @ref PM_ADC_PERIOD_US
@@ -109,4 +115,7 @@
#define PWM_TIM3_FREQ_MHZ 90 ///< Частота тиков таймера ШИМ (5-6 каналы)
#define ANGLE_TIM2_FREQ_MHZ 90 ///< Частота тиков таймера отсчета угла открытия тиристоров
+/** //UPP_COMPILED_PARAMS
+ * @}
+ */
#endif //_UPP_CONFIG_H_
diff --git a/UPP/Core/Configs/upp_defs.h b/UPP/Core/Configs/upp_defs.h
index cd82f8c..dad89f5 100644
--- a/UPP/Core/Configs/upp_defs.h
+++ b/UPP/Core/Configs/upp_defs.h
@@ -151,6 +151,9 @@ typedef struct {
#define PM_SLOW_PERIOD_US (PM_ADC_PERIOD_US*PM_SLOW_PERIOD_CNT)
#define ANGLE_PERIOD_MS(_freq_) (((float)1/(_freq_*2))*1000)
+#define PARAM_INTERNAL MB_INTERNAL.param
+#define PARAM_PUI MB_DATA.HoldRegs.pui_params
+
/**
* @brief Состояния полуволны
*/
diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c
index 5f11c17..489d7a5 100644
--- a/UPP/Core/PowerMonitor/power_monitor.c
+++ b/UPP/Core/PowerMonitor/power_monitor.c
@@ -32,32 +32,32 @@ HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm)
/* Инициализация каналов АЦП */
if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_UBA,
- MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_UBA],
- to_float(MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UBA], 10),
+ PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UBA],
+ to_float(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UBA], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_UAC,
- MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_UAC],
- to_float(MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UAC], 10),
+ PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UAC],
+ to_float(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UAC], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_IC,
- MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_IC],
- to_float(MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IC], 10),
+ PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IC],
+ to_float(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IC], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_IA,
- MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_IA],
- to_float(MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IA], 10),
+ PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IA],
+ to_float(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IA], 10),
4095) != HAL_OK)
return HAL_ERROR;
/* Инициализация алгоритма перехода через ноль */
- if(ZC_Init(&hpm->zc, 3, to_float(MB_INTERNAL.param.zc.Hysteresis, 100), MB_INTERNAL.param.zc.DebouneCouner) != HAL_OK)
+ if(ZC_Init(&hpm->zc, 3, to_float(PARAM_INTERNAL.zc.Hysteresis, 100), PARAM_INTERNAL.zc.DebouneCouner) != HAL_OK)
return HAL_ERROR;
/* Инициализация каналов алгоритма перехода через ноль */
@@ -72,7 +72,7 @@ HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm)
/* Инициализация экпоненциального фильтра медленного алга */
for(int i = 0; i < EXP_ALL; i++)
{
- if(FilterExp_Init(&hpm->exp[i], to_float(MB_INTERNAL.param.pm.mean_alpha,65535)))
+ if(FilterExp_Init(&hpm->exp[i], to_float(PARAM_INTERNAL.pm.mean_alpha,65535)))
return HAL_ERROR;
Filter_Start(&hpm->exp[i]);
}
@@ -195,8 +195,8 @@ void PowerMonitor_FastCalc(PowerMonitor_t *hpm)
/* Преобразуем в относительные единицы (о.е.) */
for(int i = 0; i < 3; i++)
{
- meas->fast.U[i] = 10*meas->real.U[i]/MB_INTERNAL.param.nominal.U;
- meas->fast.I[i] = 10*meas->real.I[i]/MB_INTERNAL.param.nominal.I;
+ meas->fast.U[i] = 10*meas->real.U[i]/PARAM_INTERNAL.nominal.U;
+ meas->fast.I[i] = 10*meas->real.I[i]/PARAM_INTERNAL.nominal.I;
}
/* Ищем переход через ноль */
@@ -250,8 +250,8 @@ int PowerMonitor_Protect(PowerMonitor_t *hpm, uint8_t Running)
return 1;
PowerMonitor_Measured_t *measure = &hpm->measured;
- UPP_PUI_Params_t *protect = &MB_DATA.HoldRegs.pui_params;
- UPP_ParamsNominal_t *nominal = &MB_INTERNAL.param.nominal;
+ UPP_PUI_Params_t *protect = &PARAM_PUI;
+ UPP_ParamsNominal_t *nominal = &PARAM_INTERNAL.nominal;
/*=============== ЗАЩИТЫ ПО НАПРЯЖЕНИЮ ==================*/
hpm->f.isU = Protect_Voltages(measure, protect, nominal);
diff --git a/UPP/Core/PowerMonitor/power_monitor.h b/UPP/Core/PowerMonitor/power_monitor.h
index 2b9ef4a..c0e97a9 100644
--- a/UPP/Core/PowerMonitor/power_monitor.h
+++ b/UPP/Core/PowerMonitor/power_monitor.h
@@ -92,11 +92,13 @@ typedef struct
}PowerMonitor_t;
extern PowerMonitor_t pm;
+// ====== ИНИЦИАЛИЗАЦИЯ ==========
/* Инициализация мониторинга сети */
HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm);
/* Запустить мониторинг сети */
HAL_StatusTypeDef PowerMonitor_Start(PowerMonitor_t *hpm);
+// ====== РАСЧЕТЫ ==========
/* Медленные расчеты АЦП */
void PowerMonitor_SlowCalc(PowerMonitor_t *hpm);
/* Считывание АЦП и быстрые расчеты */
diff --git a/UPP/Core/PowerMonitor/power_protect.c b/UPP/Core/PowerMonitor/power_protect.c
index b67dae8..2bf7206 100644
--- a/UPP/Core/PowerMonitor/power_protect.c
+++ b/UPP/Core/PowerMonitor/power_protect.c
@@ -133,12 +133,12 @@ int Protect_Currents(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *protect
void Protect_Misc(PowerMonitor_Measured_t *measure, UPP_PUI_Params_t *protect, UPP_ParamsNominal_t *nominal)
{
/* Переводим внутренние уставки в удобный вид */
- float lFnom = to_float(MB_INTERNAL.param.nominal.F, 100);
- float lFmin = lFnom - lFnom*to_float(MB_INTERNAL.param.nominal.F_deviation_minus, 100);
- float lFmax = lFnom + lFnom*to_float(MB_INTERNAL.param.nominal.F_deviation_plus, 100);
+ float lFnom = to_float(PARAM_INTERNAL.nominal.F, 100);
+ float lFmin = lFnom - lFnom*to_float(PARAM_INTERNAL.nominal.F_deviation_minus, 100);
+ float lFmax = lFnom + lFnom*to_float(PARAM_INTERNAL.nominal.F_deviation_plus, 100);
- float lTwarn = to_float(MB_INTERNAL.param.setpoints.TemperatureWarn, 100);
- float lTerr = to_float(MB_INTERNAL.param.setpoints.TemperatureWarn, 100);
+ float lTwarn = to_float(PARAM_INTERNAL.setpoints.TemperatureWarn, 100);
+ float lTerr = to_float(PARAM_INTERNAL.setpoints.TemperatureWarn, 100);
/*=============== ЗАЩИТЫ ПО ЧАСТОТЕ ==================*/
diff --git a/UPP/Core/PowerMonitor/zero_cross.h b/UPP/Core/PowerMonitor/zero_cross.h
index cb75130..ae0ab6f 100644
--- a/UPP/Core/PowerMonitor/zero_cross.h
+++ b/UPP/Core/PowerMonitor/zero_cross.h
@@ -124,32 +124,36 @@ typedef struct {
uint32_t LastTick; ///< Послднее время вызова
} ZeroCross_Handle_t;
+// ====== ИНИЦИАЛИЗАЦИЯ ==========
/* Инициализация детектора нуля с индивидуальными настройками */
HAL_StatusTypeDef ZC_Init(ZeroCross_Handle_t *zc, uint8_t num_channels,
float hysteresis, uint16_t debounce_samples);
-
/* Настройка канала детектора */
HAL_StatusTypeDef ZC_ConfigChannel(ZeroCross_Handle_t *zc, uint8_t channel,
ZC_EdgeType_t edgeType);
+// ====== УПРАВЛЕНИЕ ==========
+/* Включение/выключение мониторинга */
+void ZC_EnableMonitoring(ZeroCross_Handle_t *zc, uint8_t enable);
+/* Сброс статистики канала */
+void ZC_Reset(ZeroCross_Handle_t *zc, uint8_t channel);
+
+
+// ====== РАСЧЕТЫ ==========
/* Обработка значения отдельного канала */
void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value,
uint32_t timestamp);
-
/* Пакетная обработка всех каналов */
void ZC_ProcessAllChannels(ZeroCross_Handle_t *zc, float *values,
uint32_t timestamp);
+// ====== API ==========
/* Полученить флаг - переход произошел. */
int ZC_isOccurred(ZeroCross_Handle_t *zc, uint8_t channel);
/* Получение частоты сигнала */
float ZC_GetFrequency(ZeroCross_Handle_t *zc, uint8_t channel);
/* Получение полуволны (после последнего zero-cross) */
UPP_HalfWave_t ZC_GetHalfWave(ZeroCross_Handle_t *zc, uint8_t channel);
-/* Включение/выключение мониторинга */
-void ZC_EnableMonitoring(ZeroCross_Handle_t *zc, uint8_t enable);
-/* Сброс статистики канала */
-void ZC_Reset(ZeroCross_Handle_t *zc, uint8_t channel);
#endif /* _ZERO_CROSS_H_ */
diff --git a/UPP/Core/UPP/angle_control.c b/UPP/Core/UPP/angle_control.c
index 1fd8a2e..ef16bb1 100644
--- a/UPP/Core/UPP/angle_control.c
+++ b/UPP/Core/UPP/angle_control.c
@@ -22,9 +22,9 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle)
hangle->htim = &angletim;
// Инициализация ПИД
- float kp = to_float(MB_INTERNAL.param.angle.PID_Kp, 10000);
- float ki = to_float(MB_INTERNAL.param.angle.PID_Ki, 10000);
- float kd = to_float(MB_INTERNAL.param.angle.PID_Kd, 10000);
+ 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);
Angle_PID_Init(hangle, kp, ki, kd);
// Инициализация каналов
@@ -39,8 +39,8 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle)
// Инициализация углов
- float angle_max = to_float(MB_INTERNAL.param.angle.Angle_Max, 65535);
- float angle_min = to_float(MB_INTERNAL.param.angle.Angle_Min, 65535);
+ float angle_max = to_float(PARAM_INTERNAL.angle.Angle_Max, 65535);
+ float angle_min = to_float(PARAM_INTERNAL.angle.Angle_Min, 65535);
hangle->f.Initialized = 1;
@@ -48,50 +48,6 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle)
}
-/**
- * @brief Управление углом через ПИД регулятор.
- * @param hangle Указатель на таймер
- * @param setpoint Уставка куда регулировать
- * @param measurement Измеренные регулируемые величины
- */
-void Angle_PID(Angle_Handle_t *hangle, float setpoint, float measurement)
-{
- if(assert_upp(hangle))
- return;
-
-
- /* Ошибка регулирования = уставка - измеренное */
- float err = setpoint - measurement;
-
- /* ПИД регулирование */
- float reverse_angle = arm_pid_f32(&hangle->pid, err); // 0 - открыть максимально поздно, 1 - открыть макситмально рано
-
- /* Ограничиваем диапазон и сохраняем в alpha */
- float angle = hangle->Config.AngleMax - reverse_angle;
- if (angle > hangle->Config.AngleMax) angle = hangle->Config.AngleMax;
- if(angle < hangle->Config.AngleMin) angle = hangle->Config.AngleMin;
-
- Angle_SetAngle(hangle, angle);
-}
-
-/**
- * @brief Сброс ПИД регулятора.
- * @param hangle Указатель на таймер
- */
-void Angle_PID_Reset(Angle_Handle_t *hangle)
-{
- if(assert_upp(hangle))
- return;
-
- /* Вычисляем выход PID */
- arm_pid_reset_f32(&hangle->pid);
-
- Angle_SetAngle(hangle, hangle->Config.AngleLimit);
- Angle_Reset(hangle, UPP_PHASE_A);
- Angle_Reset(hangle, UPP_PHASE_B);
- Angle_Reset(hangle, UPP_PHASE_C);
-}
-
/**
* @brief Инициализация ПИД регулятора.
* @param hangle Указатель на таймер
@@ -109,118 +65,89 @@ void Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd)
}
/**
- * @brief Инициализация углов открытия.
+ * @brief Управление углом через ПИД регулятор.
* @param hangle Указатель на таймер
- * @param AngleLimit Лимит AngleMax, рассчитывается от параметров ШИМ
- * @param AngleMin Минимально возможный угол открытия
- * @param AngleMax Максимально возможный угол открытия
- * @return HAL Status.
+ * @param setpoint Уставка куда регулировать
+ * @param measurement Измеренные регулируемые величины
*/
-HAL_StatusTypeDef Angle_SetRange(Angle_Handle_t *hangle, float AngleMin, float AngleMax)
+void Angle_PID(Angle_Handle_t *hangle, float setpoint, float measurement)
{
if(assert_upp(hangle))
- return HAL_ERROR;
- if(hangle->f.Running)
- return HAL_BUSY;
- if(AngleMax < 0 || AngleMax > 1)
- return HAL_ERROR;
- if(AngleMin < 0 || AngleMin > 1)
- return HAL_ERROR;
+ return;
+
+ /* Ошибка регулирования = уставка - измеренное */
+ float err = setpoint - measurement;
- if(AngleMax > hangle->Config.AngleLimit)
- AngleMax = hangle->Config.AngleLimit;
- if(AngleMin > hangle->Config.AngleLimit)
- AngleMin = hangle->Config.AngleLimit;
-
- if(AngleMin >= AngleMax)
- return HAL_ERROR;
-
- hangle->Config.AngleMax = AngleMax;
- hangle->Config.AngleMin = AngleMin;
-
- return HAL_OK;
+ /* ПИД регулирование */
+ float open_control = arm_pid_f32(&hangle->pid, err); // 0 - открыть максимально поздно, 1 - открыть макситмально рано
+
+ /* Ограничиваем диапазон */
+ if (open_control > 1) open_control = 1;
+ if(open_control < 0) open_control = 0;
+
+ /* Выставляем заданный уровень открытия */
+ Angle_SetAngle(hangle, open_control);
}
-
/**
- * @brief Выставление текущего угла открытия тиристоров.
+ * @brief Сброс ПИД регулятора.
* @param hangle Указатель на таймер
- * @param AngleLimit Лимит AngleMax, рассчитывается от параметров ШИМ
- * @param AngleMin Минимально возможный угол открытия
- * @param AngleMax Максимально возможный угол открытия
- * @return HAL Status.
*/
-HAL_StatusTypeDef Angle_SetAngle(Angle_Handle_t *hangle, float Angle)
+void Angle_PID_Reset(Angle_Handle_t *hangle)
{
if(assert_upp(hangle))
- return HAL_ERROR;
+ return;
- if(Angle > hangle->Config.AngleLimit)
- Angle = hangle->Config.AngleLimit;
-
- hangle->alpha = Angle;
-
- return HAL_OK;
+ /* Вычисляем выход PID */
+ arm_pid_reset_f32(&hangle->pid);
+
+ Angle_SetAngle(hangle, 0);
+ Angle_Reset(hangle, UPP_PHASE_A);
+ Angle_Reset(hangle, UPP_PHASE_B);
+ Angle_Reset(hangle, UPP_PHASE_C);
}
+
/**
- * @brief Инициализация предельного угла открытия.
+ * @brief Выставление степени открытия тиристоров.
* @param hangle Указатель на таймер
- * @param AngleLimit Лимит AngleMax, рассчитывается от параметров ШИМ
- * @param AngleMin Минимально возможный угол открытия
- * @param AngleMax Максимально возможный угол открытия
+ * @param OpenLevel Насколько открыть тиристор:
+ - 0 - полностбю закрыт,
+ - 1 - полностью открыт
* @return HAL Status.
*/
-HAL_StatusTypeDef Angle_SetLimit(Angle_Handle_t *hangle, float AngleLimit)
+HAL_StatusTypeDef Angle_SetAngle(Angle_Handle_t *hangle, float OpenLevel)
{
if(assert_upp(hangle))
return HAL_ERROR;
- if(hangle->f.Running)
- return HAL_BUSY;
+
+ /* Приводим уровень открытия к косинусу [-1:1]*/
+ float OpenLevelForCos = (OpenLevel*2)-1;
+
+ float alpha_rad = acosf(OpenLevelForCos); // угол в радианах
+ float alpha = alpha_rad/PI; // время открытие в процентах от периода - когда открыть
+
+ if(alpha > hangle->Config.AngleMax)
+ alpha = hangle->Config.AngleMax;
+ if(alpha < hangle->Config.AngleMin)
+ alpha = hangle->Config.AngleMin;
+// if(alpha > hangle->Config.PeriodLimit)
+// {
+// alpha = hangle->Config.PeriodLimit;
+// }
+
+// float alpha_degree = alpha*180;// угол в градусах
+// hangle->alpha_degree = alpha_degree;
+
+ hangle->alpha = alpha;
- if(AngleLimit < 0 || AngleLimit > 1)
- return HAL_ERROR;
- hangle->Config.AngleLimit = AngleLimit;
return HAL_OK;
}
-/**
- * @brief Хендл таймера для рассчета угла открытия.
- * @param hangle Указатель на таймер
- * @return HAL Status.
- */
-UPP_Phase_t Angle_Handle(Angle_Handle_t *hangle)
-{
- if(assert_upp(hangle))
- return UPP_PHASE_UNKNOWN;
-
-
- switch(hangle->htim->Channel)
- {
- case HAL_TIM_ACTIVE_CHANNEL_1:
- return UPP_PHASE_A;
- break;
-
- case HAL_TIM_ACTIVE_CHANNEL_2:
- return UPP_PHASE_B;
- break;
-
- case HAL_TIM_ACTIVE_CHANNEL_3:
- return UPP_PHASE_C;
- break;
-
- default:
- return UPP_PHASE_UNKNOWN;
- break;
- }
-
-
- return UPP_PHASE_UNKNOWN;
-}
/**
- * @brief Установка угла открытия в таймер.
+ * @brief Запуск отсчета угла открытия.
* @param hangle Указатель на таймер
* @param Phase Для какой фазы надо установить угол открытия
* @return HAL Status.
@@ -235,6 +162,7 @@ HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float P
{
return HAL_ERROR;
}
+ // Дополнительно проверяем на соответствие альфа диапазону
if(hangle->alpha > hangle->Config.AngleMax)
{
hangle->alpha = hangle->Config.AngleMax;
@@ -244,25 +172,47 @@ HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float P
hangle->alpha = hangle->Config.AngleMin;
}
+ // сколько тиков надо выждать для угла
uint32_t timer_ticks = TIM_MillisToTick(PeriodMs*hangle->alpha, ANGLE_TIM2_FREQ_MHZ);
+ // сколько тиков будет в таймере когда угол отсчитается (пойдет в CCRx регистр)
uint32_t ccr_ticks = __HAL_TIM_GET_COUNTER(hangle->htim) + timer_ticks;
+ // Выставялем
switch(Phase)
{
case UPP_PHASE_A:
__HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_1, ccr_ticks);
+ // Если слишком маленький timer_tick и счетчик уже перевалил за ccr, но не сгенерил прервыание:
+ if (__HAL_TIM_GET_COMPARE(hangle->htim, ANGLE_CHANNEL_1) <= __HAL_TIM_GET_COUNTER(hangle->htim))
+ {
+ // включаем прерывание вручную
+ HAL_TIM_GenerateEvent(hangle->htim, TIM_EVENTSOURCE_CC1);
+ }
+
__HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC1);
hangle->f.Running++;
break;
case UPP_PHASE_B:
__HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_2, ccr_ticks);
+ // Если слишком маленький timer_tick и счетчик уже перевалил за ccr, но не сгенерил прервыание:
+ if (__HAL_TIM_GET_COMPARE(hangle->htim, ANGLE_CHANNEL_2) <= __HAL_TIM_GET_COUNTER(hangle->htim))
+ {
+ // включаем прерывание вручную
+ HAL_TIM_GenerateEvent(hangle->htim, TIM_EVENTSOURCE_CC2);
+ }
__HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC2);
hangle->f.Running++;
break;
case UPP_PHASE_C:
__HAL_TIM_SET_COMPARE(hangle->htim, ANGLE_CHANNEL_3, ccr_ticks);
+ // Если слишком маленький timer_tick и счетчик уже перевалил за ccr, но не сгенерил прервыание:
+ if (__HAL_TIM_GET_COMPARE(hangle->htim, ANGLE_CHANNEL_3) <= __HAL_TIM_GET_COUNTER(hangle->htim))
+ {
+ // включаем прерывание вручную
+ HAL_TIM_GenerateEvent(hangle->htim, TIM_EVENTSOURCE_CC3);
+ }
__HAL_TIM_ENABLE_IT(hangle->htim, TIM_IT_CC3);
hangle->f.Running++;
break;
@@ -319,4 +269,99 @@ HAL_StatusTypeDef Angle_Reset(Angle_Handle_t *hangle, UPP_Phase_t Phase)
break;
}
return HAL_OK;
-}
\ No newline at end of file
+}
+
+
+
+
+/**
+ * @brief Инициализация предельного угла открытия.
+ * @param hangle Указатель на таймер
+ * @param PeriodLimit Лимит AngleMax, рассчитывается от параметров ШИМ
+ * @param AngleMin Минимально возможный угол открытия
+ * @param AngleMax Максимально возможный угол открытия
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef Angle_SetLimit(Angle_Handle_t *hangle, float PeriodLimit)
+{
+ if(assert_upp(hangle))
+ return HAL_ERROR;
+ if(hangle->f.Running)
+ return HAL_BUSY;
+
+ if(PeriodLimit < 0 || PeriodLimit > 1)
+ return HAL_ERROR;
+
+ hangle->Config.PeriodLimit = PeriodLimit;
+
+ return HAL_OK;
+}
+
+
+/**
+ * @brief Инициализация углов открытия.
+ * @param hangle Указатель на таймер
+ * @param PeriodLimit Лимит AngleMax, рассчитывается от параметров ШИМ
+ * @param AngleMin Минимально возможный угол открытия
+ * @param AngleMax Максимально возможный угол открытия
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef Angle_SetRange(Angle_Handle_t *hangle, float AngleMin, float AngleMax)
+{
+ if(assert_upp(hangle))
+ return HAL_ERROR;
+ if(hangle->f.Running)
+ return HAL_BUSY;
+ if(AngleMax < 0 || AngleMax > 1)
+ return HAL_ERROR;
+ if(AngleMin < 0 || AngleMin > 1)
+ return HAL_ERROR;
+
+ if(AngleMax > hangle->Config.PeriodLimit)
+ AngleMax = hangle->Config.PeriodLimit;
+ if(AngleMin > hangle->Config.PeriodLimit)
+ AngleMin = hangle->Config.PeriodLimit;
+
+ if(AngleMin >= AngleMax)
+ return HAL_ERROR;
+
+ hangle->Config.AngleMax = AngleMax;
+ hangle->Config.AngleMin = AngleMin;
+
+ return HAL_OK;
+}
+
+
+
+/**
+ * @brief Хендл таймера для рассчета угла открытия.
+ * @param hangle Указатель на таймер
+ * @return HAL Status.
+ * @details Просто возвращает фазу, у которой закончился отсчет угла
+ */
+UPP_Phase_t Angle_Handle(Angle_Handle_t *hangle)
+{
+ if(assert_upp(hangle))
+ return UPP_PHASE_UNKNOWN;
+
+
+ switch(hangle->htim->Channel)
+ {
+ case HAL_TIM_ACTIVE_CHANNEL_1:
+ return UPP_PHASE_A;
+ break;
+
+ case HAL_TIM_ACTIVE_CHANNEL_2:
+ return UPP_PHASE_B;
+ break;
+
+ case HAL_TIM_ACTIVE_CHANNEL_3:
+ return UPP_PHASE_C;
+ break;
+
+ default:
+ return UPP_PHASE_UNKNOWN;
+ break;
+ }
+ return UPP_PHASE_UNKNOWN;
+}
diff --git a/UPP/Core/UPP/angle_control.h b/UPP/Core/UPP/angle_control.h
index 527394a..89e3902 100644
--- a/UPP/Core/UPP/angle_control.h
+++ b/UPP/Core/UPP/angle_control.h
@@ -13,9 +13,9 @@
*/
typedef struct
{
- float AngleLimit; ///< Лимит AngleMax, рассчитывается от параметров ШИМ
- float AngleMin; ///< Минимально возможный угол открытия
- float AngleMax; ///< Максимально возможный угол открытия
+ float PeriodLimit; ///< Лимит периода, выше которого нельзя выставить рассчитывается от параметров ШИМ
+ float AngleMin; ///< Минимально возможный угол открытия
+ float AngleMax; ///< Максимально возможный угол открытия
}Angle_Config_t;
/**
@@ -23,10 +23,12 @@ typedef struct
*/
typedef struct
{
- TIM_HandleTypeDef *htim; ///< Указатель на таймер для расчета угла
- Angle_Config_t Config; ///< Конфигурации алгоритма расчета угла открытия тиристоров
+ TIM_HandleTypeDef *htim; ///< Указатель на таймер для расчета угла
+ Angle_Config_t Config; ///< Конфигурации алгоритма расчета угла открытия тиристоров
+
+ //float alpha_degree; ///< текущий угол открытия в градусах [0..180]
+ float alpha; ///< текущий угол открытия в процентах от периода [0..1]
- float alpha; ///< текущий угол открытия
arm_pid_instance_f32 pid; ///< ПИД регулятор для управления углом
struct {
@@ -35,25 +37,32 @@ typedef struct
} f; ///< Флаги
}Angle_Handle_t;
+
+// ====== ИНИЦИАЛИЗАЦИЯ ==========
/* Инициализация Таймера для рассчета угла открытия. */
HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle);
-/* Управление углом через ПИД регулятор */
-void Angle_PID(Angle_Handle_t *hangle, float setpoint, float measurement);
-/* Сброс ПИД регулятора. */
-void Angle_PID_Reset(Angle_Handle_t *hangle);
/* Инициализация ПИД регулятора. */
void Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd);
+
+// ====== УПРАВЛЕНИЕ ==========
+/* Управление углом через ПИД регулятор */
+void Angle_PID(Angle_Handle_t *hangle, float setpoint, float measurement);
/* Выставление текущего угла открытия тиристоров. */
HAL_StatusTypeDef Angle_SetAngle(Angle_Handle_t *hangle, float Angle);
-/* Инициализация углов открытия. */
-HAL_StatusTypeDef Angle_SetRange(Angle_Handle_t *hangle, float AngleMin, float AngleMax);
-/* Инициализация предельного угла открытия. */
-HAL_StatusTypeDef Angle_SetLimit(Angle_Handle_t *hangle, float AngleLimit);
/* Установка угла открытия в таймер. */
HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float PeriodMs);
+
+// ====== СБРОС ==========
/* Сброс угла открытия у таймера. */
HAL_StatusTypeDef Angle_Reset(Angle_Handle_t *hangle, UPP_Phase_t Phase);
+/* Сброс ПИД регулятора. */
+void Angle_PID_Reset(Angle_Handle_t *hangle);
+// ====== СЕРВИС ==========
+/* Инициализация предельного угла открытия. */
+HAL_StatusTypeDef Angle_SetLimit(Angle_Handle_t *hangle, float PeriodLimit);
+/* Инициализация углов открытия. */
+HAL_StatusTypeDef Angle_SetRange(Angle_Handle_t *hangle, float AngleMin, float AngleMax);
/* Хендл таймера для рассчета угла открытия. */
UPP_Phase_t Angle_Handle(Angle_Handle_t *hangle);
#endif /* _ANGLE_CONTROL_H_ */
diff --git a/UPP/Core/UPP/pwm_thyristors.c b/UPP/Core/UPP/pwm_thyristors.c
index b978b5e..383645b 100644
--- a/UPP/Core/UPP/pwm_thyristors.c
+++ b/UPP/Core/UPP/pwm_thyristors.c
@@ -58,7 +58,7 @@ 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, MB_INTERNAL.param.pwm.PhaseMask, MB_INTERNAL.param.pwm.Frequency, MB_INTERNAL.param.pwm.PulseNumber);
+ PWM_SetConfig(hpwm, PARAM_INTERNAL.pwm.PhaseMask, PARAM_INTERNAL.pwm.Frequency, PARAM_INTERNAL.pwm.PulseNumber);
HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_1);
HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_2);
@@ -77,7 +77,7 @@ HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm)
* @param hpwm Указатель на хендл ШИМ тиристоров
* @param Phase На какой фазе надо запустить ШИМ
* @return HAL Status.
- * @details Переводит автомат канала ШИМ в состояние запуска ШИМ.
+ * @details Переводит автомат состояний канала ШИМ в состояние запуска ШИМ.
*/
HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase)
{
@@ -184,14 +184,14 @@ HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm)
case PWM_THYR_TIM_START: // начать ШИМ (пачка импульсов)
__PWM_SetOutputState(hPhase, PWM_ENABLE);
- hPhase->PulseCnt = hpwm->Config.PulseNumber;
+ hPhase->PulseCnt = hpwm->Config.PulseNumber - 1; // 1 импульс уже прошел
hPhase->State = PWM_THYR_TIM_ACTIVE;
hpwm->f.Running++;
break;
case PWM_THYR_TIM_ACTIVE: // управление пачкой импульсов ШИМ
hPhase->PulseCnt--;
- if (hPhase->PulseCnt <= 0)
+ if (hPhase->PulseCnt <= 1) // если остался один импльс в след раз идем в PWM_THYR_TIM_DONE
{
hPhase->PulseCnt = 0;
hPhase->State = PWM_THYR_TIM_DONE;
diff --git a/UPP/Core/UPP/pwm_thyristors.h b/UPP/Core/UPP/pwm_thyristors.h
index 8780a92..5e01dae 100644
--- a/UPP/Core/UPP/pwm_thyristors.h
+++ b/UPP/Core/UPP/pwm_thyristors.h
@@ -85,9 +85,12 @@ typedef struct {
} f;
} PWM_Handle_t;
-/* ---- API ---- */
+
+// ====== ИНИЦИАЛИЗАЦИЯ ==========
/* Инициализация ШИМ тиристоров. */
HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm);
+
+// ====== УПРАВЛЕНИЕ ==========
/* Запуск ШИМ. */
HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase);
/* Остановить ШИМ. */
@@ -97,6 +100,7 @@ HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t
/* Установка полуволны для слежения. */
HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave);
+// ====== СЕРВИС ==========
/* Хендл ШИМ тиристоров. */
HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm);
#endif /* _PWM_THYRISTORS_H */
diff --git a/UPP/Core/UPP/upp_errors.c b/UPP/Core/UPP/upp_errors.c
index ad9b482..1ad798e 100644
--- a/UPP/Core/UPP/upp_errors.c
+++ b/UPP/Core/UPP/upp_errors.c
@@ -52,7 +52,7 @@ void UPP_Errors_Power(void)
void UPP_Errors_Ranges(void)
{
/* Преобразуем уставки в нормальные тики */
- float ticksTiMax = to_float(MB_DATA.HoldRegs.pui_params.TiMax, 1)/PM_SLOW_PERIOD_US;
+ float ticksTiMax = to_float(PARAM_PUI.TiMax, 1)/PM_SLOW_PERIOD_US;
/* Счетчики для отсчитывания задержки выставления ошибки */
static int IMaxCnt = 0;
static int UMaxCnt = 0;
diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c
index c039738..54158dc 100644
--- a/UPP/Core/UPP/upp_main.c
+++ b/UPP/Core/UPP/upp_main.c
@@ -21,7 +21,7 @@ int UPP_Init(void)
BenchTime_Init();
// Подключение указателей
upp.errors = &errors;
- upp.PUI.params = &MB_DATA.HoldRegs.pui_params;
+ upp.PUI.params = &PARAM_PUI;
upp.PUI.values = &MB_DATA.InRegs.pui;
upp.call = &MB_INTERNAL.FuncCalls;
@@ -40,7 +40,7 @@ int UPP_Init(void)
*/
int UPP_PreWhile(void)
{
- UPP_Control_InternalParams();
+ UPP_Params_InternalControl();
Angle_SetRange(&upp.hangle, 0.0, 0.8);
PowerMonitor_Start(&upp.pm);
return 0;
@@ -143,7 +143,7 @@ void UPP_Tick(void)
if(upp.workmode == WM_Not_Init)
return;
UPP_Errors_Handle();
- UPP_Control_InternalParams();
+ UPP_Params_InternalControl();
}
diff --git a/UPP/Core/UPP/upp_main.h b/UPP/Core/UPP/upp_main.h
index c5c45c8..d134455 100644
--- a/UPP/Core/UPP/upp_main.h
+++ b/UPP/Core/UPP/upp_main.h
@@ -15,7 +15,7 @@
#include "angle_control.h" // Управление углом открытия
#include "upp_status.h" // статус упп
-#include "upp_control.h" // управление упп
+#include "upp_params.h" // управление упп
typedef struct
diff --git a/UPP/Core/UPP/upp_control.c b/UPP/Core/UPP/upp_params.c
similarity index 67%
rename from UPP/Core/UPP/upp_control.c
rename to UPP/Core/UPP/upp_params.c
index 67d727d..54cef43 100644
--- a/UPP/Core/UPP/upp_control.c
+++ b/UPP/Core/UPP/upp_params.c
@@ -1,6 +1,6 @@
/**
******************************************************************************
-* @file upp_control.c
+* @file upp_params.c
* @brief Модуль определябщий поведение УПП
******************************************************************************
* @details
@@ -18,7 +18,7 @@ static void __AngleSetLimit(void);
* @brief Контроль внутренних параметров УПП.
* @return HAL Status.
*/
-void UPP_Control_InternalParams(void)
+void UPP_Params_InternalControl(void)
{
if(upp.call->go) // при запущеном УПП ничего не меняем
return;
@@ -51,23 +51,23 @@ void UPP_Control_InternalParams(void)
// Параметры регулятора Угла открытия
- if(__CheckSimpleParamF(&angle_max, MB_INTERNAL.param.angle.Angle_Max, 65535))
+ if(__CheckSimpleParamF(&angle_max, PARAM_INTERNAL.angle.Angle_Max, 65535))
{
alpha_update = 1;
}
- if(__CheckSimpleParamF(&angle_min, MB_INTERNAL.param.angle.Angle_Min, 65535))
+ if(__CheckSimpleParamF(&angle_min, PARAM_INTERNAL.angle.Angle_Min, 65535))
{
alpha_update = 1;
}
- if(__CheckSimpleParamF(&angle_pid_kp, MB_INTERNAL.param.angle.PID_Kp, 10000))
+ if(__CheckSimpleParamF(&angle_pid_kp, PARAM_INTERNAL.angle.PID_Kp, 10000))
{
alpha_update = 1;
}
- if(__CheckSimpleParamF(&angle_pid_ki, MB_INTERNAL.param.angle.PID_Ki, 10000))
+ if(__CheckSimpleParamF(&angle_pid_ki, PARAM_INTERNAL.angle.PID_Ki, 10000))
{
alpha_update = 1;
}
- if(__CheckSimpleParamF(&angle_pid_kd, MB_INTERNAL.param.angle.PID_Kd, 10000))
+ if(__CheckSimpleParamF(&angle_pid_kd, PARAM_INTERNAL.angle.PID_Kd, 10000))
{
alpha_update = 1;
}
@@ -81,42 +81,42 @@ void UPP_Control_InternalParams(void)
adc_channel_zero[i] = upp.pm.adc.Coefs[i].lZero;
// Максимальное измеряемое напряжение
- if(__CheckSimpleParamF(&adc_channel_max[i], MB_INTERNAL.param.adc.ADC_Max[i], 10))
+ if(__CheckSimpleParamF(&adc_channel_max[i], PARAM_INTERNAL.adc.ADC_Max[i], 10))
{
adc_channel_update[i] = 1;
}
// Значение АЦП при нулевом входе
- if(__CheckSimpleParamU16(&adc_channel_zero[i], MB_INTERNAL.param.adc.ADC_Zero[i]))
+ if(__CheckSimpleParamU16(&adc_channel_zero[i], PARAM_INTERNAL.adc.ADC_Zero[i]))
{
adc_channel_update[i] = 1;
}
}
// Параметры алгоритма перехода через ноль
- if(__CheckSimpleParamF(&zc_hysteresis, MB_INTERNAL.param.zc.Hysteresis, 10000))
+ if(__CheckSimpleParamF(&zc_hysteresis, PARAM_INTERNAL.zc.Hysteresis, 10000))
{
zc_update = 1;
}
- if(__CheckSimpleParamU16(&zc_debounce, MB_INTERNAL.param.zc.DebouneCouner))
+ if(__CheckSimpleParamU16(&zc_debounce, PARAM_INTERNAL.zc.DebouneCouner))
{
zc_update = 1;
}
// Параметры ШИМ токов
- if(__CheckSimpleParamU8(&pwm_phase_mask, MB_INTERNAL.param.pwm.PhaseMask, 1))
+ if(__CheckSimpleParamU8(&pwm_phase_mask, PARAM_INTERNAL.pwm.PhaseMask, 1))
{
pwm_update = 1;
}
- if(__CheckSimpleParamU16(&pwm_freq, MB_INTERNAL.param.pwm.Frequency))
+ if(__CheckSimpleParamU16(&pwm_freq, PARAM_INTERNAL.pwm.Frequency))
{
pwm_update = 1;
}
- if(__CheckSimpleParamU8(&pwm_pulse_num, MB_INTERNAL.param.pwm.PulseNumber, 1))
+ if(__CheckSimpleParamU8(&pwm_pulse_num, PARAM_INTERNAL.pwm.PulseNumber, 1))
{
pwm_update = 1;
}
// Параметры мониторинга
- if(__CheckSimpleParamF(&pm_alpha, MB_INTERNAL.param.pm.mean_alpha, 65535))
+ if(__CheckSimpleParamF(&pm_alpha, PARAM_INTERNAL.pm.mean_alpha, 65535))
{
for(int i = 0; i < EXP_ALL; i++)
{
@@ -162,7 +162,7 @@ void UPP_Control_InternalParams(void)
else
errors.prvt.cnt.pwm_reinit_err++;
}
- if (upp.hangle.Config.AngleLimit == 0)
+ if ((upp.hangle.Config.PeriodLimit == 0) || (upp.hangle.Config.PeriodLimit >= 0.999))
{
__AngleSetLimit();
}
@@ -179,59 +179,60 @@ void UPP_SetDefault(int pui_default, int internal_default)
{
if(pui_default)
{
- MB_DATA.HoldRegs.pui_params.Iref = PUI_Iref_PERCENT_DEFAULT;
- MB_DATA.HoldRegs.pui_params.Tnt = PUI_Tnt_MS_DEFAULT;
- MB_DATA.HoldRegs.pui_params.Umin = PUI_Umin_PERCENT_DEFAULT;
- MB_DATA.HoldRegs.pui_params.Umax = PUI_Umax_PERCENT_DEFAULT;
- MB_DATA.HoldRegs.pui_params.Imax = PUI_Imax_PERCENT_DEFAULT;
- MB_DATA.HoldRegs.pui_params.Imin = PUI_Imin_PERCENT_DEFAULT;
- MB_DATA.HoldRegs.pui_params.TiMax = PUI_TiMax_US_DEFAULT;
- MB_DATA.HoldRegs.pui_params.Tdelay = PUI_Tdelay_SECONDS_DEFAULT;
- MB_DATA.HoldRegs.pui_params.Interlace = PUI_Interlace_EN_DEFAULT;
+ PARAM_PUI.Iref = PUI_Iref_PERCENT_DEFAULT;
+ PARAM_PUI.Tnt = PUI_Tnt_MS_DEFAULT;
+ PARAM_PUI.Umin = PUI_Umin_PERCENT_DEFAULT;
+ PARAM_PUI.Umax = PUI_Umax_PERCENT_DEFAULT;
+ PARAM_PUI.Imax = PUI_Imax_PERCENT_DEFAULT;
+ PARAM_PUI.Imin = PUI_Imin_PERCENT_DEFAULT;
+ PARAM_PUI.TiMax = PUI_TiMax_US_DEFAULT;
+ PARAM_PUI.Tdelay = PUI_Tdelay_SECONDS_DEFAULT;
+ PARAM_PUI.Interlace = PUI_Interlace_EN_DEFAULT;
}
if(internal_default)
{
- MB_INTERNAL.param.setpoints.TemperatureWarn = SETPOINT_TEMP_WARN*10;
- MB_INTERNAL.param.setpoints.TemperatureErr = SETPOINT_TEMP_ERR*10;
+ PARAM_INTERNAL.setpoints.TemperatureWarn = SETPOINT_TEMP_WARN*10;
+ PARAM_INTERNAL.setpoints.TemperatureErr = SETPOINT_TEMP_ERR*10;
- MB_INTERNAL.param.nominal.PhaseNumber = NOM_PHASE_NUMB;
- MB_INTERNAL.param.nominal.U = NOM_U_V_DEFAULT*10;
- MB_INTERNAL.param.nominal.U_deviation_plus = NOM_U_DEVIATION_PLUS_PERCENT_DEFAULT*100;
- MB_INTERNAL.param.nominal.U_deviation_minus = NOM_U_DEVIATION_MINUS_PERCENT_DEFAULT*100;
- MB_INTERNAL.param.nominal.F = NOM_F_HZ_DEFAULT*100;
- MB_INTERNAL.param.nominal.F_deviation_plus = NOM_F_DEVIATION_PLUS_PERCENT_DEFAULT*100;
- MB_INTERNAL.param.nominal.F_deviation_minus = NOM_F_DEVIATION_MINUS_PERCENT_DEFAULT*100;
- MB_INTERNAL.param.nominal.I = NOM_I_A_DEFAULT*10;
+ PARAM_INTERNAL.nominal.PhaseNumber = NOM_PHASE_NUMB;
+ PARAM_INTERNAL.nominal.U = NOM_U_V_DEFAULT*10;
+ PARAM_INTERNAL.nominal.U_deviation_plus = NOM_U_DEVIATION_PLUS_PERCENT_DEFAULT*100;
+ PARAM_INTERNAL.nominal.U_deviation_minus = NOM_U_DEVIATION_MINUS_PERCENT_DEFAULT*100;
+ PARAM_INTERNAL.nominal.F = NOM_F_HZ_DEFAULT*100;
+ PARAM_INTERNAL.nominal.F_deviation_plus = NOM_F_DEVIATION_PLUS_PERCENT_DEFAULT*100;
+ PARAM_INTERNAL.nominal.F_deviation_minus = NOM_F_DEVIATION_MINUS_PERCENT_DEFAULT*100;
+ PARAM_INTERNAL.nominal.I = NOM_I_A_DEFAULT*10;
- MB_INTERNAL.param.pm.mean_alpha = PM_EXP_ALPHA_COEF_DEFAULT*65535;
+ PARAM_INTERNAL.pm.mean_alpha = PM_EXP_ALPHA_COEF_DEFAULT*65535;
- MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UBA] = ADC_U_MAX_V_DEFAULT*10;
- MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UAC] = ADC_U_MAX_V_DEFAULT*10;
- MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IC] = ADC_I_MAX_A_DEFAULT*10;
- MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IA] = ADC_I_MAX_A_DEFAULT*10;
- MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_UBA] = ADC_U_ZERO_DEFAULT;
- MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_UAC] = ADC_U_ZERO_DEFAULT;
- MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_IC] = ADC_I_ZERO_DEFAULT;
- MB_INTERNAL.param.adc.ADC_Zero[ADC_CHANNEL_IA] = ADC_I_ZERO_DEFAULT;
+ 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;
+ PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IC] = ADC_I_MAX_A_DEFAULT*10;
+ PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IA] = ADC_I_MAX_A_DEFAULT*10;
+ PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UBA] = ADC_U_ZERO_DEFAULT;
+ PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UAC] = ADC_U_ZERO_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;
- MB_INTERNAL.param.pwm.PhaseMask = 0x7; // (все три фазы)
- MB_INTERNAL.param.pwm.Frequency = (float)PWM_THYR_FREQUENCY_HZ_DEFAULT;
- MB_INTERNAL.param.pwm.PulseNumber = PWM_THYR_PULSE_NUMBER_DEFAULT;
+ PARAM_INTERNAL.pwm.PhaseMask = 0x7; // (все три фазы)
+ PARAM_INTERNAL.pwm.Frequency = (float)PWM_THYR_FREQUENCY_HZ_DEFAULT;
+ PARAM_INTERNAL.pwm.PulseNumber = PWM_THYR_PULSE_NUMBER_DEFAULT;
- MB_INTERNAL.param.zc.Hysteresis = ZERO_CROSS_HYSTERESIS_PERCENT_DEFAULT*100;
- MB_INTERNAL.param.zc.DebouneCouner = ZERO_CROSS_DEBOUNCE_CNT_DEFAULT;
+ PARAM_INTERNAL.zc.Hysteresis = ZERO_CROSS_HYSTERESIS_PERCENT_DEFAULT*100;
+ PARAM_INTERNAL.zc.DebouneCouner = ZERO_CROSS_DEBOUNCE_CNT_DEFAULT;
//__AngleSetLimit();
}
}
+// Перерасчет максимально допустимого угла
static void __AngleSetLimit(void)
-{
- // Перерасчет максимально допустимого угла
- float pulses_percent_of_period = ((MB_INTERNAL.param.pwm.PulseNumber / MB_INTERNAL.param.pwm.Frequency) * 1000) / ANGLE_PERIOD_MS(NOM_F_HZ_DEFAULT);
- float angle_limit = 1 - pulses_percent_of_period;
+{ // Сколько пачка ипульсов занимает процентов от всего периода
+ float pulses_percent_of_period = (((float)PARAM_INTERNAL.pwm.PulseNumber / PARAM_INTERNAL.pwm.Frequency) * 1000) / ANGLE_PERIOD_MS(NOM_F_HZ_DEFAULT);
+ // Вычитаем этот процент из 1 - получаем максимально безопасный угол
+ float angle_limit = 1 - pulses_percent_of_period*1.5; // добавляем запас в половину пачки импульсов
Angle_SetLimit(&upp.hangle, angle_limit);
}
diff --git a/UPP/Core/UPP/upp_control.h b/UPP/Core/UPP/upp_params.h
similarity index 96%
rename from UPP/Core/UPP/upp_control.h
rename to UPP/Core/UPP/upp_params.h
index 5836033..d57e813 100644
--- a/UPP/Core/UPP/upp_control.h
+++ b/UPP/Core/UPP/upp_params.h
@@ -1,13 +1,13 @@
/**
******************************************************************************
-* @file upp_control.h
+* @file upp_params.h
* @brief Модуль определябщий поведение УПП
******************************************************************************
* @details
******************************************************************************/
-#ifndef _UPP_CONTROL_H
-#define _UPP_CONTROL_H
+#ifndef _UPP_PARAMS_H
+#define _UPP_PARAMS_H
#include "upp_defs.h"
#define to_float(_u16_, _coef_) ((float)_u16_/_coef_)
@@ -93,8 +93,8 @@ typedef struct
/* Контроль внутренних параметров УПП. */
-void UPP_Control_InternalParams(void);
+void UPP_Params_InternalControl(void);
/* Установка параметров на дефолтные значения */
void UPP_SetDefault(int pui_default, int internal_default);
-#endif //_UPP_CONTROL_H
\ No newline at end of file
+#endif //_UPP_PARAMS_H
\ No newline at end of file
diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx
index fd4f4c5..a772821 100644
--- a/UPP/MDK-ARM/UPP.uvoptx
+++ b/UPP/MDK-ARM/UPP.uvoptx
@@ -411,30 +411,6 @@
0
0
0
- ..\Core\UPP\upp_control.c
- upp_control.c
- 0
- 0
-
-
- 2
- 18
- 5
- 0
- 0
- 0
- ..\Core\UPP\upp_control.h
- upp_control.h
- 0
- 0
-
-
- 2
- 19
- 1
- 0
- 0
- 0
..\Core\UPP\upp_status.c
upp_status.c
0
@@ -442,7 +418,7 @@
2
- 20
+ 18
5
0
0
@@ -454,7 +430,7 @@
2
- 21
+ 19
1
0
0
@@ -466,7 +442,7 @@
2
- 22
+ 20
5
0
0
@@ -476,6 +452,30 @@
0
0
+
+ 2
+ 21
+ 1
+ 0
+ 0
+ 0
+ ..\Core\UPP\upp_params.c
+ upp_params.c
+ 0
+ 0
+
+
+ 2
+ 22
+ 5
+ 0
+ 0
+ 0
+ ..\Core\UPP\upp_params.h
+ upp_params.h
+ 0
+ 0
+
diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx
index 24baab7..3da23b5 100644
--- a/UPP/MDK-ARM/UPP.uvprojx
+++ b/UPP/MDK-ARM/UPP.uvprojx
@@ -470,16 +470,6 @@
5
..\Core\UPP\angle_control.h
-
- upp_control.c
- 1
- ..\Core\UPP\upp_control.c
-
-
- upp_control.h
- 5
- ..\Core\UPP\upp_control.h
-
upp_status.c
1
@@ -500,6 +490,16 @@
5
..\Core\UPP\upp_errors.h
+
+ upp_params.c
+ 1
+ ..\Core\UPP\upp_params.c
+
+
+ upp_params.h
+ 5
+ ..\Core\UPP\upp_params.h
+