рефакторинг и вроде бы понял как надо управлять импульсами
надо доделать и проверить
This commit is contained in:
parent
c0eea077d9
commit
aa59f84fb7
@ -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.
@ -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
|
||||
* @}
|
||||
|
||||
@ -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))
|
||||
|
||||
|
||||
/* Дефайны для индексов */
|
||||
|
||||
@ -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++)
|
||||
{
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -51,6 +51,10 @@ int UPP_App_Init(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(UPP_Params_Init() != HAL_OK)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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);
|
||||
/* Установка параметров на дефолтные значения */
|
||||
|
||||
12
Информация для программиста (УПП СП СЭД)/CALC/alpha_calc.m
Normal file
12
Информация для программиста (УПП СП СЭД)/CALC/alpha_calc.m
Normal 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(α)');
|
||||
Loading…
Reference in New Issue
Block a user