diff --git a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_dma.c b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_dma.c index 7a85299..f6bb6fd 100644 --- a/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_dma.c +++ b/MATLAB/MCU_STM32_Matlab/Drivers/STM32_SIMULINK/stm32_matlab_dma.c @@ -95,16 +95,76 @@ void DMA_Sim_Transfer(DMA_TypeDef* DMAx, uint32_t stream) stream_sim->current_index++; - // Проверяем завершение передачи + // Определяем какой регистр использовать (LISR или HISR) в зависимости от потока + volatile uint32_t* lisr_reg = NULL; + volatile uint32_t* hisr_reg = NULL; + uint32_t tcif_mask = 0; + uint32_t htif_mask = 0; + + // Настраиваем маски флагов в зависимости от потока + if (DMAx == DMA1) { + lisr_reg = &DMA1->LISR; + hisr_reg = &DMA1->HISR; + } +#ifdef DMA2 + else if (DMAx == DMA2) { + lisr_reg = &DMA2->LISR; + hisr_reg = &DMA2->HISR; + } +#endif + + // Устанавливаем маски для конкретного потока + switch (stream) { + case 0: + case 4: + tcif_mask = DMA_FLAG_TCIF0_4; htif_mask = DMA_FLAG_HTIF0_4; break; + case 1: + case 5: + tcif_mask = DMA_FLAG_TCIF1_5; htif_mask = DMA_FLAG_HTIF1_5; break; + case 2: + case 6: + tcif_mask = DMA_FLAG_TCIF2_6; htif_mask = DMA_FLAG_HTIF2_6; break; + case 3: + case 7: + tcif_mask = DMA_FLAG_TCIF3_7; htif_mask = DMA_FLAG_HTIF3_7; break; + }; + + // Проверяем и выставляем флаги + if (stream_sim->current_index == stream_sim->buffer_size / 2) { + // Половинное заполнение - выставляем флаг HTIF + if (stream < 4) { + *lisr_reg |= htif_mask; // Потоки 0-3 в LISR + } + else { + *hisr_reg |= htif_mask; // Потоки 4-7 в HISR + } + + // Вызываем обработчик прерывания + //DMA_Call_IRQHandller(DMAx, stream); //todo + } + if (stream_sim->current_index >= stream_sim->buffer_size) { + // Полное заполнение - выставляем флаг TCIF + if (stream < 4) { + *lisr_reg |= tcif_mask; // Потоки 0-3 в LISR + } + else { + *hisr_reg |= tcif_mask; // Потоки 4-7 в HISR + } + stream_sim->transfer_complete = 1; + if (stream_sim->circular_mode) { stream_sim->current_index = 0; - } else { + // В циклическом режиме не сбрасываем флаги - они должны быть сброшены программно + } + else { stream_sim->transfer_enabled = 0; stream_sim->enabled = 0; - DMA_Call_IRQHandller(DMAx, stream); } + + // Вызываем обработчик прерывания + DMA_Call_IRQHandller(DMAx, stream); } } diff --git a/MATLAB/app_wrapper/app_io.c b/MATLAB/app_wrapper/app_io.c index fa2bff6..8a51993 100644 --- a/MATLAB/app_wrapper/app_io.c +++ b/MATLAB/app_wrapper/app_io.c @@ -84,6 +84,12 @@ void Write_PowerMonitor(real_T* Buffer, int ind_port) WriteOutputArray(upp.pm.measured.final.I[2], ind_port, nn++); WriteOutputArray(upp.pm.measured.final.Fmean, ind_port, nn++); } + + { //20-21 + WriteOutputArray(upp.pm.isr_cnt, ind_port, nn++); + WriteOutputArray(upp.pm.slow_cnt, ind_port, nn++); + } + } @@ -123,7 +129,7 @@ void app_readInputs(const real_T* Buffer) { MB_INTERNAL.param.angle.PID_Kp = ReadInputArray(1, 4) * 10000; MB_INTERNAL.param.angle.PID_Ki = ReadInputArray(1, 5) * 10000; MB_INTERNAL.param.angle.PID_Kd = ReadInputArray(1, 6) * 10000; - MB_INTERNAL.param.angle.PID_ExpAlpha = ReadInputArray(1, 7) * 65535; + MB_DATA.HoldRegs.pui_params.Tnt = ReadInputArray(1, 7) * 1000; MB_INTERNAL.param.nominal.U = ReadInputArray(1, 8) * 10; MB_INTERNAL.param.nominal.I = ReadInputArray(1, 9) * 10; diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx index 3864d75..1e5c793 100644 Binary files a/MATLAB/upp_r2023.slx and b/MATLAB/upp_r2023.slx differ diff --git a/UPP/AllLibs/MyLibs b/UPP/AllLibs/MyLibs index 513f56f..30fdbc3 160000 --- a/UPP/AllLibs/MyLibs +++ b/UPP/AllLibs/MyLibs @@ -1 +1 @@ -Subproject commit 513f56fe7dbf0fa8e6a075c22e138c908a01d33f +Subproject commit 30fdbc35ddb1a72a5102aece8863921af0e4078d diff --git a/UPP/AllLibs/PeriphGeneral b/UPP/AllLibs/PeriphGeneral index 11c00f1..c0733a1 160000 --- a/UPP/AllLibs/PeriphGeneral +++ b/UPP/AllLibs/PeriphGeneral @@ -1 +1 @@ -Subproject commit 11c00f1e0c94ebd2cae77e17453005e32dfe5a3c +Subproject commit c0733a1d31ebd7b334dee6b1a8c2b00767fdbfca diff --git a/UPP/Core/Configs/mylibs_config.h b/UPP/Core/Configs/mylibs_config.h index 11c8233..b92e13c 100644 --- a/UPP/Core/Configs/mylibs_config.h +++ b/UPP/Core/Configs/mylibs_config.h @@ -97,12 +97,14 @@ #define BENCH_TIME_ENABLE ///< Включить бенч времени -#define BENCH_TIME_MAX_CHANNELS 5 ///< Максимальное количество каналов измерения +#define BENCH_TIME_MAX_CHANNELS 6 ///< Максимальное количество каналов измерения -#define BT_SLOWCALC 0 -#define BT_ADC 1 -#define BT_PWM 2 -#define BT_SYSTICK 3 +#define BT_SLOWCALC_PRD 0 +#define BT_SLOWCALC 1 +#define BT_ADC 2 +#define BT_ADC_PRD 3 +#define BT_PWM 4 +#define BT_SYSTICK 5 /** GEN_CONFIG * @} */ diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h index 94aae73..aac2abc 100644 --- a/UPP/Core/Configs/upp_config.h +++ b/UPP/Core/Configs/upp_config.h @@ -62,6 +62,7 @@ /* Параметры ПУИ */ #define PUI_Iref_PERCENT_DEFAULT 1.5 #define PUI_Tnt_MS_DEFAULT 300 +#define PUI_Tnt_CalcAlpha(...) FilterExp_CalcAlpha95(__VA_ARGS__) ///< Уровень в процентах, до куда нарастет ток за время Tnt #define PUI_Umin_PERCENT_DEFAULT 0.8 #define PUI_Umax_PERCENT_DEFAULT 1.2 #define PUI_Imax_PERCENT_DEFAULT 0.99 @@ -83,7 +84,6 @@ #define ANGLE_PID_KP_COEF_DEFAULT 0.0001 #define ANGLE_PID_KI_COEF_DEFAULT 0.0001 #define ANGLE_PID_KD_COEF_DEFAULT 0 -#define ANGLE_REF_TAU_COEF_DEFAULT 20.0 /* Параметри мониторинга сети */ #define PM_EXP_TAU_COEF_DEFAULT 0.05 @@ -99,8 +99,9 @@ #define ZERO_CROSS_DEBOUNCE_CNT_DEFAULT 2*100 // (2.5 * 100 = 2.5 мс) /* Параметры ШИМ для тиристоров */ -#define PWM_THYR_FREQUENCY_HZ_DEFAULT 5000 -#define PWM_THYR_PULSE_NUMBER_DEFAULT 5 +#define PWM_THYR_FREQUENCY_HZ_DEFAULT 16000 +#define PWM_THYR_DUTY_PERCENT_DEFAULT 0.5 +#define PWM_THYR_PULSE_NUMBER_DEFAULT 20 /** //UPP_PARAMS_DEFAULT * @} @@ -115,11 +116,11 @@ */ /* Периоды обновления всякого */ -#define PM_ADC_PERIOD_US 30 ///< Период опроса АЦП в мкс -#define PM_SLOW_PERIOD_US 500 ///< Период обновления медленных расчетов в мкс (чтобы делилось на @ref PM_ADC_PERIOD_US) -#define PM_TEMP_SLOW_PERIOD_MS 1000 ///< Период опроса АЦП в мс -#define PM_F_SLOW_PERIOD_MS 40 ///< Период обновления частоты в мс -#define UPP_INIT_BEFORE_READY_MS 2000 ///< Сколько сканировать сеть, перед выставлением состояния готовности +#define PM_ADC_PERIOD_US 25 ///< Период опроса АЦП в мкс +#define PM_SLOW_PERIOD_US 500 ///< Период обновления медленных расчетов в мкс (чтобы делилось на @ref PM_ADC_PERIOD_US) +#define PM_TEMP_SLOW_PERIOD_MS 1000 ///< Период обновлениия (фильтрации) датчиков температуры в мс +#define PM_F_SLOW_PERIOD_MS 40 ///< Период обновления (фильтрации) частоты в мс +#define UPP_INIT_BEFORE_READY_MS 2000 ///< Сколько сканировать сеть, перед выставлением состояния готовности /* Частоты таймеров в МГц*/ #define PWM_TIM1_FREQ_MHZ 180 ///< Частота тиков таймера ШИМ (1-4 каналы) @@ -128,19 +129,32 @@ #define ADC_TIM3_FREQ_MZH 90 ///< Частота тиков таймера АЦП #define ANGLE_TIM2_FREQ_MHZ 90 ///< Частота тиков таймера отсчета угла открытия тиристоров +/** //UPP_COMPILED_PARAMS + * @} + */ // ===== ОТЛАДОЧНЫЕ ШТУКИ ДЛЯ 417 ====== #if defined(STM32F417xx) + +// У старой платы УПП другие диапазоны датчиков +#undef ADC_U_MAX_V_DEFAULT +#undef ADC_I_MAX_A_DEFAULT + +#define ADC_U_MAX_V_DEFAULT 707.11 +#define ADC_I_MAX_A_DEFAULT 424.26 + + + +// У 417 меньше частота поэтому меняем прескалер #undef PWM_TIM1_FREQ_MHZ #undef PWM_TIM8_FREQ_MHZ #undef US_TIM5_FREQ_MHZ #undef ADC_TIM3_FREQ_MZH #undef ANGLE_TIM2_FREQ_MHZ -// У 417 меньше частота поэтому меняем прескалер #define PWM_TIM1_FREQ_MHZ 168 ///< Частота тиков таймера ШИМ (1-4 каналы) #define PWM_TIM8_FREQ_MHZ 168 ///< Частота тиков таймера ШИМ (5-6 каналы) #define US_TIM5_FREQ_MHZ 84 ///< Частота тиков микросекундного таймера @@ -148,9 +162,10 @@ #define ANGLE_TIM2_FREQ_MHZ 84 ///< Частота тиков таймера отсчета угла открытия тиристоров #define HAL_PWREx_EnableOverDrive() HAL_ERROR -#endif -// ===== ОТЛАДОЧНЫЕ ШТУКИ ДЛЯ MATLAB ====== +#endif //defined(STM32F417xx) + +// ===== ОТЛАДОЧНЫЕ ШТУКИ ДЛЯ MATLAB ====== #if defined(MATLAB) #undef UPP_INIT_BEFORE_READY_MS @@ -158,8 +173,5 @@ #define UPP_INIT_BEFORE_READY_MS 100 ///< Сколько сканировать сеть, перед выставлением состояния готовности -#endif -/** //UPP_COMPILED_PARAMS - * @} - */ +#endif //defined(MATLAB) #endif //_UPP_CONFIG_H_ diff --git a/UPP/Core/Configs/upp_defs.h b/UPP/Core/Configs/upp_defs.h index dd055dc..c0afca5 100644 --- a/UPP/Core/Configs/upp_defs.h +++ b/UPP/Core/Configs/upp_defs.h @@ -158,8 +158,7 @@ typedef struct { /* Перерасчеты в тики */ #define ANGLE_PERIOD_MS(_freq_) (((float)1/(_freq_*2))*1000) ///< Период обновления частоты в тиках @ref PM_SLOW_PERIOD_CNT -/* Расчет коэффициента альфа для экспоненциального фильтра */ -#define CALC_TAU_COEF(tau, TsUs) (((float)TsUs/1000000) / (((float)TsUs/1000000) + (tau))) +#define SQRT2 1.4142135 /* Дефайны для "удобного" доступа к структурам */ #define PARAM_INTERNAL MB_INTERNAL.param diff --git a/UPP/Core/PowerMonitor/adc_tools.c b/UPP/Core/PowerMonitor/adc_tools.c index f959c46..a84dfc9 100644 --- a/UPP/Core/PowerMonitor/adc_tools.c +++ b/UPP/Core/PowerMonitor/adc_tools.c @@ -104,7 +104,7 @@ HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, float PeriodUs) HAL_TIM_Base_Stop(adc->htim); // Запускаем таймер который будет запускать опрос АЦП с заданным периодом - __HAL_TIM_SET_AUTORELOAD_FORCE(adc->htim, TIM_MicrosToTick(PeriodUs, ADC_TIM3_FREQ_MZH-1)); + __HAL_TIM_SET_AUTORELOAD_FORCE(adc->htim, TIM_MicrosToTick(PeriodUs, ADC_TIM3_FREQ_MZH)); res = HAL_TIM_Base_Start(adc->htim); if(res != HAL_OK) diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c index 9c82526..1f70473 100644 --- a/UPP/Core/PowerMonitor/power_monitor.c +++ b/UPP/Core/PowerMonitor/power_monitor.c @@ -162,15 +162,17 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm) /* Средниее напряжение фазы */ uphase_mean = fabsf(meas->slow.U[i]); - meas->final.U[i] = Filter_Process(&hpm->exp[EXP_UBA+i], uphase_mean); + uphase_mean = Filter_Process(&hpm->exp[EXP_UBA+i], uphase_mean); + meas->final.U[i] = uphase_mean*PI/2/SQRT2; /*PI/2 - получить амплитудное, SQRT2 - получить действующее */ /* Средний ток фазы */ iphase_mean = fabsf(meas->slow.I[i]); - meas->final.I[i] = Filter_Process(&hpm->exp[EXP_IC+i], iphase_mean); + iphase_mean = Filter_Process(&hpm->exp[EXP_IC+i], iphase_mean)*PI/2; + meas->final.I[i] = iphase_mean*PI/2/SQRT2; /*PI/2 - получить амплитудное, SQRT2 - получить действующее */ /* Реальные единицы измерения (Вольты/Амперы) */ - meas->real.I[i] = meas->slow.I[i]*i_base; - meas->real.U[i] = meas->slow.U[i]*u_base; + meas->real.I[i] = meas->final.I[i]*i_base; + meas->real.U[i] = meas->final.U[i]*u_base; } /* Получение средней частоты по трем фазам */ meas->final.Fmean = fmean / 3; @@ -186,12 +188,13 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm) /* Расчет амплитуд трехфазной сети */ - float uamp = vector_abs_linear_calc(meas->slow.U[U_BA], meas->slow.U[U_AC]); - float iamp = vector_abs_phase_calc(meas->slow.I[I_A], meas->slow.I[I_C]); + float uamp = vector_abs_linear_calc(meas->slow.U[U_BA], meas->slow.U[U_AC])/SQRT2; /* SQRT2 - получить действующее */ + float iamp = vector_abs_phase_calc(meas->slow.I[I_A], meas->slow.I[I_C])/SQRT2; /* SQRT2 - получить действующее */ meas->final.Uamp = Filter_Process(&hpm->exp[EXP_U], uamp); meas->final.Iamp = Filter_Process(&hpm->exp[EXP_I], iamp); - + + hpm->slow_cnt++; } /** diff --git a/UPP/Core/PowerMonitor/power_monitor.h b/UPP/Core/PowerMonitor/power_monitor.h index ee343ff..b0a4872 100644 --- a/UPP/Core/PowerMonitor/power_monitor.h +++ b/UPP/Core/PowerMonitor/power_monitor.h @@ -80,11 +80,11 @@ typedef struct float I[3]; ///< Ток }slow; - /** @brief Реальные величины - обновляются кто где, и содержат значения в В/А */ + /** @brief Реальные величины - обновляются в main в @ref PowerMonitor_SlowCalc, и содержат значения в В/А */ struct { - float U[3]; ///< Напряжение (обновляется в прерывании АЦП) - float I[3]; ///< Ток (обновляется в прерывании АЦП) + float U[3]; ///< Напряжение (Действующее) + float I[3]; ///< Ток (Действующее) }real; }PowerMonitor_Measured_t; @@ -104,6 +104,7 @@ typedef struct PowerMonitor_Flags_t f; ///< Флаги мониторинга uint32_t isr_cnt; + uint32_t slow_cnt; }PowerMonitor_t; extern PowerMonitor_t pm; diff --git a/UPP/Core/Src/main.c b/UPP/Core/Src/main.c index 64019f9..e231ae7 100644 --- a/UPP/Core/Src/main.c +++ b/UPP/Core/Src/main.c @@ -80,6 +80,7 @@ int main(void) __HAL_FREEZE_TIM8_DBGMCU(); __HAL_FREEZE_TIM11_DBGMCU(); __HAL_FREEZE_TIM12_DBGMCU(); + __HAL_FREEZE_TIM14_DBGMCU(); /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ diff --git a/UPP/Core/Src/stm32f4xx_it.c b/UPP/Core/Src/stm32f4xx_it.c index 526ec8a..974357c 100644 --- a/UPP/Core/Src/stm32f4xx_it.c +++ b/UPP/Core/Src/stm32f4xx_it.c @@ -238,6 +238,10 @@ void TIM2_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 */ HAL_TIM_IRQHandler(&htim8); @@ -253,11 +257,14 @@ void TIM8_TRG_COM_TIM14_IRQHandler(void) void DMA2_Stream0_IRQHandler(void) { /* USER CODE BEGIN DMA2_Stream0_IRQn 0 */ - + // Вторая половина буфера (Transfer Complete) + if (DMA2->LISR & DMA_LISR_TCIF0) { + UPP_ADC_Handle(); + } /* USER CODE END DMA2_Stream0_IRQn 0 */ HAL_DMA_IRQHandler(&hdma_adc3); /* USER CODE BEGIN DMA2_Stream0_IRQn 1 */ - UPP_ADC_Handle(); + /* USER CODE END DMA2_Stream0_IRQn 1 */ } diff --git a/UPP/Core/Src/tim.c b/UPP/Core/Src/tim.c index 97a009e..1f5a7d0 100644 --- a/UPP/Core/Src/tim.c +++ b/UPP/Core/Src/tim.c @@ -209,7 +209,7 @@ void MX_TIM3_Init(void) Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; - sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE; + sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK) { Error_Handler(); diff --git a/UPP/Core/UPP/angle_control.c b/UPP/Core/UPP/angle_control.c index 1d4e3ff..6efb442 100644 --- a/UPP/Core/UPP/angle_control.c +++ b/UPP/Core/UPP/angle_control.c @@ -21,12 +21,6 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle) hangle->htim = &angletim; - // Инициализация ПИД - float kp = to_float(PARAM_INTERNAL.angle.PID_Kp, 10000); - float ki = to_float(PARAM_INTERNAL.angle.PID_Ki, 10000); - float kd = to_float(PARAM_INTERNAL.angle.PID_Kd, 10000); - float ref_alpha = to_float(PARAM_INTERNAL.angle.PID_ExpAlpha, 65535); - Angle_PID_Init(hangle, kp, ki, kd, ref_alpha); // Инициализация каналов HAL_TIM_OC_Start_IT(hangle->htim, ANGLE_CHANNEL_1); @@ -43,7 +37,14 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle) float angle_min = to_float(PARAM_INTERNAL.angle.Angle_Min, 65535); hangle->f.Initialized = 1; - return HAL_OK; + + // Инициализация ПИД + float kp = to_float(PARAM_INTERNAL.angle.PID_Kp, 10000); + float ki = to_float(PARAM_INTERNAL.angle.PID_Ki, 10000); + float kd = to_float(PARAM_INTERNAL.angle.PID_Kd, 10000); + float ref_alpha = PUI_Tnt_CalcAlpha(to_float(PARAM_PUI.Tnt, 1000), PM_SLOW_PERIOD_US); + + return Angle_PID_Init(hangle, kp, ki, kd, ref_alpha);; } @@ -52,10 +53,10 @@ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle) * @param hangle Указатель на таймер * @param kp, ki kd Коэффициенты регулятора */ -void Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float alpha) +HAL_StatusTypeDef Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float alpha) { if(assert_upp(hangle)) - return; + return HAL_ERROR; // Сам ПИД регулятор hangle->pid.Kp = kp; @@ -67,6 +68,8 @@ void Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float FilterExp_Init(&hangle->refFilter, alpha); Filter_Start(&hangle->refFilter); Filter_Process(&hangle->refFilter, 0); + + return HAL_OK; } /** diff --git a/UPP/Core/UPP/angle_control.h b/UPP/Core/UPP/angle_control.h index 9b72f8b..6017e54 100644 --- a/UPP/Core/UPP/angle_control.h +++ b/UPP/Core/UPP/angle_control.h @@ -44,7 +44,7 @@ typedef struct /* Инициализация Таймера для рассчета угла открытия. */ HAL_StatusTypeDef Angle_Init(Angle_Handle_t *hangle); /* Инициализация ПИД регулятора. */ -void Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float alpha); +HAL_StatusTypeDef Angle_PID_Init(Angle_Handle_t *hangle, float kp, float ki, float kd, float alpha); // ====== УПРАВЛЕНИЕ ========== /* Управление углом через ПИД регулятор */ diff --git a/UPP/Core/UPP/pwm_thyristors.c b/UPP/Core/UPP/pwm_thyristors.c index dc47ed3..e9f8245 100644 --- a/UPP/Core/UPP/pwm_thyristors.c +++ b/UPP/Core/UPP/pwm_thyristors.c @@ -59,7 +59,10 @@ 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, PARAM_INTERNAL.pwm.PulseNumber); + PWM_SetConfig(hpwm, PARAM_INTERNAL.pwm.PhaseMask, + PARAM_INTERNAL.pwm.Frequency, + to_float(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); @@ -154,7 +157,6 @@ HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_ { // в первую очередь выключаем канал, потом выставим режим каналов __HAL_TIM_MOE_DISABLE(&hpwm1); - // в первую очередь выключаем канал, потом выставим режим каналов __HAL_TIM_MOE_DISABLE(&hpwm2); @@ -197,7 +199,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, uint8_t PulseNumber) +HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, uint8_t PulseNumber) { if(assert_upp(hpwm)) return HAL_ERROR; @@ -210,16 +212,19 @@ HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t hpwm->Config.PhaseMask.all = PhaseMask; hpwm->Config.PulseNumber = PulseNumber; hpwm->Config.Frequency = Frequency; + hpwm->Config.Duty = Duty; // Высставление периодов __HAL_TIM_SET_AUTORELOAD(&hpwm1, TIM_FreqToTick(Frequency, PWM_TIM1_FREQ_MHZ-1)); __HAL_TIM_SET_AUTORELOAD(&hpwm2, TIM_FreqToTick(Frequency, PWM_TIM8_FREQ_MHZ-1)); - // Скважности 50/50 - __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_1, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); - __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_2, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); - __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_3, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); - __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_4, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); - __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_5, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2); - __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_6, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2); + // Скважности + uint32_t pwm1_duty_ccr = (float)__HAL_TIM_GET_AUTORELOAD(&hpwm1)*(1-Duty); + uint32_t pwm2_duty_ccr = (float)__HAL_TIM_GET_AUTORELOAD(&hpwm2)*(1-Duty); + __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_1, pwm1_duty_ccr); + __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_2, pwm1_duty_ccr); + __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_3, pwm1_duty_ccr); + __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_4, pwm1_duty_ccr); + __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_5, pwm2_duty_ccr); + __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_6, pwm2_duty_ccr); // Сброс счетчиков таймера и запуск заного diff --git a/UPP/Core/UPP/pwm_thyristors.h b/UPP/Core/UPP/pwm_thyristors.h index c35c208..ee1075b 100644 --- a/UPP/Core/UPP/pwm_thyristors.h +++ b/UPP/Core/UPP/pwm_thyristors.h @@ -74,6 +74,7 @@ typedef struct { }PhaseMask; ///< Какими каналами управлять uint8_t PulseNumber; ///< Сколько импульсов отправить в пакете для открытия тиристоров uint16_t Frequency; ///< Частота импульсов + float Duty; ///< Скважность импульсов } PWM_ThyrConfig_t; /** @@ -100,7 +101,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); /* Установка частоты ШИМ. */ -HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, uint8_t PulseNumber); +HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, uint8_t PulseNumber); /* Установка полуволны для слежения. */ HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave); /* Установка полярности шим. */ diff --git a/UPP/Core/UPP/upp_errors.c b/UPP/Core/UPP/upp_errors.c index 0afb1c0..d5a269b 100644 --- a/UPP/Core/UPP/upp_errors.c +++ b/UPP/Core/UPP/upp_errors.c @@ -19,7 +19,7 @@ UPP_Errors_t errors; static UPP_ErrorType_t UPP_SelectCommonError(void); -static int setError(int condition, int flag, int *timer, int delay); +__STATIC_FORCEINLINE int setError(int condition, int flag, int *timer, int delay); void UPP_Errors_Program(void); void UPP_Errors_Power(void); void UPP_Errors_Ranges(void); @@ -225,7 +225,7 @@ static UPP_ErrorType_t UPP_SelectCommonError(void) } -static int setError(int condition, int flag, int *timer, int delay) +__STATIC_FORCEINLINE int setError(int condition, int flag, int *timer, int delay) { if (condition) { if (*timer < delay) diff --git a/UPP/Core/UPP/upp_errors.h b/UPP/Core/UPP/upp_errors.h index 96d2985..c314ffc 100644 --- a/UPP/Core/UPP/upp_errors.h +++ b/UPP/Core/UPP/upp_errors.h @@ -145,6 +145,7 @@ typedef struct struct { + uint16_t angle_reinit_err; uint16_t adc_reinit_err; uint16_t zc_reinit_err; uint16_t pwm_reinit_err; diff --git a/UPP/Core/UPP/upp_io.c b/UPP/Core/UPP/upp_io.c index 529fad7..41aa5ce 100644 --- a/UPP/Core/UPP/upp_io.c +++ b/UPP/Core/UPP/upp_io.c @@ -29,7 +29,7 @@ static void UPP_DO5_Write(int state); */ void UPP_IO_Init(void) { - /* Дискретне выходы */ + /* Дискретные выходы */ UPP_DO.CEN = &UPP_CEN_Write; UPP_DO.Ready = &UPP_RDO3_Write; UPP_DO.Work = &UPP_RDO2_Write; diff --git a/UPP/Core/UPP/upp_io.h b/UPP/Core/UPP/upp_io.h index 7d369d6..3fecb4b 100644 --- a/UPP/Core/UPP/upp_io.h +++ b/UPP/Core/UPP/upp_io.h @@ -10,7 +10,10 @@ #define _UPP_IO_H #include "mylibs_include.h" - +#define DIN_Pusk_GPIO_Port DIN1_GPIO_Port +#define DIN_Pusk_Pin DIN1_Pin +#define DIN_MestDist_GPIO_Port DIN2_GPIO_Port +#define DIN_MestDist_Pin DIN2_Pin typedef struct { diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c index 87e0742..36a4ed5 100644 --- a/UPP/Core/UPP/upp_main.c +++ b/UPP/Core/UPP/upp_main.c @@ -16,7 +16,7 @@ UPP_t upp; HAL_StatusTypeDef res; // сюда сохраняется результат от выполения всяких функций float dbg_iref = 2; -int dbg_polarity = 0; +int dbg_polarity = 1; /** * @brief Инициализация УПП. @@ -60,17 +60,12 @@ int UPP_App_Init(void) * @return 0 - если ОК, >1 если ошибка. */ int UPP_PreWhile(void) -{ - UPP_Params_ControlInternal(); - - if(Angle_SetRange(&upp.hangle, 0.0, 0.8) != HAL_OK) - return 1; +{ + UPP_Params_Control(); if(PowerMonitor_Start(&upp.pm) != HAL_OK) return 1; - - UPP_DO.CEN(ENABLE); return 0; } @@ -86,19 +81,26 @@ int UPP_While(void) if(upp.pm.f.runSlow) { static uint32_t slow_cnt = 0; + upp.Timings.slow_calc_prd_us = BenchTime_Period(BT_SLOWCALC_PRD, angletim.Instance->CNT, HAL_MAX_DELAY)/ANGLE_TIM2_FREQ_MHZ; BenchTime_Start(BT_SLOWCALC, angletim.Instance->CNT, HAL_MAX_DELAY); - res = HAL_IWDG_Refresh(&hiwdg); + res = HAL_IWDG_Refresh(&hiwdg); // если не вызываются медленные расчеты - что-то не то сбрасываемся по watchdog // Медленные расчеты - PowerMonitor_SlowCalc(&upp.pm); + PowerMonitor_SlowCalc(&upp.pm); #ifdef UPP_SIMULATE_I // симулируем токи - upp.pm.measured.final.Iamp = upp.hangle.Iref/2; + upp.pm.measured.final.Iamp = upp.hangle.Iref/2; // Защиты // При симуляции тока не включаем его проверку PowerMonitor_Protect(&upp.pm, 0); #else // Защиты // Определенные защиты по току включаем только в после разгона PowerMonitor_Protect(&upp.pm, (fabsf(upp.hangle.Iref - dbg_iref) < 0.1)); #endif + // Обрабока ошибок и выставление итоговой Ошибки + UPP_Errors_Handle(); + // Контроль парамеров + UPP_Params_Control(); + + #ifndef UPP_DISABLE_ERROR_BLOCK @@ -224,13 +226,10 @@ int UPP_While(void) */ void UPP_Tick(void) { + // Начинаем все проверять только после того как уйдем из режима инициализации if(upp.workmode == UPP_Init) return; - // Обрабока ошибок и выставление итоговой Ошибки - UPP_Errors_Handle(); - // - UPP_Params_ControlInternal(); if(GPIO_Read_Switch(&UPP_DIN.Pusk)) { @@ -244,10 +243,16 @@ void UPP_Tick(void) -// ПРЕРЫВАНИЯ stm32f4xx_it.c +//================ ПРЕРЫВАНИЯ stm32f4xx_it.c =================== +/** + * @brief @ref DMA2_Stream0_IRQHandler + */ void UPP_ADC_Handle(void) { + upp.Timings.isr_adc_prd_us = BenchTime_Period(BT_ADC_PRD, angletim.Instance->CNT, HAL_MAX_DELAY)/ANGLE_TIM2_FREQ_MHZ; BenchTime_Start(BT_ADC, angletim.Instance->CNT, HAL_MAX_DELAY); + + if(upp.pm.f.inIsr) { ERR_PRIVATE.overrun_fast_calc = 1; @@ -282,6 +287,9 @@ void UPP_ADC_Handle(void) 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); @@ -289,6 +297,9 @@ void UPP_PWM_Handle(void) upp.Timings.isr_pwm_us = BenchTime_End(BT_PWM, angletim.Instance->CNT)/ANGLE_TIM2_FREQ_MHZ; } +/** + * @brief @ref HAL_TIM_OC_DelayElapsedCallback + */ void UPP_Angle_Handle(void) { UPP_Phase_t phase = Angle_Handle(&upp.hangle); @@ -315,7 +326,9 @@ void UPP_Angle_Handle(void) } } -// Callback по совпадению CCRx +/** + * @brief Callback по совпадению CCRx c CNT + */ void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim) { if (htim == upp.hangle.htim) @@ -323,6 +336,9 @@ void HAL_TIM_OC_DelayElapsedCallback(TIM_HandleTypeDef* htim) UPP_Angle_Handle(); } } +/** + * @brief @ref HAL_TIM_PeriodElapsedCallback + */ void HAL_IncTick(void) { BenchTime_Start(BT_SYSTICK, angletim.Instance->CNT, HAL_MAX_DELAY); diff --git a/UPP/Core/UPP/upp_main.h b/UPP/Core/UPP/upp_main.h index 22a261c..112354d 100644 --- a/UPP/Core/UPP/upp_main.h +++ b/UPP/Core/UPP/upp_main.h @@ -39,7 +39,9 @@ typedef struct struct { + uint32_t slow_calc_prd_us; uint32_t slow_calc_us; + uint32_t isr_adc_prd_us; uint32_t isr_adc_us; uint32_t isr_pwm_us; uint32_t isr_systick_us; diff --git a/UPP/Core/UPP/upp_params.c b/UPP/Core/UPP/upp_params.c index c0377ed..b37e83a 100644 --- a/UPP/Core/UPP/upp_params.c +++ b/UPP/Core/UPP/upp_params.c @@ -1,26 +1,105 @@ /** ****************************************************************************** * @file upp_params.c -* @brief Модуль определябщий поведение УПП +* @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 __CheckSimpleParamF(float *paramDist, uint16_t paramSrc, float Coef); -static int __CheckSimpleParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef); -static int __CheckSimpleParamU16(uint16_t *paramDist, uint16_t paramSrc); -static int __CheckSimpleParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef); +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 Уставка на скорость нарастания пускового тока Iref */ + float angle_ref_alphaPUI = PUI_Tnt_CalcAlpha(to_float(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) { - __AngleSetLimit(); if(upp.call->go) // при запущеном УПП ничего не меняем return; @@ -36,7 +115,6 @@ void UPP_Params_ControlInternal(void) float angle_pid_kp = upp.hangle.pid.Kp; float angle_pid_ki = upp.hangle.pid.Ki; float angle_pid_kd = upp.hangle.pid.Kd; - float angle_ref_alpha = upp.hangle.refFilter.alpha; // временная переменная для параметров каналов АЦП float adc_channel_max[ADC_NUMB_OF_REGULAR_CHANNELS] = {0}; uint16_t adc_channel_zero[ADC_NUMB_OF_REGULAR_CHANNELS] = {0}; @@ -46,6 +124,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 pm_alpha = upp.pm.exp[0].alpha; @@ -53,31 +132,26 @@ void UPP_Params_ControlInternal(void) // Параметры регулятора Угла открытия - if(__CheckSimpleParamF(&angle_max, PARAM_INTERNAL.angle.Angle_Max, 65535)) + if(__CheckParamF(&angle_max, PARAM_INTERNAL.angle.Angle_Max, 65535)) { alpha_update = 1; } - if(__CheckSimpleParamF(&angle_min, PARAM_INTERNAL.angle.Angle_Min, 65535)) + if(__CheckParamF(&angle_min, PARAM_INTERNAL.angle.Angle_Min, 65535)) { alpha_update = 1; } - if(__CheckSimpleParamF(&angle_pid_kp, PARAM_INTERNAL.angle.PID_Kp, 10000)) + if(__CheckParamF(&angle_pid_kp, PARAM_INTERNAL.angle.PID_Kp, 10000)) { alpha_update = 1; } - if(__CheckSimpleParamF(&angle_pid_ki, PARAM_INTERNAL.angle.PID_Ki, 10000)) + if(__CheckParamF(&angle_pid_ki, PARAM_INTERNAL.angle.PID_Ki, 10000)) { alpha_update = 1; } - if(__CheckSimpleParamF(&angle_pid_kd, PARAM_INTERNAL.angle.PID_Kd, 10000)) + if(__CheckParamF(&angle_pid_kd, PARAM_INTERNAL.angle.PID_Kd, 10000)) { alpha_update = 1; - } - if(__CheckSimpleParamF(&angle_ref_alpha, PARAM_INTERNAL.angle.PID_ExpAlpha, 65535)) - { - alpha_update = 1; - } - + } // Параметры АЦП @@ -87,56 +161,72 @@ void UPP_Params_ControlInternal(void) adc_channel_zero[i] = upp.pm.adc.Coefs[i].lZero; // Максимальное измеряемое напряжение - if(__CheckSimpleParamF(&adc_channel_max[i], PARAM_INTERNAL.adc.ADC_Max[i], 10)) + if(__CheckParamF(&adc_channel_max[i], PARAM_INTERNAL.adc.ADC_Max[i], 10)) { adc_channel_update[i] = 1; } // Значение АЦП при нулевом входе - if(__CheckSimpleParamU16(&adc_channel_zero[i], PARAM_INTERNAL.adc.ADC_Zero[i])) + if(__CheckParamU16(&adc_channel_zero[i], PARAM_INTERNAL.adc.ADC_Zero[i])) { adc_channel_update[i] = 1; } } // Параметры алгоритма перехода через ноль - if(__CheckSimpleParamF(&zc_hysteresis, PARAM_INTERNAL.zc.Hysteresis, 10000)) + if(__CheckParamF(&zc_hysteresis, PARAM_INTERNAL.zc.Hysteresis, 10000)) { zc_update = 1; } - if(__CheckSimpleParamU16(&zc_debounce, PARAM_INTERNAL.zc.DebouneCouner)) + if(__CheckParamU16(&zc_debounce, PARAM_INTERNAL.zc.DebouneCouner)) { zc_update = 1; } // Параметры ШИМ токов - if(__CheckSimpleParamU8(&pwm_phase_mask, PARAM_INTERNAL.pwm.PhaseMask, 1)) + if(__CheckParamU8(&pwm_phase_mask, PARAM_INTERNAL.pwm.PhaseMask, 1)) { pwm_update = 1; } - if(__CheckSimpleParamU16(&pwm_freq, PARAM_INTERNAL.pwm.Frequency)) + if(__CheckParamU16(&pwm_freq, PARAM_INTERNAL.pwm.Frequency)) { pwm_update = 1; } - if(__CheckSimpleParamU8(&pwm_pulse_num, PARAM_INTERNAL.pwm.PulseNumber, 1)) + if(__CheckParamF(&pwm_duty, PARAM_INTERNAL.pwm.Duty, 100)) { pwm_update = 1; - } + } + if(__CheckParamU8(&pwm_pulse_num, PARAM_INTERNAL.pwm.PulseNumber, 1)) + { + pwm_update = 1; + } + // Параметры мониторинга - if(__CheckSimpleParamF(&pm_alpha, PARAM_INTERNAL.pm.mean_alpha, 65535)) + if(__CheckParamF(&pm_alpha, PARAM_INTERNAL.pm.mean_alpha, 65535)) { for(int i = 0; i < EXP_ALL; i++) { Filter_ReInit(&upp.pm.exp[i], pm_alpha); + Filter_Start(&upp.pm.exp[i]); } } // Обновление регулятора угла открытия + __AngleSetLimit(); if(alpha_update) { - Angle_SetRange(&upp.hangle, angle_min, angle_max); - Angle_PID_Init(&upp.hangle, angle_pid_kp, angle_pid_ki, angle_pid_kd, angle_ref_alpha); + if(Angle_SetRange(&upp.hangle, angle_min, angle_max) == HAL_OK) + { + if(Angle_PID_Init(&upp.hangle, angle_pid_kp, angle_pid_ki, 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++) @@ -160,7 +250,7 @@ void UPP_Params_ControlInternal(void) // Обновление ШИМ конфигов if(pwm_update) { - if(PWM_SetConfig(&upp.hpwm, pwm_phase_mask, pwm_freq, pwm_pulse_num) == HAL_OK) + if(PWM_SetConfig(&upp.hpwm, pwm_phase_mask, pwm_freq, pwm_duty, pwm_pulse_num) == HAL_OK) { pwm_update = 0; } @@ -178,6 +268,46 @@ void UPP_Params_ControlInternal(void) */ 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, ADC_U_MAX_V_DEFAULT*10); + SATURATE_U16(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_UAC], 0, ADC_U_MAX_V_DEFAULT*10); + SATURATE_U16(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IC], 0, ADC_I_MAX_A_DEFAULT*10); + SATURATE_U16(PARAM_INTERNAL.adc.ADC_Max[ADC_CHANNEL_IA], 0, ADC_I_MAX_A_DEFAULT*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.pwm.PulseNumber, 1, 50); + + 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); } /** @@ -215,7 +345,7 @@ void UPP_Params_SetDefault(int pui_default, int internal_default) 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.mean_alpha = CALC_TAU_COEF(PM_EXP_TAU_COEF_DEFAULT,PM_SLOW_PERIOD_US)*65535; + PARAM_INTERNAL.pm.mean_alpha = FilterExp_CalcAlpha(PM_EXP_TAU_COEF_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; @@ -226,9 +356,10 @@ void UPP_Params_SetDefault(int pui_default, int internal_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 = (float)PWM_THYR_FREQUENCY_HZ_DEFAULT; - PARAM_INTERNAL.pwm.PulseNumber = PWM_THYR_PULSE_NUMBER_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.zc.Hysteresis = ZERO_CROSS_HYSTERESIS_PERCENT_DEFAULT*100; PARAM_INTERNAL.zc.DebouneCouner = ZERO_CROSS_DEBOUNCE_CNT_DEFAULT; @@ -237,7 +368,6 @@ void UPP_Params_SetDefault(int pui_default, int internal_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.PID_ExpAlpha = CALC_TAU_COEF(ANGLE_REF_TAU_COEF_DEFAULT,PM_SLOW_PERIOD_US)*65535; 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; @@ -266,7 +396,7 @@ static void __AngleSetLimit(void) * @param Coef Коэффициент для приведения float к uint16_t: uint16_t = float*coef, float = uint16_t/coef * @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc. */ -static int __CheckSimpleParamF(float *paramDist, uint16_t paramSrc, float Coef) +static int __CheckParamF(float *paramDist, uint16_t paramSrc, float Coef) { if(paramDist == NULL) return 0; @@ -289,7 +419,7 @@ static int __CheckSimpleParamF(float *paramDist, uint16_t paramSrc, float Coef) * @param Coef Коэффициент для приведения uint32_t к uint16_t: uint16_t = uint32_t*coef, uint32_t = uint16_t/coef * @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc. */ -static int __CheckSimpleParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef) +static int __CheckParamU32(uint32_t *paramDist, uint16_t paramSrc, float Coef) { if(paramDist == NULL) return 0; @@ -311,7 +441,7 @@ static int __CheckSimpleParamU32(uint32_t *paramDist, uint16_t paramSrc, float C * @param paramSrc Значение для сравнения с uint16_t параметром * @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc. */ -static int __CheckSimpleParamU16(uint16_t *paramDist, uint16_t paramSrc) +static int __CheckParamU16(uint16_t *paramDist, uint16_t paramSrc) { if(paramDist == NULL) return 0; @@ -335,7 +465,7 @@ static int __CheckSimpleParamU16(uint16_t *paramDist, uint16_t paramSrc) * @param Coef Коэффициент для приведения uint32_t к uint16_t: uint16_t = uint8_t*coef, uint8_t = uint16_t/coef * @return 0 - параметры совпадают, 1 - параметр был обновлен на paramSrc. */ -static int __CheckSimpleParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef) +static int __CheckParamU8(uint8_t *paramDist, uint16_t paramSrc, float Coef) { if(paramDist == NULL) return 0; diff --git a/UPP/Core/UPP/upp_params.h b/UPP/Core/UPP/upp_params.h index 22a3db6..82684a1 100644 --- a/UPP/Core/UPP/upp_params.h +++ b/UPP/Core/UPP/upp_params.h @@ -65,9 +65,10 @@ typedef struct /* Параметры ШИМ */ struct { - uint16_t PhaseMask; ///< Битовяя маска на какие фазы подавать ШИМ: 0 бит - a, 1 бит - b, 2 бит - c - uint16_t Frequency; ///< Частота ШИМ для пачки импульсов на тиристоры [Герцы] - uint16_t PulseNumber; ///< Количесво импульсов в пачке [Количество] + uint16_t PhaseMask; ///< Битовяя маска на какие фазы подавать ШИМ: 0 бит - a, 1 бит - b, 2 бит - c + uint16_t Frequency; ///< Частота ШИМ для пачки импульсов на тиристоры [Герцы] + uint16_t Duty; ///< Скважность ШИМ для пачки импульсов на тиристоры [Проценты] + uint16_t PulseNumber; ///< Количесво импульсов в пачке [Количество] }pwm; /* Параметры Угла */ @@ -87,16 +88,20 @@ typedef struct uint16_t PID_Kp; ///< Пропорциональный коэфициент ПИ регулятора угла [x 10000] uint16_t PID_Ki; ///< Интегральный коэфициент ПИ регулятора угла [x 10000] uint16_t PID_Kd; ///< Интегральный коэфициент ПИ регулятора угла [x 10000] - uint16_t PID_ExpAlpha; ///< Коэффициент сглаживающего фильтра задания регулятора [0..1 x 65535] }angle; }UPP_PrvtParams_t; - +/* Контроль параметров УПП. */ +void UPP_Params_Control(void); +/* Контроль параметров от ПУИ. */ +void UPP_Params_ControlPUI(void); /* Контроль внутренних параметров УПП. */ void UPP_Params_ControlInternal(void); +/* Контроль параметров УПП на корректные значения. */ +void UPP_Params_Saturate(void); /* Установка параметров на дефолтные значения */ void UPP_Params_SetDefault(int pui_default, int internal_default); diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx index 2702d77..3504953 100644 --- a/UPP/MDK-ARM/UPP.uvoptx +++ b/UPP/MDK-ARM/UPP.uvoptx @@ -322,59 +322,10 @@ 0 ST-LINKIII-KEIL_SWO - -U005600373433510237363934 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131123 -TC168000000 -TT10000000 -TP21 -TDS800D -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F417ZGTx$CMSIS\Flash\STM32F4xx_1024.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2 + -U005600373433510237363934 -O206 -SF10000 -C0 -A0 -I0 -HNlocalhost -HP7184 -P1 -N00("ARM CoreSight SW-DP (ARM Core") -D00(2BA01477) -L00(0) -TO131123 -TC168000000 -TT10000000 -TP21 -TDS800D -TDT1 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F417ZGTx$CMSIS\Flash\STM32F4xx_1024.FLM) -WA0 -WE0 -WVCE4 -WS2710 -WM0 -WP2 - - - 0 - 0 - 407 - 1 -
134233766
- 0 - 0 - 0 - 0 - 0 - 1 - ../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c - - \\Debug_F417\../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c\407 -
- - 1 - 0 - 136 - 1 -
134256344
- 0 - 0 - 0 - 0 - 0 - 1 - ../Core/Src/stm32f4xx_it.c - - \\Debug_F417\../Core/Src/stm32f4xx_it.c\136 -
- - 2 - 0 - 27 - 1 -
0
- 0 - 0 - 0 - 0 - 0 - 0 - .\startup_stm32f417xx.s - - -
-
+ 0 @@ -456,6 +407,21 @@ 1 \\Debug_F417\../Core/UPP/upp_io.c\UPP_DIN.Pusk.Sw_FilterDelay + + 16 + 1 + hadc3 + + + 17 + 1 + upp.hangle.Iref + + + 18 + 1 + upp.pm.measured.final.U[0] + @@ -466,7 +432,7 @@ 1 2 - MB_DATA + MB_DATA,0x0A 2 @@ -523,6 +489,11 @@ 2 upp.pm.measured.slow.U[0] + + 13 + 2 + upp,0x0A + 0 @@ -530,7 +501,7 @@ 0 1 - 1 + 0 0 0 0 @@ -569,41 +540,17 @@ 0 - `upp.pm.zc.Channel[0].HalfWave - 0000000000000000000000000000000000000040000000000000000000000000000000007570702E706D2E7A632E4368616E6E656C5B305D2E48616C66576176650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500000001000000000000000000F03F1400000000000000000000000000000000000000FC9E0008 + `upp.pm.measured.final.U[0] + 008000000000000000000000000000000000F03F000000000000000000000000000000007570702E706D2E6D656173757265642E66696E616C2E555B305D0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000001000000000000000000F03F140000000000000000000000000000000000000020B20008 - System Viewer\DBG - 35902 - - - System Viewer\GPIOE - 35898 - - - System Viewer\GPIOG - 35899 - - - System Viewer\TIM1 - 35901 - - - System Viewer\TIM14 - 35903 - - - System Viewer\TIM2 - 35900 - - - System Viewer\TIM5 + System Viewer\ADC3 35905 - System Viewer\TIM8 + System Viewer\DMA2 35904 @@ -1227,7 +1174,7 @@ MyLibs - 0 + 1 0 0 0 @@ -1515,7 +1462,7 @@ PeriphGeneral - 1 + 0 0 0 0 diff --git a/UPP/MDK-ARM/UPP.uvprojx b/UPP/MDK-ARM/UPP.uvprojx index 45f9920..70d41f4 100644 --- a/UPP/MDK-ARM/UPP.uvprojx +++ b/UPP/MDK-ARM/UPP.uvprojx @@ -1122,11 +1122,11 @@ 0 1 1 - 4101 + 4096 1 BIN\UL2CM3.DLL - + "" () diff --git a/UPP/UPP.ioc b/UPP/UPP.ioc index 322dd2f..5d60256 100644 --- a/UPP/UPP.ioc +++ b/UPP/UPP.ioc @@ -488,7 +488,7 @@ TIM2.OCMode_2=TIM_OCMODE_TIMING TIM2.OCMode_3=TIM_OCMODE_TIMING TIM3.IPParameters=TIM_MasterSlaveMode,TIM_MasterOutputTrigger TIM3.TIM_MasterOutputTrigger=TIM_TRGO_UPDATE -TIM3.TIM_MasterSlaveMode=TIM_MASTERSLAVEMODE_ENABLE +TIM3.TIM_MasterSlaveMode=TIM_MASTERSLAVEMODE_DISABLE TIM5.IPParameters=Prescaler TIM5.Prescaler=90-1 TIM8.Channel-PWM\ Generation3\ CH3=TIM_CHANNEL_3