diff --git a/MATLAB/app_wrapper/app_io.c b/MATLAB/app_wrapper/app_io.c index 4766238..3f2a22a 100644 --- a/MATLAB/app_wrapper/app_io.c +++ b/MATLAB/app_wrapper/app_io.c @@ -6,6 +6,7 @@ #include "mcu_wrapper_conf.h" #include "app_wrapper.h" +float dbg_err_limit = 0; float dbg[16]; #define PIN_READ(_verbname_) (_verbname_##_GPIO_Port->ODR & (_verbname_##_Pin)) ? 1 : 0 @@ -50,7 +51,7 @@ void Write_UPP_Outputs(real_T* Buffer, int ind_port) //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); + int ready = upp.errors->common; if (CEN_GPIO_Port->ODR & CEN_Pin) { @@ -165,6 +166,7 @@ void app_readInputs(const real_T* Buffer) { MB_DATA.HoldRegs.pui_params.Tdelay = ReadInputArray(1, 8); MB_DATA.HoldRegs.pui_params.Interlace = ReadInputArray(1, 9); + MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UAC] = ReadInputArray(2, 0) * 10; MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_UBA] = ReadInputArray(2, 0) * 10; MB_INTERNAL.param.adc.ADC_Max[ADC_CHANNEL_IA] = ReadInputArray(2, 1) * 10; @@ -175,8 +177,11 @@ void app_readInputs(const real_T* Buffer) { MB_INTERNAL.param.angle.PID_Kp = ReadInputArray(2, 4) * 10000; MB_INTERNAL.param.angle.PID_Ki = ReadInputArray(2, 5) * 10000; - MB_INTERNAL.param.angle.PID_Kd = ReadInputArray(2, 6) * 10000; - MB_INTERNAL.param.angle.PulseLengthReserve = ReadInputArray(2, 7); + /*MB_INTERNAL.param.angle.PID_Kd*/dbg_err_limit = ReadInputArray(2, 6); + + MB_INTERNAL.param.angle.Angle_Max = ReadInputArray(2, 7)/180 * 65535; + MB_INTERNAL.param.angle.Angle_Min = ReadInputArray(2, 8)/180 * 65535; + MB_INTERNAL.param.pwm.PulseLength = ReadInputArray(2, 9)/180 * 65535; } // USER APP INPUT END diff --git a/MATLAB/upp_init.m b/MATLAB/upp_init.m index ad6a586..6cd838e 100644 --- a/MATLAB/upp_init.m +++ b/MATLAB/upp_init.m @@ -1,11 +1,11 @@ clear all -IadcMax = 50; +IadcMax = 200; VadcMax = 1216; Ts = 5e-6; Vnom = 400; -Inom = 15; +Inom = 25; Fnom = 50; Temperature1 = 2.22; % 20 градусов diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx index ca02fd4..5a4f314 100644 Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h index 6c8f97d..1faf50e 100644 --- a/UPP/Core/Configs/upp_config.h +++ b/UPP/Core/Configs/upp_config.h @@ -23,7 +23,7 @@ */ #define UPP_DISABLE_ERROR_BLOCK ///< Отключить блокировку УПП при ошибках -#define UPP_SIMULATE_I ///< Симулировт токи (Iref/2) а не брать с АЦП +//#define UPP_SIMULATE_I ///< Симулировт токи (Iref/2) а не брать с АЦП #define UPP_DISABLE_PROTECT_BOARDPOWER ///< Отключить проверки питания плат (+24, +5 В) #define UPP_DISABLE_PROTECT_LOSS_PHASE ///< Отключить проверки на потерянные фазы @@ -41,12 +41,13 @@ * @{ */ - /* Периоды обновления всякого */ -#define PM_ADC_PERIOD_US 25 ///< Период опроса АЦП в мкс -#define PM_SLOW_PERIOD_US 500 ///< Период обновления медленных расчетов в мкс (чтобы делилось на @ref PM_ADC_PERIOD_US) +/* Периоды обновления всякого */ +#define PM_FAST_PERIOD_US 25 ///< Период обновления быстрых расчетов в мкс (АЦП, пересечение нуля, ШИМ) +#define PM_SLOW_PERIOD_US 500 ///< Период обновления медленных расчетов в мкс (сглаженные и действующие значения, ПИД угла, ошибки) #define PM_TEMP_SLOW_PERIOD_MS 1000 ///< Период обновлениия (фильтрации) датчиков температуры в мс #define PM_F_SLOW_PERIOD_MS 40 ///< Период обновления (фильтрации) частоты в мс #define UPP_INIT_BEFORE_READY_MS 2000 ///< Сколько сканировать сеть, перед выставлением состояния готовности +#define UPP_HALFWAVE_PERIOD 10 ///< Период полуволны. От него будет рассчитываться углы от 0 до 180 градусов /* Частоты таймеров в МГц*/ #define PWM_TIM1_FREQ_MHZ 180 ///< Частота тактирования таймера ШИМ (1-4 каналы) @@ -126,7 +127,7 @@ /* Параметры ШИМ для тиристоров */ #define PWM_THYR_FREQUENCY_HZ_DEFAULT 16000 #define PWM_THYR_DUTY_PERCENT_DEFAULT 0.5 -#define PWM_THYR_PULSE_NUMBER_DEFAULT 10 +#define PWM_THYR_PULSE_LENGTH_DEFAULT (60.0/180.0) /** //UPP_PARAMS_DEFAULT * @} diff --git a/UPP/Core/Configs/upp_defs.h b/UPP/Core/Configs/upp_defs.h index 4f194aa..a256971 100644 --- a/UPP/Core/Configs/upp_defs.h +++ b/UPP/Core/Configs/upp_defs.h @@ -170,11 +170,11 @@ typedef struct { #define TEMP_2 1 /* Перерасчеты в тики */ -#define PM_SLOW_PERIOD_CNT (PM_SLOW_PERIOD_US/PM_ADC_PERIOD_US) ///< Период обновления медленных расчетов тиках @ref PM_ADC_PERIOD_US +#define PM_SLOW_PERIOD_CNT (PM_SLOW_PERIOD_US/PM_FAST_PERIOD_US) ///< Период обновления медленных расчетов тиках @ref PM_FAST_PERIOD_US +#define US_TO_FAST_TICKS(_us_) ((_us_)/PM_FAST_PERIOD_US) ///< Пересчитать мкс в тики быстрых расчетов +#define MS_TO_FAST_TICKS(_ms_) US_TO_FAST_TICKS((_ms_)*1000) ///< Пересчитать мс в тики быстрых расчетов #define US_TO_SLOW_TICKS(_us_) ((_us_)/PM_SLOW_PERIOD_US) ///< Пересчитать мкс в тики медленных расчетов #define MS_TO_SLOW_TICKS(_ms_) US_TO_SLOW_TICKS((_ms_)*1000) ///< Пересчитать мс в тики медленных расчетов - -/* Перерасчеты в тики */ #define PM_F_SLOW_PERIOD_CNT (MS_TO_SLOW_TICKS(PM_F_SLOW_PERIOD_MS)) ///< Период обновления частоты в тиках @ref PM_SLOW_PERIOD_CNT #define SQRT2 1.4142135 @@ -201,8 +201,8 @@ typedef enum { */ typedef enum { UPP_PHASE_A = 0, - UPP_PHASE_B = 1, - UPP_PHASE_C = 2, + UPP_PHASE_C = 1, + UPP_PHASE_B = 2, UPP_PHASE_UNKNOWN = 3 } UPP_Phase_t; diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c index 469d02b..e81d8ec 100644 --- a/UPP/Core/PowerMonitor/power_monitor.c +++ b/UPP/Core/PowerMonitor/power_monitor.c @@ -75,14 +75,14 @@ HAL_StatusTypeDef PowerMonitor_Init(PowerMonitor_t *hpm) /** * @brief Запустить мониторинг сети. * @param hpm Указатель на структуру мониторинга сети - * @details Запускает АЦП с периодом @ref PM_ADC_PERIOD_US + * @details Запускает АЦП с периодом @ref PM_FAST_PERIOD_US */ HAL_StatusTypeDef PowerMonitor_Start(PowerMonitor_t *hpm) { if(hpm == NULL) return HAL_ERROR; - if(ADC_Start(&hpm->adc, PM_ADC_PERIOD_US) != HAL_OK) + if(ADC_Start(&hpm->adc, PM_FAST_PERIOD_US) != HAL_OK) return HAL_ERROR; return HAL_OK; @@ -160,7 +160,7 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm) /* Расчет амплитуд трехфазной сети */ float uamp = vector_abs_linear_calc(meas->slow.U[U_AB], meas->slow.U[U_CA])/SQRT2; /* SQRT2 - получить действующее */ - float iamp = vector_abs_phase_calc(meas->slow.I[I_A], meas->slow.I[I_C])/SQRT2; /* SQRT2 - получить действующее */ + float iamp = vector_abs_phase_calc(meas->slow.I[I_A], meas->slow.I[I_C]); meas->final.Uamp = Filter_Process(&hpm->rms_exp[RMS_EXP_U], uamp); meas->final.Iamp = Filter_Process(&hpm->rms_exp[RMS_EXP_I], iamp); diff --git a/UPP/Core/Src/stm32f4xx_it.c b/UPP/Core/Src/stm32f4xx_it.c index 368ee07..5f49f7b 100644 --- a/UPP/Core/Src/stm32f4xx_it.c +++ b/UPP/Core/Src/stm32f4xx_it.c @@ -214,7 +214,7 @@ void TIM1_UP_TIM10_IRQHandler(void) /* USER CODE END TIM1_UP_TIM10_IRQn 0 */ HAL_TIM_IRQHandler(&htim1); /* USER CODE BEGIN TIM1_UP_TIM10_IRQn 1 */ - UPP_PWM_Handle(); + //UPP_PWM_Handle(); /* USER CODE END TIM1_UP_TIM10_IRQn 1 */ } @@ -242,7 +242,7 @@ void TIM8_UP_TIM13_IRQHandler(void) /* USER CODE END TIM8_UP_TIM13_IRQn 0 */ HAL_TIM_IRQHandler(&htim8); /* USER CODE BEGIN TIM8_UP_TIM13_IRQn 1 */ - UPP_PWM_Handle(); + //UPP_PWM_Handle(); /* USER CODE END TIM8_UP_TIM13_IRQn 1 */ } @@ -252,9 +252,6 @@ void TIM8_UP_TIM13_IRQHandler(void) void TIM8_TRG_COM_TIM14_IRQHandler(void) { /* USER CODE BEGIN TIM8_TRG_COM_TIM14_IRQn 0 */ - if (__HAL_TIM_GET_FLAG(&htim8, TIM_FLAG_UPDATE) != RESET) { - UPP_PWM_Handle(); - } #ifndef MATLAB // в матлабе нет htim14, т.к. это систем тики /* USER CODE END TIM8_TRG_COM_TIM14_IRQn 0 */ diff --git a/UPP/Core/UPP/angle_control.c b/UPP/Core/UPP/angle_control.c index 2cc38b9..d9b1427 100644 --- a/UPP/Core/UPP/angle_control.c +++ b/UPP/Core/UPP/angle_control.c @@ -75,23 +75,43 @@ void Angle_PID(Angle_Handle_t *hangle, float setpoint, float measurement) if(assert_upp(hangle)) return; + /* Плавное нарастание уставки */ hangle->Iref = Filter_Process(&hangle->refFilter, setpoint); hangle->Imeas = measurement; /* Ошибка регулирования = уставка - измеренное */ float err = hangle->Iref - hangle->Imeas; + /* Ограничение скорости изменения */ + extern float dbg_err_limit; + if(err > dbg_err_limit) + { + err = dbg_err_limit; + } + else if (err < -dbg_err_limit) + { + err = -dbg_err_limit; + } /* ПИД регулирование */ float open_level = arm_pid_f32(&hangle->pid, err); // 0 - открыть максимально поздно, 1 - открыть макситмально рано + + /* Ограничиваем диапазон */ - if (open_level > 1) open_level = 1; - if(open_level < 0) open_level = 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; // угол открытия тиристора в о.е. от максимально заданного + float alpha = alpha_rad/PI*hangle->Config.AngleMax; // угол открытия тиристора в о.е. от максимально заданного /* Выставляем заданный уровень открытия */ Angle_SetAlpha(hangle, alpha); diff --git a/UPP/Core/UPP/pwm_thyristors.c b/UPP/Core/UPP/pwm_thyristors.c index 6855655..e7b0415 100644 --- a/UPP/Core/UPP/pwm_thyristors.c +++ b/UPP/Core/UPP/pwm_thyristors.c @@ -67,10 +67,8 @@ HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm) HAL_TIM_PWM_Start(&hpwm2, PWM_CHANNEL_6); PWM_Stop(hpwm, 0, 1); -#ifndef PWM_HARDWARE_IMPULSES_CONTROL __PWM_ReConfigToSoftwarePulses(); - HAL_TIM_Base_Start_IT(&hpwm1); -#endif + HAL_TIM_Base_Start(&hpwm1); return HAL_OK; } @@ -85,9 +83,6 @@ HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase) { if(assert_upp_phase(hpwm, Phase)) return HAL_ERROR; - // Если уже какой-то канал запущен - не запускаем - if(hpwm->f.Running) - return HAL_BUSY; if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN]) return HAL_ERROR; @@ -105,22 +100,8 @@ HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase) // Запуск только если таймер в режиме ожидания case PWM_THYR_TIM_WAIT: -#ifndef PWM_HARDWARE_IMPULSES_CONTROL hpwm->Phase[Phase]->State = PWM_THYR_TIM_START; return HAL_OK; -#else - hpwm->Phase[Phase]->State = PWM_THYR_TIM_ACTIVE; - - if(hpwm->Config.PulseNumber) - hpwm->Phase[Phase]->htim->Instance->RCR = hpwm->Config.PulseNumber-1; - else - return HAL_ERROR; - - __PWM_SetOutputState(hpwm->Phase[Phase], PWM_ENABLE); - - hpwm->f.Running++; - return HAL_TIM_Base_Start_IT(hpwm->Phase[Phase]->htim); -#endif default: return HAL_ERROR; @@ -159,24 +140,44 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_ } // Если НЕ force_stop_all - сбрасываем ТОЛЬКО заданный канал else - { - if (hpwm->Phase[Phase] == NULL || hpwm->Phase[Phase] == &hpwm->AllPhases[PHASE_UNKNOWN]) - return HAL_ERROR; - + { // Если не force_stop_all - сбрасываем только текущий канал __PWM_SetOutputState(hpwm->Phase[Phase], PWM_DISABLE); - if(hpwm->Phase[Phase]->State != PWM_THYR_DISABLED) - { - hpwm->Phase[Phase]->State = PWM_THYR_DISABLED; -#ifdef PWM_HARDWARE_IMPULSES_CONTROL - if(hpwm->f.Running) - hpwm->f.Running--; - HAL_TIM_Base_Stop(hpwm->Phase[Phase]->htim); -#endif - } return HAL_OK; } } +/** + * @brief Установка полуволны для слежения. + * @param hpwm Указатель на хендл ШИМ тиристоров + * @param Phase Для какой фазы надо установить полуволну + * @param halfwave Какую полуволну установить + * @return HAL Status. + * @details Меняет указатель канала фазы на канал соответствующей полуволны + */ +HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave) +{ + if(assert_upp_phase(hpwm, Phase)) + return HAL_ERROR; + + // Выставляем текущий активную полуволну + switch(halfwave) + { + case UPP_WAVE_POSITIVE: + hpwm->Phase[Phase] = &hpwm->AllPhases[Phase]; + hpwm->Phase[Phase]->State = PWM_THYR_TIM_WAIT; + return HAL_OK; + + case UPP_WAVE_NEGATIVE: + hpwm->Phase[Phase] = &hpwm->AllPhases[Phase+3]; + hpwm->Phase[Phase]->State = PWM_THYR_TIM_WAIT; + return HAL_OK; + + default: + hpwm->Phase[Phase] = &hpwm->AllPhases[PHASE_UNKNOWN]; + return HAL_ERROR; + } +} + /** * @brief Установка параметров ШИМ. @@ -184,7 +185,7 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_ * @param Frequency Частота в ГЦ * @return HAL Status. */ -HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, uint8_t PulseNumber) +HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, float PulseLength) { if(assert_upp(hpwm)) return HAL_ERROR; @@ -192,10 +193,10 @@ HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t return HAL_BUSY; // Остановка таймера - HAL_TIM_Base_Stop_IT(&hpwm1); + HAL_TIM_Base_Stop(&hpwm1); hpwm->Config.PhaseMask.all = PhaseMask; - hpwm->Config.PulseNumber = PulseNumber; + hpwm->Config.PulseLength = PulseLength; hpwm->Config.Frequency = Frequency; hpwm->Config.Duty = Duty; // Высставление периодов @@ -218,49 +219,10 @@ HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t PWM_Stop(hpwm, 0, 1); -#ifndef PWM_HARDWARE_IMPULSES_CONTROL - return HAL_TIM_Base_Start_IT(&hpwm1); -#else - return HAL_OK; -#endif + return HAL_TIM_Base_Start(&hpwm1); } -/** - * @brief Установка полуволны для слежения. - * @param hpwm Указатель на хендл ШИМ тиристоров - * @param Phase Для какой фазы надо установить полуволну - * @param halfwave Какую полуволну установить - * @return HAL Status. - * @details Меняет указатель канала фазы на канал соответствующей полуволны - */ -HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave) -{ - if(assert_upp_phase(hpwm, Phase)) - return HAL_ERROR; - - // Сбрасываем текущий канал - PWM_Stop(hpwm, Phase, 0); - - // Выставляем канал - switch(halfwave) - { - case UPP_WAVE_POSITIVE: - hpwm->Phase[Phase] = &hpwm->AllPhases[Phase]; - hpwm->Phase[Phase]->State = PWM_THYR_TIM_WAIT; - return HAL_OK; - - case UPP_WAVE_NEGATIVE: - hpwm->Phase[Phase] = &hpwm->AllPhases[Phase+3]; - hpwm->Phase[Phase]->State = PWM_THYR_TIM_WAIT; - return HAL_OK; - - default: - hpwm->Phase[Phase] = &hpwm->AllPhases[PHASE_UNKNOWN]; - return HAL_ERROR; - } -} - /** * @brief Установка полярности шим. * @param hpwm Указатель на хендл ШИМ тиристоров @@ -291,7 +253,7 @@ HAL_StatusTypeDef PWM_SetPolarity(PWM_Handle_t *hpwm, int polarity) * @return HAL Status. * @details Автомат состояний, который определяет поведение каналов ШИМ */ -HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm) +HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm, float PeriodMs) { if(assert_upp(hpwm)) return HAL_ERROR; @@ -305,7 +267,6 @@ HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm) if (hPhase->htim == NULL) continue; -#ifndef PWM_HARDWARE_IMPULSES_CONTROL switch (hPhase->State) { case PWM_THYR_DISABLED: // канал отключен @@ -318,7 +279,7 @@ HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm) case PWM_THYR_TIM_START: // начать ШИМ (пачка импульсов) __PWM_SetOutputState(hPhase, PWM_ENABLE); - hPhase->PulseCnt = hpwm->Config.PulseNumber - 1; // 1 импульс уже прошел + hPhase->PulseCnt = MS_TO_FAST_TICKS(PeriodMs*hpwm->Config.PulseLength) - 1; // 1 импульс уже прошел hPhase->State = PWM_THYR_TIM_ACTIVE; hpwm->f.Running++; break; @@ -342,17 +303,6 @@ HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm) __PWM_SetOutputState(hPhase, PWM_DISABLE); break; } -#else //PWM_HARDWARE_IMPULSES_CONTROL - // после того как пачка импульсов прошла отключаем активный канал - if (hPhase->State == PWM_THYR_TIM_ACTIVE) - { - hPhase->State = PWM_THYR_TIM_WAIT; - if(hpwm->f.Running) - hpwm->f.Running--; - __PWM_SetOutputState(hPhase, PWM_DISABLE); - HAL_TIM_Base_Stop(hPhase->htim); - } -#endif } return HAL_OK; } diff --git a/UPP/Core/UPP/pwm_thyristors.h b/UPP/Core/UPP/pwm_thyristors.h index 8a1ff6c..96a7366 100644 --- a/UPP/Core/UPP/pwm_thyristors.h +++ b/UPP/Core/UPP/pwm_thyristors.h @@ -33,6 +33,8 @@ #define PHASE_UNKNOWN 6 +#define PWM_PulseLengthToCnt(_length_, _period_) ((_length_)*(_period_)/ + /** * @brief Состояния канала */ @@ -72,7 +74,7 @@ typedef struct { uint8_t phC:1; }; }PhaseMask; ///< Какими каналами управлять - uint8_t PulseNumber; ///< Сколько импульсов отправить в пакете для открытия тиристоров + float PulseLength; ///< Длина импульса в о.е. от 180 градусов uint16_t Frequency; ///< Частота импульсов float Duty; ///< Скважность импульсов } PWM_ThyrConfig_t; @@ -80,9 +82,9 @@ typedef struct { /** * @brief Хендл управляюзщий тиристорами */ typedef struct { - PWM_ThyrConfig_t Config; - PWM_Channel_t *Phase[3]; ///< Текущие каналы для фаз - PWM_Channel_t AllPhases[7]; ///< Все каналы для фаз (+1 для деинициализированного канала) + PWM_ThyrConfig_t Config; ///< Конфигурации ШИМ + PWM_Channel_t *Phase[3]; ///< Каналы для активной в данный момент фазы + PWM_Channel_t AllPhases[7]; ///< Все каналы для фаз (+1 для деинициализированного канала) struct { unsigned Initialized : 1; @@ -101,12 +103,12 @@ HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase); /* Остановить ШИМ. */ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop_all); /* Установка частоты ШИМ. */ -HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, uint8_t PulseNumber); +HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, float PulseLength); /* Установка полуволны для слежения. */ HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave); /* Установка полярности шим. */ HAL_StatusTypeDef PWM_SetPolarity(PWM_Handle_t *hpwm, int polarity); // ====== СЕРВИС ========== /* Хендл ШИМ тиристоров. */ -HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm); +HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm, float PeriodMs); #endif /* _PWM_THYRISTORS_H */ diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c index 07bff1d..b3ab9a8 100644 --- a/UPP/Core/UPP/upp_main.c +++ b/UPP/Core/UPP/upp_main.c @@ -94,14 +94,16 @@ int UPP_While(void) // Медленные расчеты PowerMonitor_SlowCalc(&upp.pm); + int razgon_done = (fabsf(upp.hangle.Iref - u2f(PARAM_PUI.Iref, 100)) < 0.1); + #ifdef UPP_SIMULATE_I // симулируем токи upp.pm.measured.final.Iamp = upp.hangle.Iref/2; - // Защиты // При симуляции тока не включаем его проверку - PowerMonitor_Protect(&upp.pm, 0); -#else - // Защиты // Определенные защиты по току включаем только в после разгона - PowerMonitor_Protect(&upp.pm, (fabsf(upp.hangle.Iref - u2f(PARAM_PUI.Iref, 100)) < 0.1)); + // При симуляции тока не включаем его проверку + razgon_done = 0; #endif + + // Защиты // Определенные защиты по току включаем только после разгона + PowerMonitor_Protect(&upp.pm, razgon_done); // Обрабока ошибок и выставление итоговой Ошибки UPP_Errors_Handle(); // Контроль парамеров @@ -282,27 +284,19 @@ void UPP_ADC_Handle(void) UPP_HalfWave_t curr_halfwave = ZC_GetHalfWave(&upp.pm.zc, phase); res = PWM_SetHalfWave(&upp.hpwm, phase, curr_halfwave); // Начинаем отсчитывать угол - res = Angle_Start(&upp.hangle, phase, 10); + res = Angle_Start(&upp.hangle, phase, UPP_HALFWAVE_PERIOD); if(res != HAL_OK) __NOP(); } } } - // Проверяем на ошибки + // ШИМим ключи + res = PWM_Handle(&upp.hpwm, UPP_HALFWAVE_PERIOD); upp.Timings.isr_adc_us = BenchTime_End(BT_ADC, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ; upp.pm.f.inIsr = 0; } -/** - * @brief @ref TIM1_UP_TIM10_IRQHandler @ref - */ -void UPP_PWM_Handle(void) -{ - BenchTime_Start(BT_PWM, angletim.Instance->CNT, HAL_MAX_DELAY); - res = PWM_Handle(&upp.hpwm); - upp.Timings.isr_pwm_us = BenchTime_End(BT_PWM, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ; -} /** * @brief @ref HAL_TIM_OC_DelayElapsedCallback diff --git a/UPP/Core/UPP/upp_params.c b/UPP/Core/UPP/upp_params.c index be86437..677b8c2 100644 --- a/UPP/Core/UPP/upp_params.c +++ b/UPP/Core/UPP/upp_params.c @@ -125,7 +125,7 @@ void UPP_Params_ControlInternal(void) uint8_t pwm_phase_mask = upp.hpwm.Config.PhaseMask.all; uint16_t pwm_freq = upp.hpwm.Config.Frequency; float pwm_duty = upp.hpwm.Config.Duty; - uint8_t pwm_pulse_num = upp.hpwm.Config.PulseNumber; + float 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; @@ -183,7 +183,7 @@ void UPP_Params_ControlInternal(void) zc_update = 1; } - // Параметры ШИМ токов + // Параметры ШИМ if(__CheckParamU8(&pwm_phase_mask, PARAM_INTERNAL.pwm.PhaseMask, 1)) { pwm_update = 1; @@ -196,7 +196,7 @@ void UPP_Params_ControlInternal(void) { pwm_update = 1; } - if(__CheckParamU8(&pwm_pulse_num, PARAM_INTERNAL.pwm.PulseNumber, 1)) + if(__CheckParamF(&pwm_pulse_len, PARAM_INTERNAL.pwm.PulseLength, 65535)) { pwm_update = 1; } @@ -258,7 +258,7 @@ void UPP_Params_ControlInternal(void) // Обновление ШИМ конфигов if(pwm_update) { - if(PWM_SetConfig(&upp.hpwm, pwm_phase_mask, pwm_freq, pwm_duty, pwm_pulse_num) == HAL_OK) + if(PWM_SetConfig(&upp.hpwm, pwm_phase_mask, pwm_freq, pwm_duty, pwm_pulse_len) == HAL_OK) { pwm_update = 0; } @@ -346,7 +346,7 @@ HAL_StatusTypeDef UPP_Params_Init(void) 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) + PARAM_INTERNAL.pwm.PulseLength) != HAL_OK) return HAL_ERROR; return HAL_OK; @@ -392,7 +392,6 @@ void UPP_Params_Saturate(void) SATURATE_U16(PARAM_INTERNAL.pwm.PhaseMask, 0, 7); SATURATE_U16(PARAM_INTERNAL.pwm.Frequency, 1000, 40000); - SATURATE_U16(PARAM_INTERNAL.pwm.PulseNumber, 1, 50); SATURATE_U16(PARAM_INTERNAL.zc.Hysteresis, 0, 0.1*100); SATURATE_U16(PARAM_INTERNAL.zc.DebouneCouner, 0, 1000); @@ -451,7 +450,7 @@ void UPP_Params_SetDefault(int pui_default, int internal_default) PARAM_INTERNAL.pwm.PhaseMask = 7; // (все три фазы) PARAM_INTERNAL.pwm.Frequency = PWM_THYR_FREQUENCY_HZ_DEFAULT; PARAM_INTERNAL.pwm.Duty = PWM_THYR_DUTY_PERCENT_DEFAULT*100; - PARAM_INTERNAL.pwm.PulseNumber = PWM_THYR_PULSE_NUMBER_DEFAULT; + PARAM_INTERNAL.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; @@ -473,7 +472,7 @@ void UPP_Params_SetDefault(int pui_default, int internal_default) // Перерасчет максимально допустимого угла static void __AngleSetLimit(void) { // Сколько пачка ипульсов занимает процентов от всего периода - float pulses_percent_of_period = (((float)PARAM_INTERNAL.pwm.PulseNumber / PARAM_INTERNAL.pwm.Frequency) * 1000) / ANGLE_PERIOD_MS(upp.pm.measured.final.Fmean); + 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 процентов от пачки импульсов diff --git a/UPP/Core/UPP/upp_params.h b/UPP/Core/UPP/upp_params.h index 4a8753e..05e4762 100644 --- a/UPP/Core/UPP/upp_params.h +++ b/UPP/Core/UPP/upp_params.h @@ -69,7 +69,7 @@ typedef struct uint16_t PhaseMask; ///< Битовяя маска на какие фазы подавать ШИМ: 0 бит - a, 1 бит - b, 2 бит - c uint16_t Frequency; ///< Частота ШИМ для пачки импульсов на тиристоры [Герцы] uint16_t Duty; ///< Скважность ШИМ для пачки импульсов на тиристоры [Проценты] - uint16_t PulseNumber; ///< Количесво импульсов в пачке [Количество] + uint16_t PulseLength; ///< Количесво импульсов в пачке [Количество] }pwm; /* Параметры Угла */