рефакторинг и вроде бы понял как надо управлять импульсами

надо доделать и проверить
This commit is contained in:
Razvalyaev 2025-12-04 15:01:55 +03:00
parent c0eea077d9
commit aa59f84fb7
16 changed files with 156 additions and 146 deletions

View File

@ -35,19 +35,19 @@ void Write_UPP_Outputs(real_T* Buffer, int ind_port)
//int pwm4_pin = PIN_READ(PWM4);
//int pwm5_pin = PIN_READ(PWM5);
//int pwm6_pin = PIN_READ(PWM6);
//int pwm1_pin = (upp.hpwm.AllPhases[PHASE_A_POS].State == PWM_THYR_TIM_ACTIVE);
//int pwm2_pin = (upp.hpwm.AllPhases[PHASE_A_NEG].State == PWM_THYR_TIM_ACTIVE);
//int pwm3_pin = (upp.hpwm.AllPhases[PHASE_B_POS].State == PWM_THYR_TIM_ACTIVE);
//int pwm4_pin = (upp.hpwm.AllPhases[PHASE_B_NEG].State == PWM_THYR_TIM_ACTIVE);
//int pwm5_pin = (upp.hpwm.AllPhases[PHASE_C_POS].State == PWM_THYR_TIM_ACTIVE);
//int pwm6_pin = (upp.hpwm.AllPhases[PHASE_C_NEG].State == PWM_THYR_TIM_ACTIVE);
int pwm1_pin = (upp.hpwm.AllPhases[PHASE_A_POS].State == PWM_THYR_TIM_ACTIVE);
int pwm2_pin = (upp.hpwm.AllPhases[PHASE_A_NEG].State == PWM_THYR_TIM_ACTIVE);
int pwm3_pin = (upp.hpwm.AllPhases[PHASE_B_POS].State == PWM_THYR_TIM_ACTIVE);
int pwm4_pin = (upp.hpwm.AllPhases[PHASE_B_NEG].State == PWM_THYR_TIM_ACTIVE);
int pwm5_pin = (upp.hpwm.AllPhases[PHASE_C_POS].State == PWM_THYR_TIM_ACTIVE);
int pwm6_pin = (upp.hpwm.AllPhases[PHASE_C_NEG].State == PWM_THYR_TIM_ACTIVE);
pwm_wtf(upp.hpwm.AllPhases[PHASE_A_POS].State, upp.hpwm.AllPhases[PHASE_A_NEG].State, &pwm1_pin);
pwm_wtf(upp.hpwm.AllPhases[PHASE_A_NEG].State, upp.hpwm.AllPhases[PHASE_A_POS].State, &pwm2_pin);
pwm_wtf(upp.hpwm.AllPhases[PHASE_B_POS].State, upp.hpwm.AllPhases[PHASE_B_NEG].State, &pwm3_pin);
pwm_wtf(upp.hpwm.AllPhases[PHASE_B_NEG].State, upp.hpwm.AllPhases[PHASE_B_POS].State, &pwm4_pin);
pwm_wtf(upp.hpwm.AllPhases[PHASE_C_POS].State, upp.hpwm.AllPhases[PHASE_C_NEG].State, &pwm5_pin);
pwm_wtf(upp.hpwm.AllPhases[PHASE_C_NEG].State, upp.hpwm.AllPhases[PHASE_C_POS].State, &pwm6_pin);
//pwm_wtf(upp.hpwm.AllPhases[PHASE_A_POS].State, upp.hpwm.AllPhases[PHASE_A_NEG].State, &pwm1_pin);
//pwm_wtf(upp.hpwm.AllPhases[PHASE_A_NEG].State, upp.hpwm.AllPhases[PHASE_A_POS].State, &pwm2_pin);
//pwm_wtf(upp.hpwm.AllPhases[PHASE_B_POS].State, upp.hpwm.AllPhases[PHASE_B_NEG].State, &pwm3_pin);
//pwm_wtf(upp.hpwm.AllPhases[PHASE_B_NEG].State, upp.hpwm.AllPhases[PHASE_B_POS].State, &pwm4_pin);
//pwm_wtf(upp.hpwm.AllPhases[PHASE_C_POS].State, upp.hpwm.AllPhases[PHASE_C_NEG].State, &pwm5_pin);
//pwm_wtf(upp.hpwm.AllPhases[PHASE_C_NEG].State, upp.hpwm.AllPhases[PHASE_C_POS].State, &pwm6_pin);
int err = PIN_READ(RDO1);
int work = PIN_READ(RDO2);
int ready = PIN_READ(RDO3);

Binary file not shown.

View File

@ -26,7 +26,6 @@
#define UPP_SIMULATE_I ///< Симулировт токи (Iref/2) а не брать с АЦП
#define UPP_DISABLE_PROTECT_BOARDPOWER ///< Отключить проверки питания плат (+24, +5 В)
#define UPP_DISABLE_PROTECT_LOSS_PHASE ///< Отключить проверки на потерянные фазы
//#define UPP_ANGLE_COSINE ///< Расчет угла через acos, а не линейно
/** //UPP_PARAMS_TEST
* @}

View File

@ -152,6 +152,8 @@ typedef struct {
// Проверка корректности структуры
#define assert_upp(_struct_) check_null_ptr_2(_struct_, (_struct_)->f.Initialized)
// Проверка корректности структуры и фазы
#define assert_upp_phase(_struct_, _phase_) (check_null_ptr_2(_struct_, (_struct_)->f.Initialized) || (_phase_ >= 3))
/* Дефайны для индексов */

View File

@ -30,34 +30,8 @@ HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm)
if(ADC_Init(&hpm->adc, &adc_tim, &hadc3) != HAL_OK)
return HAL_ERROR;
/* Инициализация каналов АЦП */
if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_UBA,
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UBA],
u2f(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UBA], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_UAC,
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UAC],
u2f(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UAC], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_IC,
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IC],
u2f(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IC], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&hpm->adc, ADC_CHANNEL_IA,
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IA],
u2f(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IA], 10),
4095) != HAL_OK)
return HAL_ERROR;
/* Инициализация алгоритма перехода через ноль */
if(ZC_Init(&hpm->zc, 3, u2f(PARAM_INTERNAL.zc.Hysteresis, 100), PARAM_INTERNAL.zc.DebouneCouner) != HAL_OK)
if(ZC_Init(&hpm->zc, 3, 0, 0) != HAL_OK)
return HAL_ERROR;
/* Инициализация каналов алгоритма перехода через ноль */
@ -69,21 +43,6 @@ HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm)
return HAL_ERROR;
/* Инициализация RMS фильтра медленного алга */
for(int i = 0; i < RMS_ALL; i++)
{
if(FilterRMS_Init(&hpm->rms[i], PARAM_INTERNAL.pm.rms_window_size))
return HAL_ERROR;
Filter_Start(&hpm->rms[i]);
}
/* Инициализация экпоненциального фильтра медленного алга */
for(int i = 0; i < RMS_EXP_ALL; i++)
{
if(FilterExp_Init(&hpm->rms_exp[i], u2f(PARAM_INTERNAL.pm.rms_exp_alpha, 65535)))
return HAL_ERROR;
Filter_Start(&hpm->rms_exp[i]);
}
/* Инициализация среднего фильтра медленного алга */
for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
{

View File

@ -32,19 +32,11 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle)
Angle_Reset(hangle, UPP_PHASE_B);
Angle_Reset(hangle, UPP_PHASE_C);
// Инициализация углов
float angle_max = u2f(PARAM_INTERNAL.angle.Angle_Max, 65535);
float angle_min = u2f(PARAM_INTERNAL.angle.Angle_Min, 65535);
hangle->f.Initialized = 1;
hangle->Config.PeriodLimit = 1;
// Инициализация ПИД
float kp = u2f(PARAM_INTERNAL.angle.PID_Kp, 10000);
float ki = u2f(PARAM_INTERNAL.angle.PID_Ki, 10000);
float kd = u2f(PARAM_INTERNAL.angle.PID_Kd, 10000);
float ref_alpha = PUI_Tnt_CalcAlpha(u2f(PARAM_PUI.Tnt, 1000), PM_SLOW_PERIOD_US);
return Angle_PID_Init(hangle, kp, ki, kd, ref_alpha);
return HAL_OK;
}
@ -89,14 +81,20 @@ void Angle_PID(Angle_Handle_t *hangle, float setpoint, float measurement)
float err = hangle->Iref - hangle->Imeas;
/* ПИД регулирование */
float open_control = arm_pid_f32(&hangle->pid, err); // 0 - открыть максимально поздно, 1 - открыть макситмально рано
float open_level = arm_pid_f32(&hangle->pid, err); // 0 - открыть максимально поздно, 1 - открыть макситмально рано
/* Ограничиваем диапазон */
if (open_control > 1) open_control = 1;
if(open_control < 0) open_control = 0;
if (open_level > 1) open_level = 1;
if(open_level < 0) open_level = 0;
/* Приводим уровень открытия к косинусу [-1:1]*/
float OpenLevelForCos = (open_level*2)-1;
float alpha_rad = acosf(OpenLevelForCos); // угол в радианах
float alpha = alpha_rad/PI* hangle->Config.PeriodLimit; // угол открытия тиристора в о.е. от максимально заданного
/* Выставляем заданный уровень открытия */
Angle_SetAngle(hangle, open_control);
Angle_SetAlpha(hangle, alpha);
}
/**
@ -118,7 +116,8 @@ void Angle_PID_Reset(Angle_Handle_t *hangle)
Filter_Start(&hangle->refFilter);
Filter_Process(&hangle->refFilter, 0);
Angle_SetAngle(hangle, 0);
Angle_SetAlpha(hangle, 1); // максимально закрываем
Angle_Reset(hangle, UPP_PHASE_A);
Angle_Reset(hangle, UPP_PHASE_B);
Angle_Reset(hangle, UPP_PHASE_C);
@ -127,40 +126,27 @@ void Angle_PID_Reset(Angle_Handle_t *hangle)
/**
* @brief Выставление степени открытия тиристоров.
* @param hangle Указатель на таймер
* @param OpenLevel Насколько открыть тиристор:
- 0 - максимально закрыт,
- 1 - максимально открыт
* @param hangle Указатель на таймер
* @param Alpha Угол открытия тиристора в о.е. от 180 градусов:
- 0 - максимально закрыт,
- 1 - максимально открыт
* @return HAL Status.
*/
HAL_StatusTypeDef Angle_SetAngle(Angle_Handle_t *hangle, float OpenLevel)
HAL_StatusTypeDef Angle_SetAlpha(Angle_Handle_t *hangle, float Alpha)
{
if(assert_upp(hangle))
return HAL_ERROR;
/* Приводим уровень открытия к косинусу [-1:1]*/
#ifdef UPP_ANGLE_COSINE
float OpenLevelForCos = (OpenLevel*2)-1;
float alpha_rad = acosf(OpenLevelForCos); // угол в радианах
float alpha = alpha_rad/PI* hangle->Config.PeriodLimit; // время открытие в процентах от периода - когда открыть
#else
float alpha = (1-OpenLevel) * hangle->Config.PeriodLimit; // время открытие в процентах от периода - когда открыть
#endif
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;
// }
if(Alpha > hangle->Config.AngleMax)
Alpha = hangle->Config.AngleMax;
if(Alpha < hangle->Config.AngleMin)
Alpha = hangle->Config.AngleMin;
// float alpha_degree = alpha*180;// угол в градусах
// hangle->alpha_degree = alpha_degree;
hangle->alpha = alpha;
// сколько надо выжидать исходя из заданного угла
hangle->alpha_real = Alpha + (30.0/180.0); // 30 градусов - сдвиг между линейными и фазными напряжениями
hangle->alpha = Alpha;
@ -175,26 +161,11 @@ HAL_StatusTypeDef Angle_SetAngle(Angle_Handle_t *hangle, float OpenLevel)
*/
HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float PeriodMs)
{
if(assert_upp(hangle))
if(assert_upp_phase(hangle, Phase))
return HAL_ERROR;
// Если канал дурацкий - возвращаем ошибку
if(Phase >= 3)
{
return HAL_ERROR;
}
// Дополнительно проверяем на соответствие альфа диапазону
if(hangle->alpha > hangle->Config.AngleMax)
{
hangle->alpha = hangle->Config.AngleMax;
}
if(hangle->alpha < hangle->Config.AngleMin)
{
hangle->alpha = hangle->Config.AngleMin;
}
// сколько тиков надо выждать для угла
uint32_t timer_ticks = TIM_MillisToTick(PeriodMs*hangle->alpha, ANGLE_TIM2_FREQ_MHZ);
uint32_t timer_ticks = TIM_MillisToTick(PeriodMs*hangle->alpha_real, ANGLE_TIM2_FREQ_MHZ);
// сколько тиков будет в таймере когда угол отсчитается (пойдет в CCRx регистр)
uint32_t ccr_ticks = __HAL_TIM_GET_COUNTER(hangle->htim) + timer_ticks;
@ -259,15 +230,9 @@ HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float P
*/
HAL_StatusTypeDef Angle_Reset(Angle_Handle_t *hangle, UPP_Phase_t Phase)
{
if(assert_upp(hangle))
if(assert_upp_phase(hangle, Phase))
return HAL_ERROR;
// Если канал дурацкий - возвращаем ошибку
if(Phase >= 3)
{
return HAL_ERROR;
}
switch(Phase)
{
case UPP_PHASE_A:

View File

@ -27,8 +27,13 @@ typedef struct
Angle_Config_t Config; ///< Конфигурации алгоритма расчета угла открытия тиристоров
float Iref; ///< текущее задание тока в о.е. [0..1]
float Imeas; ///< измеренное значение тока в о.е. [0..1]
float alpha; ///< текущий угол открытия в о.е. [0..1] (% от периода)
float Imeas; ///< измеренное значение тока в о.е. [0..1]
float alpha; ///< текущий угол открытия в о.е. [0..1] от 180 градусов
float alpha_real; /*!< @brief Фактический отсчитываемый угол открытия в о.е. [0..1] от 180 градусов
@details Этот угол отличается от @ref alpha дополнительными задержками и компенсациями:
- 30 градусов - смещение между линейными и фазными напряжение (мы смотрим линейные, а коммутируем фазные) */
arm_pid_instance_f32 pid; ///< ПИД регулятор для управления углом
FilterExp_t refFilter; ///< Фильтр для плавного нарастания регулирования
@ -50,7 +55,7 @@ HAL_StatusTypeDef Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, flo
/* Управление углом через ПИД регулятор */
void Angle_PID(Angle_Handle_t *hangle, float setpoint, float measurement);
/* Выставление текущего угла открытия тиристоров. */
HAL_StatusTypeDef Angle_SetAngle(Angle_Handle_t *hangle, float Angle);
HAL_StatusTypeDef Angle_SetAlpha(Angle_Handle_t *hangle, float Angle);
/* Установка угла открытия в таймер. */
HAL_StatusTypeDef Angle_Start(Angle_Handle_t *hangle, UPP_Phase_t Phase, float PeriodMs);

View File

@ -59,11 +59,6 @@ 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,
u2f(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);
HAL_TIM_PWM_Start(&hpwm1, PWM_CHANNEL_3);
@ -88,16 +83,11 @@ HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm)
*/
HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase)
{
if(assert_upp(hpwm))
if(assert_upp_phase(hpwm, Phase))
return HAL_ERROR;
// Если уже какой-то канал запущен - не запускаем
if(hpwm->f.Running)
return HAL_BUSY;
// Если канал дурацкий - возвращаем ошибку
if(Phase >= 3)
{
return HAL_ERROR;
}
if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
return HAL_ERROR;
@ -149,7 +139,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)
{
if(assert_upp(hpwm))
if(assert_upp_phase(hpwm, Phase))
return HAL_ERROR;
// Если force_stop_all - сбрасываем ВСЕ КАНАЛЫ
@ -170,11 +160,6 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_
// Если НЕ force_stop_all - сбрасываем ТОЛЬКО заданный канал
else
{
// Если канал дурацкий - возвращаем ошибку
if(Phase >= 3)
{
return HAL_ERROR;
}
if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN])
return HAL_ERROR;
@ -251,18 +236,12 @@ 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)
{
if(assert_upp(hpwm))
if(assert_upp_phase(hpwm, Phase))
return HAL_ERROR;
// Сбрасываем текущий канал
PWM_Stop(hpwm, Phase, 0);
// Если канал дурацкий - выставляем заглушку
if(Phase >= 3)
{
hpwm->Phase[Phase] = &hpwm->AllPhases[PHASE_UNKNOWN];
return HAL_ERROR;
}
// Выставляем канал
switch(halfwave)
{

View File

@ -51,6 +51,10 @@ int UPP_App_Init(void)
return 1;
}
if(UPP_Params_Init() != HAL_OK)
{
return 1;
}
return 0;
}

View File

@ -270,6 +270,89 @@ void UPP_Params_ControlInternal(void)
/**
* @brief Инициализация параметров УПП.
* @return HAL Status.
*/
HAL_StatusTypeDef UPP_Params_Init(void)
{
/*====== ИНИЦИАЛИЗАЦИЯ МОДУЛЯ angle_control ======*/
// Инициализация ПИД
if(Angle_PID_Init(&upp.hangle,
u2f(PARAM_INTERNAL.angle.PID_Kp, 10000),
u2f(PARAM_INTERNAL.angle.PID_Ki, 10000),
u2f(PARAM_INTERNAL.angle.PID_Kd, 10000),
PUI_Tnt_CalcAlpha(u2f(PARAM_PUI.Tnt, 1000), PM_SLOW_PERIOD_US)) != HAL_OK)
return HAL_ERROR;
// Инициализация углов
if(Angle_SetRange(&upp.hangle,
u2f(PARAM_INTERNAL.angle.Angle_Min, 65535),
u2f(PARAM_INTERNAL.angle.Angle_Max, 65535)) != HAL_OK)
return HAL_ERROR;
/*===== ИНИЦИАЛИЗАЦИЯ МОДУЛЯ power_monitor ======*/
/* Инициализация каналов АЦП */
if(ADC_ConfigChannel(&upp.pm.adc, ADC_CHANNEL_UBA,
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UBA],
u2f(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UBA], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&upp.pm.adc, ADC_CHANNEL_UAC,
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_UAC],
u2f(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UAC], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&upp.pm.adc, ADC_CHANNEL_IC,
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IC],
u2f(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IC], 10),
4095) != HAL_OK)
return HAL_ERROR;
if(ADC_ConfigChannel(&upp.pm.adc, ADC_CHANNEL_IA,
PARAM_INTERNAL.adc.ADC_Zero[ADC_CHANNEL_IA],
u2f(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IA], 10),
4095) != HAL_OK)
return HAL_ERROR;
/* Инициализация алгоритма перехода через ноль */
if(ZC_Init(&upp.pm.zc, 3, u2f(PARAM_INTERNAL.zc.Hysteresis, 100), PARAM_INTERNAL.zc.DebouneCouner) != HAL_OK)
return HAL_ERROR;
/* Инициализация RMS фильтра медленного алга */
for(int i = 0; i < RMS_ALL; i++)
{
if(FilterRMS_Init(&upp.pm.rms[i], PARAM_INTERNAL.pm.rms_window_size))
return HAL_ERROR;
Filter_Start(&upp.pm.rms[i]);
}
/* Инициализация экпоненциального фильтра медленного алга */
for(int i = 0; i < RMS_EXP_ALL; i++)
{
if(FilterExp_Init(&upp.pm.rms_exp[i], u2f(PARAM_INTERNAL.pm.rms_exp_alpha, 65535)))
return HAL_ERROR;
Filter_Start(&upp.pm.rms_exp[i]);
}
/*====== ИНИЦИАЛИЗАЦИЯ МОДУЛЯ pwm_thyristors ======*/
if(PWM_SetConfig(&upp.hpwm, PARAM_INTERNAL.pwm.PhaseMask,
PARAM_INTERNAL.pwm.Frequency,
u2f(PARAM_INTERNAL.pwm.Duty, 100),
PARAM_INTERNAL.pwm.PulseNumber) != HAL_OK)
return HAL_ERROR;
return HAL_OK;
}
/**
* @brief Контроль параметров УПП на корректные значения.
* @return HAL Status.

View File

@ -101,6 +101,8 @@ void UPP_Params_Control(void);
void UPP_Params_ControlPUI(void);
/* Контроль внутренних параметров УПП. */
void UPP_Params_ControlInternal(void);
/* Инициализация параметров УПП. */
HAL_StatusTypeDef UPP_Params_Init(void);
/* Контроль параметров УПП на корректные значения. */
void UPP_Params_Saturate(void);
/* Установка параметров на дефолтные значения */

View File

@ -0,0 +1,12 @@
open_level = 0:0.01:1; % Степень регулирования выходного напряжения (epsilon) от 0 до 1
OpenLevelForCos = (open_level.*2)-1;
alpha_rad = acos(OpenLevelForCos); % угол в радианах
alpha = alpha_rad/pi; % угол открытия тиристора в о.е. от максимально заданного
plot(alpha, open_level)
grid on;
xlabel('\alpha, о.е. (от \pi)');
ylabel('\epsilon, о.е.');
title('Регулировочная характеристика \epsilon');
legend('ε = cos(α)');