578 lines
22 KiB
C
578 lines
22 KiB
C
/**
|
||
******************************************************************************
|
||
* @file upp_params.c
|
||
* @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 __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 - Уставка на скорость нарастания пускового тока */
|
||
float angle_ref_alphaPUI = PUI_Tnt_CalcAlpha(u2f(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)
|
||
{
|
||
if(upp.call->go) // при запущеном УПП ничего не меняем
|
||
return;
|
||
|
||
// флаги обновились ли конфиги
|
||
static int alpha_update = 0;
|
||
static int adc_channel_update[ADC_NUMB_OF_REGULAR_CHANNELS] = {0};
|
||
static int zc_update = 0;
|
||
static int pwm_update = 0;
|
||
|
||
// временная переменная для параметров Мониторинга сети
|
||
float angle_max = upp.hangle.Config.AngleMax;
|
||
float angle_min = upp.hangle.Config.AngleMin;
|
||
float angle_pid_kp = upp.hangle.pid.Kp;
|
||
float angle_pid_ki = upp.hangle.pid.Ki/((float)PM_SLOW_PERIOD_US/1000000);
|
||
float angle_pid_kd = upp.hangle.pid.Kd;
|
||
// временная переменная для параметров каналов АЦП
|
||
float adc_channel_max[ADC_NUMB_OF_REGULAR_CHANNELS] = {0};
|
||
uint16_t adc_channel_zero[ADC_NUMB_OF_REGULAR_CHANNELS] = {0};
|
||
// временная переменная для параметров перехода через ноль
|
||
float zc_hysteresis = upp.pm.zc.Config.Hysteresis;
|
||
uint16_t zc_debounce = upp.pm.zc.Config.DebounceSamples;
|
||
// временная переменная для параметров ШИМ
|
||
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;
|
||
float pwm_pulse_len = upp.hpwm.Config.PulseLength;
|
||
// временная переменная для параметров Мониторинга сети
|
||
uint16_t pm_rms_widnow_size = upp.pm.rms[0].window_size;
|
||
float pm_rms_exp_alpha = upp.pm.rms_exp[0].alpha;
|
||
|
||
|
||
|
||
// Параметры регулятора Угла открытия
|
||
if(__CheckParamF(&angle_max, PARAM_INTERNAL->angle.Angle_Max, 65535))
|
||
{
|
||
alpha_update = 1;
|
||
}
|
||
if(__CheckParamF(&angle_min, PARAM_INTERNAL->angle.Angle_Min, 65535))
|
||
{
|
||
alpha_update = 1;
|
||
}
|
||
if(__CheckParamF(&angle_pid_kp, PARAM_INTERNAL->angle.PID_Kp, 10000))
|
||
{
|
||
alpha_update = 1;
|
||
}
|
||
if(__CheckParamF(&angle_pid_ki, PARAM_INTERNAL->angle.PID_Ki, 10000))
|
||
{
|
||
alpha_update = 1;
|
||
}
|
||
if(__CheckParamF(&angle_pid_kd, PARAM_INTERNAL->angle.PID_Kd, 10000))
|
||
{
|
||
alpha_update = 1;
|
||
}
|
||
|
||
|
||
// Параметры АЦП
|
||
for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
|
||
{
|
||
adc_channel_max[i] = upp.pm.adc.Coefs[i].vMax;
|
||
adc_channel_zero[i] = upp.pm.adc.Coefs[i].lZero;
|
||
|
||
// Максимальное измеряемое напряжение
|
||
if(__CheckParamF(&adc_channel_max[i], PARAM_INTERNAL->adc.ADC_Max[i], 10))
|
||
{
|
||
adc_channel_update[i] = 1;
|
||
}
|
||
// Значение АЦП при нулевом входе
|
||
if(__CheckParamU16(&adc_channel_zero[i], PARAM_INTERNAL->adc.ADC_Zero[i]))
|
||
{
|
||
adc_channel_update[i] = 1;
|
||
}
|
||
}
|
||
|
||
// Параметры алгоритма перехода через ноль
|
||
if(__CheckParamF(&zc_hysteresis, PARAM_INTERNAL->zc.Hysteresis, 10000))
|
||
{
|
||
zc_update = 1;
|
||
}
|
||
if(__CheckParamU16(&zc_debounce, PARAM_INTERNAL->zc.DebouneCouner))
|
||
{
|
||
zc_update = 1;
|
||
}
|
||
|
||
// Параметры ШИМ
|
||
if(__CheckParamU8(&pwm_phase_mask, PARAM_INTERNAL->pwm.PhaseMask, 1))
|
||
{
|
||
pwm_update = 1;
|
||
}
|
||
if(__CheckParamU16(&pwm_freq, PARAM_INTERNAL->pwm.Frequency))
|
||
{
|
||
pwm_update = 1;
|
||
}
|
||
if(__CheckParamF(&pwm_duty, PARAM_INTERNAL->pwm.Duty, 100))
|
||
{
|
||
pwm_update = 1;
|
||
}
|
||
if(__CheckParamF(&pwm_pulse_len, PARAM_INTERNAL->pwm.PulseLength, 65535))
|
||
{
|
||
pwm_update = 1;
|
||
}
|
||
|
||
// Параметры мониторинга
|
||
if(__CheckParamU16(&pm_rms_widnow_size, PARAM_INTERNAL->pm.rms_window_size))
|
||
{
|
||
for(int i = 0; i < RMS_ALL; i++)
|
||
{
|
||
Filter_ReInit(&upp.pm.rms[i], pm_rms_widnow_size);
|
||
Filter_Start(&upp.pm.rms[i]);
|
||
}
|
||
}
|
||
if(__CheckParamF(&pm_rms_exp_alpha, PARAM_INTERNAL->pm.rms_exp_alpha, 65535))
|
||
{
|
||
for(int i = 0; i < RMS_EXP_ALL; i++)
|
||
{
|
||
Filter_ReInit(&upp.pm.rms_exp[i], pm_rms_exp_alpha);
|
||
Filter_Start(&upp.pm.rms_exp[i]);
|
||
}
|
||
}
|
||
|
||
|
||
// Обновление регулятора угла открытия
|
||
__AngleSetLimit();
|
||
if(alpha_update)
|
||
{
|
||
if(Angle_SetRange(&upp.hangle, angle_min, angle_max) == HAL_OK)
|
||
{
|
||
if(Angle_PID_Init(&upp.hangle, angle_pid_kp,
|
||
angle_pid_ki*((float)PM_SLOW_PERIOD_US/1000000),
|
||
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++)
|
||
{
|
||
if(adc_channel_update[i])
|
||
{
|
||
if(ADC_ConfigChannel(&upp.pm.adc, i, adc_channel_zero[i], adc_channel_max[i], 4095) == HAL_OK)
|
||
adc_channel_update[i] = 0;
|
||
else
|
||
ERR_PRIVATE_CNT->adc_reinit_err++;
|
||
}
|
||
}
|
||
// Обновление Zero-Cross конфигов
|
||
if(zc_update)
|
||
{
|
||
if(ZC_Init(&upp.pm.zc, upp.pm.zc.Config.NumChannels, zc_hysteresis, zc_debounce) == HAL_OK)
|
||
zc_update = 0;
|
||
else
|
||
ERR_PRIVATE_CNT->zc_reinit_err++;
|
||
}
|
||
// Обновление ШИМ конфигов
|
||
if(pwm_update)
|
||
{
|
||
if(PWM_SetConfig(&upp.hpwm, pwm_phase_mask, pwm_freq, pwm_duty, pwm_pulse_len) == HAL_OK)
|
||
{
|
||
pwm_update = 0;
|
||
}
|
||
else
|
||
ERR_PRIVATE_CNT->pwm_reinit_err++;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @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)*((float)PM_SLOW_PERIOD_US/1000000),
|
||
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.PulseLength) != HAL_OK)
|
||
return HAL_ERROR;
|
||
|
||
return HAL_OK;
|
||
}
|
||
|
||
|
||
/**
|
||
* @brief Контроль параметров УПП на корректные значения.
|
||
* @return HAL Status.
|
||
*/
|
||
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, 5000*10);
|
||
SATURATE_U16(PARAM_INTERNAL->adc.ADC_Max[ADC_CHANNEL_UAC], 0, 5000*10);
|
||
SATURATE_U16(PARAM_INTERNAL->adc.ADC_Max[ADC_CHANNEL_IC], 0, 1000*10);
|
||
SATURATE_U16(PARAM_INTERNAL->adc.ADC_Max[ADC_CHANNEL_IA], 0, 1000*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->zc.Hysteresis, 0, 0.1*100);
|
||
SATURATE_U16(PARAM_INTERNAL->zc.DebouneCouner, 0, 1000);
|
||
|
||
|
||
SATURATE_U16(PARAM_INTERNAL->angle.PulseLengthReserve, 50, 1000);
|
||
}
|
||
|
||
/**
|
||
* @brief Установка параметров на дефолтные значения @ref UPP_PARAMS_DEFAULT.
|
||
* @param pui_default Сбросить параметры ПУИ
|
||
* @param internal_default Сбросить внутренние параметры
|
||
* @return HAL Status.
|
||
*/
|
||
void UPP_Params_SetDefault(int pui_default, int internal_default)
|
||
{
|
||
if(pui_default)
|
||
{
|
||
PARAM_PUI->Iref = PUI_Iref_PERCENT_DEFAULT*100;
|
||
PARAM_PUI->Tnt = PUI_Tnt_MS_DEFAULT;
|
||
PARAM_PUI->Umin = PUI_Umin_PERCENT_DEFAULT*100;
|
||
PARAM_PUI->Umax = PUI_Umax_PERCENT_DEFAULT*100;
|
||
PARAM_PUI->Imax = PUI_Imax_PERCENT_DEFAULT*100;
|
||
PARAM_PUI->Imin = PUI_Imin_PERCENT_DEFAULT*100;
|
||
PARAM_PUI->TiMax = PUI_TiMax_US_DEFAULT;
|
||
PARAM_PUI->Tdelay = PUI_Tdelay_SECONDS_DEFAULT;
|
||
PARAM_PUI->Interlace = PUI_Interlace_EN_DEFAULT;
|
||
}
|
||
|
||
if(internal_default)
|
||
{
|
||
PARAM_INTERNAL->setpoints.TemperatureWarn = SETPOINT_TEMP_WARN*10;
|
||
PARAM_INTERNAL->setpoints.TemperatureErr = SETPOINT_TEMP_ERR*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;
|
||
|
||
PARAM_INTERNAL->pm.rms_window_size = PM_RMS_WINDOW_PERIOD_US_DEFAULT/PM_SLOW_PERIOD_US;
|
||
PARAM_INTERNAL->pm.rms_exp_alpha = FilterExp_CalcAlpha98(PM_RMS_EXT_TAU_US_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;
|
||
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;
|
||
|
||
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.PulseLength = PWM_THYR_PULSE_LENGTH_DEFAULT*65535;
|
||
|
||
PARAM_INTERNAL->zc.Hysteresis = ZERO_CROSS_HYSTERESIS_PERCENT_DEFAULT*100;
|
||
PARAM_INTERNAL->zc.DebouneCouner = ZERO_CROSS_DEBOUNCE_CNT_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.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;
|
||
//__AngleSetLimit();
|
||
}
|
||
}
|
||
|
||
|
||
#define ANGLE_PERIOD_MS(_freq_) (((float)1/(_freq_*2))*1000)
|
||
|
||
// Перерасчет максимально допустимого угла
|
||
static void __AngleSetLimit(void)
|
||
{ // Сколько пачка ипульсов занимает процентов от всего периода
|
||
float pulses_percent_of_period = (((float)PARAM_INTERNAL->pwm.PulseLength / PARAM_INTERNAL->pwm.Frequency) * 1000) / ANGLE_PERIOD_MS(upp.pm.measured.final.Fmean);
|
||
// Вычитаем этот процент из 1 - получаем максимально безопасный угол
|
||
float angle_limit = 1;
|
||
angle_limit -= pulses_percent_of_period*u2f(PARAM_INTERNAL->angle.PulseLengthReserve, 100); // добавляем запас в PulseLengthReserve процентов от пачки импульсов
|
||
Angle_SetLimit(&upp.hangle, angle_limit);
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* @brief Сверить и обновить float параметр из uint16_t.
|
||
* @param paramDist Указатель на float параметр
|
||
* @param paramSrc Значение для сравнения с float параметром
|
||
* @param Coef Коэффициент для приведения float к uint16_t: uint16_t = float*coef, float = uint16_t/coef
|
||
* @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
|
||
*/
|
||
static int __CheckParamF(float *paramDist, uint16_t paramSrc, float Coef)
|
||
{
|
||
if(paramDist == NULL)
|
||
return 0;
|
||
|
||
uint16_t expected_mb_param = *paramDist*Coef;
|
||
if(expected_mb_param != paramSrc)
|
||
{
|
||
*paramDist = (float)paramSrc/Coef;
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
/**
|
||
* @brief Сверить и обновить uint32_t параметр из uint16_t.
|
||
* @param paramDist Указатель на uint32_t параметр
|
||
* @param paramSrc Значение для сравнения с uint32_t параметром
|
||
* @param Coef Коэффициент для приведения uint32_t к uint16_t: uint16_t = uint32_t*coef, uint32_t = uint16_t/coef
|
||
* @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
|
||
*/
|
||
static int __CheckParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef)
|
||
{
|
||
if(paramDist == NULL)
|
||
return 0;
|
||
|
||
uint16_t expected_mb_param = *paramDist*Coef;
|
||
if(expected_mb_param != paramSrc)
|
||
{
|
||
*paramDist = (uint32_t)paramSrc/Coef;
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
/**
|
||
* @brief Сверить и обновить uint16_t параметр из uint16_t.
|
||
* @param paramDist Указатель на uint16_t параметр
|
||
* @param paramSrc Значение для сравнения с uint16_t параметром
|
||
* @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
|
||
*/
|
||
static int __CheckParamU16(uint16_t *paramDist, uint16_t paramSrc)
|
||
{
|
||
if(paramDist == NULL)
|
||
return 0;
|
||
|
||
uint16_t expected_mb_param = *paramDist;
|
||
if(expected_mb_param != paramSrc)
|
||
{
|
||
*paramDist = (uint16_t)paramSrc;
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @brief Сверить и обновить uint8_t параметр из uint16_t.
|
||
* @param paramDist Указатель на uint8_t параметр
|
||
* @param paramSrc Значение для сравнения с uint32_t параметром
|
||
* @param Coef Коэффициент для приведения uint32_t к uint16_t: uint16_t = uint8_t*coef, uint8_t = uint16_t/coef
|
||
* @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc.
|
||
*/
|
||
static int __CheckParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef)
|
||
{
|
||
if(paramDist == NULL)
|
||
return 0;
|
||
|
||
uint16_t expected_mb_param = *paramDist*Coef;
|
||
if(expected_mb_param != paramSrc)
|
||
{
|
||
*paramDist = (uint8_t)paramSrc/Coef;
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
return 0;
|
||
}
|
||
} |