Рефакторинг и фиксы
Вроде сделал управление для трехфазной сети без нулевого провода. В матлабе запускается, но токи странные и регулятор не доделан нормально
This commit is contained in:
parent
aa59f84fb7
commit
2703f7efda
@ -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
|
||||
|
||||
@ -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.
@ -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
|
||||
* @}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 процентов от пачки импульсов
|
||||
|
||||
@ -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;
|
||||
|
||||
/* Параметры Угла */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user