Рефакторинг и фиксы

Вроде сделал управление для трехфазной сети без нулевого провода. В матлабе запускается, но токи странные и регулятор не доделан нормально
This commit is contained in:
Razvalyaev 2025-12-05 18:36:38 +03:00
parent aa59f84fb7
commit 2703f7efda
13 changed files with 115 additions and 147 deletions

View File

@ -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

View File

@ -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 градусов

Binary file not shown.

View File

@ -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 ///< Отключить проверки на потерянные фазы
@ -42,11 +42,12 @@
*/
/* Периоды обновления всякого */
#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
* @}

View File

@ -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;

View File

@ -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);

View File

@ -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 */

View File

@ -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);

View File

@ -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;
@ -160,23 +141,43 @@ 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;
}

View File

@ -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,8 +82,8 @@ typedef struct {
/**
* @brief Хендл управляюзщий тиристорами */
typedef struct {
PWM_ThyrConfig_t Config;
PWM_Channel_t *Phase[3]; ///< Текущие каналы для фаз
PWM_ThyrConfig_t Config; ///< Конфигурации ШИМ
PWM_Channel_t *Phase[3]; ///< Каналы для активной в данный момент фазы
PWM_Channel_t AllPhases[7]; ///< Все каналы для фаз (+1 для деинициализированного канала)
struct {
@ -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 */

View File

@ -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

View File

@ -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 процентов от пачки импульсов

View File

@ -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;
/* Параметры Угла */