diff --git a/MATLAB/upp_r2023.slx b/MATLAB/upp_r2023.slx
index 3044084..7899bcf 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 a6b27da..795ebbd 160000
--- a/UPP/AllLibs/MyLibs
+++ b/UPP/AllLibs/MyLibs
@@ -1 +1 @@
-Subproject commit a6b27da4ce1d3cf60a251225beff3e6d0af1193e
+Subproject commit 795ebbd220fd16ba9db4d1c071ed66700c2df928
diff --git a/UPP/Core/Configs/upp_config.h b/UPP/Core/Configs/upp_config.h
index e9301c9..479352a 100644
--- a/UPP/Core/Configs/upp_config.h
+++ b/UPP/Core/Configs/upp_config.h
@@ -27,6 +27,8 @@
#define UPP_DISABLE_PROTECT_BOARDPOWER ///< Отключить проверки питания плат (+24, +5 В)
#define UPP_DISABLE_PROTECT_LOSS_PHASE ///< Отключить проверки на потерянные фазы
+#define ZC_DISABLE_HYSTERESIS_DEBOUNCE ///< Отключить гиситерезис и дребезг на определении перехода через ноль
+
/** //UPP_PARAMS_TEST
* @}
*/
diff --git a/UPP/Core/PowerMonitor/adc_tools.c b/UPP/Core/PowerMonitor/adc_tools.c
index d96f1bb..d48f3bd 100644
--- a/UPP/Core/PowerMonitor/adc_tools.c
+++ b/UPP/Core/PowerMonitor/adc_tools.c
@@ -7,36 +7,49 @@
******************************************************************************/
#include "adc_tools.h"
-static void ADC_EnableAllFilters(ADC_Periodic_t *adc)
-{
- for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
- {
- Filter_Start(&adc->filter[i]);
-// FilterExpInt_Process(&adc->filter[i], adc->Coefs[i].lZero);
- }
-}
static void ADC_InitAllFilters(ADC_Periodic_t *adc)
{
-// Filter_Init(&adc->filter[ADC_CHANNEL_UBA], coefs_biquad_U);
-// Filter_Init(&adc->filter[ADC_CHANNEL_UAC], coefs_biquad_U);
-// Filter_Init(&adc->filter[ADC_CHANNEL_IC], coefs_biquad_I);
-// Filter_Init(&adc->filter[ADC_CHANNEL_IA], coefs_biquad_I);
-// Filter_Init(&adc->filter[ADC_CHANNEL_TEMP1], coefs_biquad_T);
-// Filter_Init(&adc->filter[ADC_CHANNEL_TEMP2], coefs_biquad_T);
- for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
+// FilterBandPassDerivative_Init(&adc->u_fltr[U_AB], (50.0f*PM_FAST_PERIOD_US/1000000), 0.1);
+// FilterBandPassDerivative_Init(&adc->u_fltr[U_CA], (50.0f*PM_FAST_PERIOD_US/1000000), 0.1);
+//
+// FilterMedianInt_Init(&adc->i_fltr[I_C], 5, 2048);
+// FilterMedianInt_Init(&adc->i_fltr[I_A], 5, 2048);
+//
+// FilterLUT_Init(&adc->temp_map[TEMP_1],
+// (float *)adc_temp_quants,
+// (float *)adc_temp_vals,
+// numbof(adc_temp_quants), 1);
+// FilterLUT_Init(&adc->temp_map[TEMP_2],
+// (float *)adc_temp_quants,
+// (float *)adc_temp_vals,
+// numbof(adc_temp_quants), 1);
+
+ // Инициализация фильтров
+ for(int i = 0; i < 2; i++)
{
- Filter_Init(&adc->filter[i], Filter_Initializator);
+ FilterBandPassDerivative_Init(&adc->u_fltr[i], (50.0f*PM_FAST_PERIOD_US/1000000), 0.1);
+ FilterMedianInt_Init(&adc->i_fltr[I_C], 5, 2048);
+ FilterLUT_Init(&adc->temp_map[i],
+ (float *)adc_temp_quants,
+ (float *)adc_temp_vals,
+ numbof(adc_temp_quants), 1);
+ }
+
+ // Запуск фильтров
+ for(int i = 0; i < 2; i++)
+ {
+ Filter_Start(&adc->u_fltr[i]);
+ Filter_Start(&adc->i_fltr[i]);
+ Filter_Start(&adc->temp_map[i]);
}
- FilterLUT_Init(&adc->temp_map[0],
- (float *)adc_temp_quants,
- (float *)adc_temp_vals,
- numbof(adc_temp_quants), 1);
- FilterLUT_Init(&adc->temp_map[1],
- (float *)adc_temp_quants,
- (float *)adc_temp_vals,
- numbof(adc_temp_quants), 1);
}
+
+__STATIC_FORCEINLINE void ADC_FilterRaw(ADC_Periodic_t *adc, int ch_start, int ch_end)
+{
+
+}
+
/**
* @brief Инициализация периодического АЦП.
* @param adc Указатель на кастомный хендл АЦП
@@ -111,17 +124,13 @@ HAL_StatusTypeDef ADC_Start(ADC_Periodic_t *adc, float PeriodUs)
{
return res;
}
- // Запускаем АЦП который будет перекидывать данные в ADC_DMA_Buffer
- res = HAL_ADC_Start_DMA(adc->hadc, (uint32_t*)adc->RawData, 6); // Затем АЦП с DMA
+ // Запускаем АЦП который будет перекидывать данные в DMA буфер RawData
+ res = HAL_ADC_Start_DMA(adc->hadc, (uint32_t*)adc->RawData, 6);
if(res != HAL_OK)
{
return res;
}
- ADC_EnableAllFilters(adc);
- Filter_Start(&adc->temp_map[0]);
- Filter_Start(&adc->temp_map[1]);
-
return res;
}
/**
@@ -139,6 +148,39 @@ HAL_StatusTypeDef ADC_Stop(ADC_Periodic_t *adc)
return HAL_TIM_Base_Stop(adc->htim);
}
+/**
+ * @brief Обновление напряжений АЦП.
+ * @return HAL Status.
+ */
+HAL_StatusTypeDef ADC_UpdateRegular(ADC_Periodic_t *adc)
+{
+ if(assert_upp(adc))
+ return HAL_ERROR;
+
+ ADC_Coefs_t *coefs = adc->Coefs;
+ uint16_t *raw = adc->RawData;
+ float *data = adc->Data;
+
+ // Фильтрация от импульсных шумов каналов токов (напряжения позже фильтруются полосовым фильтром)
+ for(int i = 0; i < 2; i++)
+ {
+ int u_ind = ADC_U_CHANNELS_START + i;
+ int i_ind = ADC_I_CHANNELS_START + i;
+ // заменяем сырые данные на отфильтрованные данные
+ raw[u_ind] = Filter_Process(&adc->u_fltr[i], raw[u_ind]);
+ raw[i_ind] = Filter_Process(&adc->i_fltr[i], raw[i_ind]);
+ }
+
+ // Перерасчеты Напряжений/Токов в единицы измерения
+ for(int i = ADC_U_CHANNELS_START; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
+ {
+ ADC_Coefs_t *coefs = &adc->Coefs[i];
+ data[i] = ((float)(raw[i])-coefs->lZero) * coefs->vMax / (coefs->lMax-coefs->lZero);
+ }
+
+
+ return HAL_OK;
+}
/**
@@ -152,56 +194,12 @@ HAL_StatusTypeDef ADC_UpdateTemperatures(ADC_Periodic_t *adc)
float *data = adc->Data;
uint16_t *raw = adc->RawData;
-
- // Фильтрация от импульсных шумов для каналов напряжения/токов
- for(int i = ADC_TEMP_CHANNELS_START; i < ADC_NUMB_OF_CHANNELS; i++)
- {
- // заменяем сырые данные на отфильтрованные данные
- raw[i] = Filter_Process(&adc->filter[i], raw[i]);
- }
-
+
// Преобразования температуры по таблице
- for (int i = ADC_TEMP_CHANNELS_START; i < ADC_NUMB_OF_CHANNELS; i++)
+ for (int i = ADC_TEMP_CHANNELS_START; i < ADC_TEMP_CHANNELS_END; i++)
{
data[i] = Filter_Process(&adc->temp_map[i-ADC_TEMP_CHANNELS_START], raw[i]);
}
return HAL_OK;
}
-
-/**
- * @brief Обработка АЦП.
- * @return HAL Status.
- * @note Вызывается в DMA2_Stream0_IRQHandler() для обработки напряжений/токов,
- которые пришли по DMA.
- */
-HAL_StatusTypeDef ADC_Handle(ADC_Periodic_t *adc)
-{
- if(assert_upp(adc))
- return HAL_ERROR;
-
- ADC_Coefs_t *coefs = adc->Coefs;
- uint16_t *raw = adc->RawData;
- float *data = adc->Data;
-
- // Фильтрация от импульсных шумов для каналов напряжения/токов
- for(int i = 0; i < ADC_NUMB_OF_CHANNELS; i++)
- {
- // заменяем сырые данные на отфильтрованные данные
- raw[i] = Filter_Process(&adc->filter[i], raw[i]);
- }
-
- // Перерасчеты Напряжений/Токов в единицы измерения
- for(int i = 0; i < ADC_NUMB_OF_REGULAR_CHANNELS; i++)
- {
- ADC_Coefs_t *coefs = &adc->Coefs[i];
- data[i] = ((float)(raw[i])-coefs->lZero) * coefs->vMax / (coefs->lMax-coefs->lZero);
- }
-
-
-// if(Filter_isDataReady(&adc->filter[0]))
-// adc->f.DataReady = 1;
-
-
- return HAL_OK;
-}
diff --git a/UPP/Core/PowerMonitor/adc_tools.h b/UPP/Core/PowerMonitor/adc_tools.h
index 1f51105..1b9d4ec 100644
--- a/UPP/Core/PowerMonitor/adc_tools.h
+++ b/UPP/Core/PowerMonitor/adc_tools.h
@@ -18,12 +18,19 @@
#define ADC_CHANNEL_TEMP2 5
-#define ADC_NUMB_OF_CHANNELS 6
-#define ADC_NUMB_OF_U_CHANNELS 2
-#define ADC_NUMB_OF_I_CHANNELS 2
-#define ADC_NUMB_OF_T_CHANNELS 2
+#define ADC_NUMB_OF_CHANNELS 6
+#define ADC_NUMB_OF_U_CHANNELS 2
+#define ADC_NUMB_OF_I_CHANNELS 2
+#define ADC_NUMB_OF_T_CHANNELS 2
#define ADC_NUMB_OF_REGULAR_CHANNELS (ADC_NUMB_OF_U_CHANNELS+ADC_NUMB_OF_I_CHANNELS)
-#define ADC_TEMP_CHANNELS_START ADC_NUMB_OF_REGULAR_CHANNELS
+
+#define ADC_U_CHANNELS_START 0
+#define ADC_U_CHANNELS_END 1
+#define ADC_I_CHANNELS_START 2
+#define ADC_I_CHANNELS_END 3
+#define ADC_TEMP_CHANNELS_START 4
+#define ADC_TEMP_CHANNELS_END 5
+
#define ADC_TEMPERATURES_QUANTS \
{ 2188, 2197, 2206, 2216, 2226, 2236, 2247, 2259, 2271, 2283, \
@@ -50,11 +57,7 @@
static const float adc_temp_vals[] = ADC_TEMPERATURES;
static const float adc_temp_quants[] = ADC_TEMPERATURES_QUANTS;
-
-#define Filter_t FilterMedianInt_t
-#define Filter_Init FilterMedianInt_Init
-#define Filter_Initializator 5, 2048
-
+
/**
* @brief Коэфициенты канала АЦП для пересчета в единицы измерения
*/
@@ -100,9 +103,9 @@ typedef struct
uint16_t RawData[ADC_NUMB_OF_CHANNELS]; ///< Сырые значения АЦП
ADC_Coefs_t Coefs[ADC_NUMB_OF_REGULAR_CHANNELS]; ///< Коэффициенты @ref ADC_Coefs_t для регулярных каналов (не температуры)
- Filter_t filter[ADC_NUMB_OF_CHANNELS]; ///< Фильтр от шумов АЦП
-
- FilterLUT_t temp_map[2]; ///< Коррекция нелинейности датчиков температуры
+ FilterBandPassDerivative_t u_fltr[ADC_NUMB_OF_U_CHANNELS]; ///< Полосовой Фильтр Напряжений от шумов
+ FilterMedianInt_t i_fltr[ADC_NUMB_OF_I_CHANNELS]; ///< Медианный Фильтр Токов от шумов
+ FilterLUT_t temp_map[ADC_NUMB_OF_T_CHANNELS]; ///< Коррекция нелинейности датчиков температуры
float Data[ADC_NUMB_OF_CHANNELS]; ///< Пересчитанные значения АЦП (в Вольтах/Амперах)
@@ -128,6 +131,6 @@ HAL_StatusTypeDef ADC_Stop(ADC_Periodic_t *adc);
/* Обновление температур АЦП. */
HAL_StatusTypeDef ADC_UpdateTemperatures(ADC_Periodic_t *adc);
/* Обработка АЦП после получения данных. */
-HAL_StatusTypeDef ADC_Handle(ADC_Periodic_t *adc);
+HAL_StatusTypeDef ADC_UpdateRegular(ADC_Periodic_t *adc);
#endif //_ADC_TOOLS_H_
diff --git a/UPP/Core/PowerMonitor/power_monitor.c b/UPP/Core/PowerMonitor/power_monitor.c
index 8706b57..7c82bcc 100644
--- a/UPP/Core/PowerMonitor/power_monitor.c
+++ b/UPP/Core/PowerMonitor/power_monitor.c
@@ -125,6 +125,7 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
/* Расчет всякого для трех фаз отдельно */
float fmean = 0; // средняя частота по трем фазам
+ float umean = 0; // средний напряжение по трем фазам
float imean = 0; // средний ток по трем фазам
float iphase_mean = 0; // средний ток каждой фазы
float uphase_mean = 0; // среднее напряжение каждой фазы
@@ -134,21 +135,15 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
for(int i = 0; i < 3; i++)
{
/* Получение частоты фазы */
- meas->final.F[i] = Filter_Process(&hpm->avg[AVG_FAB+i], ZC_GetFrequency(&hpm->zc, i));
- meas->final.Offset[i] = ZC_GetOffset(&hpm->zc, i);
+ meas->final.F[i] = Filter_Process(&hpm->avg[AVG_F+i], ZC_GetFrequency(&hpm->zc, i));
+// meas->final.Offset[i] = ZC_GetOffset(&hpm->zc, i);
fmean += meas->final.F[i];
/* Средниее напряжение фазы */
-// uphase_mean = fabsf(meas->slow.U[i]);
-// uphase_mean = Filter_Process(&hpm->rms[RMS_UAB+i], uphase_mean);
-// meas->final.U[i] = uphase_mean*PI/2/SQRT2; /*PI/2 - получить амплитудное, SQRT2 - получить действующее */
uphase_mean = Filter_Process(&hpm->rms[RMS_U+i], meas->slow.U[i]);
meas->final.U[i] = Filter_Process(&hpm->rms_exp[RMS_U+i], uphase_mean);
/* Средний ток фазы */
-// iphase_mean = fabsf(meas->slow.I[i]);
-// iphase_mean = Filter_Process(&hpm->rms[RMS_IC+i], iphase_mean)*PI/2;
-// meas->final.I[i] = iphase_mean*PI/2/SQRT2; /*PI/2 - получить амплитудное, SQRT2 - получить действующее */
iphase_mean = Filter_Process(&hpm->rms[RMS_I+i], meas->slow.I[i]);
meas->final.I[i] = Filter_Process(&hpm->rms_exp[RMS_I+i], iphase_mean);
imean += meas->final.I[i];
@@ -159,23 +154,24 @@ void PowerMonitor_SlowCalc(PowerMonitor_t *hpm)
}
/* Получение средней частоты по трем фазам */
meas->final.Fmean = fmean / 3;
- /* Оределение сдвига фаз */
- static uint32_t prev_tick_phase_a = 0;
- if(prev_tick_phase_a != hpm->zc.Channel[0].PeriodStartTime)
- { // Определяем только когда начался новый период фазы A
- prev_tick_phase_a = hpm->zc.Channel[0].PeriodStartTime;
- meas->final.Phase[0] = 0;
- meas->final.Phase[1] = ZC_GetPhaseShift(&hpm->zc, 0, 1);
- meas->final.Phase[2] = ZC_GetPhaseShift(&hpm->zc, 0, 2);
- }
+// /* Оределение сдвига фаз */
+// static uint32_t prev_tick_phase_a = 0;
+// if(prev_tick_phase_a != hpm->zc.Channel[0].PeriodStartTime)
+// { // Определяем только когда начался новый период фазы A
+// prev_tick_phase_a = hpm->zc.Channel[0].PeriodStartTime;
+// meas->final.Phase[0] = 0;
+// meas->final.Phase[1] = ZC_GetPhaseShift(&hpm->zc, 0, 1);
+// meas->final.Phase[2] = ZC_GetPhaseShift(&hpm->zc, 0, 2);
+// }
/* Расчет амплитуд трехфазной сети */
- float uamp = vector_abs_linear_calc(meas->slow.U[U_AB], meas->slow.U[U_CA])/SQRT2; /* SQRT2 - получить действующее */
+// 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]);
+ float uamp = umean / 3;
float iamp = imean / 3;
- meas->final.Uamp = Filter_Process(&hpm->rms_exp[RMS_EXP_U], uamp);
- meas->final.Iamp = Filter_Process(&hpm->rms_exp[RMS_EXP_I], iamp);
+ meas->final.Uamp = uamp;//Filter_Process(&hpm->rms_exp[RMS_EXP_U], uamp);
+ meas->final.Iamp = iamp;//Filter_Process(&hpm->rms_exp[RMS_EXP_I], iamp);
hpm->slow_cnt++;
@@ -197,7 +193,7 @@ void PowerMonitor_FastCalc(PowerMonitor_t *hpm)
PowerMonitor_Measured_t *meas = &hpm->measured;
/* Считываем АЦП с пересчетами и медианой фильтрацией от выбросов */
- ADC_Handle(&hpm->adc);
+ ADC_UpdateRegular(&hpm->adc);
/* Заполняем Напряжения/Токи в о.е. */
float uba_fast = hpm->adc.Data[ADC_CHANNEL_UBA]/u_base;
diff --git a/UPP/Core/PowerMonitor/zero_cross.c b/UPP/Core/PowerMonitor/zero_cross.c
index abf2f2d..b60c8c8 100644
--- a/UPP/Core/PowerMonitor/zero_cross.c
+++ b/UPP/Core/PowerMonitor/zero_cross.c
@@ -103,6 +103,7 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
zc_ch->CurrentValue = value;
+#ifndef ZC_DISABLE_HYSTERESIS_DEBOUNCE
// Фильтрация дребезга
if(zc_ch->DebounceCounter > 0)
{
@@ -144,6 +145,25 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
zc_detected = -1;
}
}
+#else //ZC_DISABLE_HYSTERESIS_DEBOUNCE
+ // Детектирование rising edge (отрицательное -> положительное)
+ if ((zc_ch->LastValue < 0) &&
+ (value > 0))
+ {
+
+ if (zc_ch->EdgeType == ZC_RISING_EDGE || zc_ch->EdgeType == ZC_BOTH_EDGES) {
+ zc_detected = 1;
+ }
+ }
+ // Детектирование falling edge (положительное -> отрицательное)
+ else if ((zc_ch->LastValue > 0) &&
+ (value < 0))
+ {
+ if (zc_ch->EdgeType == ZC_FALLING_EDGE || zc_ch->EdgeType == ZC_BOTH_EDGES) {
+ zc_detected = -1;
+ }
+ }
+#endif //ZC_DISABLE_HYSTERESIS_DEBOUNCE
if(zc_detected)
{
@@ -172,11 +192,15 @@ void ZC_ProcessChannel(ZeroCross_Handle_t *zc, uint8_t channel, float value, uin
zc_ch->CrossCount++;
}
+#ifndef ZC_DISABLE_HYSTERESIS_DEBOUNCE
// Сохраняем текущее значение для следующей итерации в случае если оно не в мертвой зоне
if((value > zc->Config.Hysteresis) || (value < -zc->Config.Hysteresis))
{
zc_ch->LastValue = value;
}
+#else //ZC_DISABLE_HYSTERESIS_DEBOUNCE
+ zc_ch->LastValue = value;
+#endif //ZC_DISABLE_HYSTERESIS_DEBOUNCE
}
/**
diff --git a/UPP/Core/Src/main.c b/UPP/Core/Src/main.c
index e231ae7..1b613b2 100644
--- a/UPP/Core/Src/main.c
+++ b/UPP/Core/Src/main.c
@@ -87,7 +87,7 @@ int main(void)
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
-
+
/* USER CODE BEGIN Init */
#ifndef MATLAB
diff --git a/UPP/Core/UPP/pwm_thyristors.c b/UPP/Core/UPP/pwm_thyristors.c
index e7b0415..ff3c946 100644
--- a/UPP/Core/UPP/pwm_thyristors.c
+++ b/UPP/Core/UPP/pwm_thyristors.c
@@ -323,37 +323,37 @@ static HAL_StatusTypeDef __PWM_SetOutputState(PWM_Channel_t *hCh, uint32_t state
if (hCh->htim == NULL)
return HAL_ERROR;
- uint32_t ch_mode = state;
+ // Если режим уже выставлен
+ if(hCh->CurrentMode == state)
+ {
+ return HAL_OK;
+ }
+
+ hCh->CurrentMode = state;
// выставляем режим каналов
switch(hCh->ChMask)
{
case TIM_CHANNEL_1:
hCh->htim->Instance->CCMR1 &= ~TIM_OCMODE_PWM2;
- hCh->htim->Instance->CCMR1 |= ch_mode;
+ hCh->htim->Instance->CCMR1 |= state;
break;
case TIM_CHANNEL_2:
hCh->htim->Instance->CCMR1 &= ~(TIM_OCMODE_PWM2 << 8);
- hCh->htim->Instance->CCMR1 |= (ch_mode << 8);
+ hCh->htim->Instance->CCMR1 |= (state << 8);
break;
case TIM_CHANNEL_3:
hCh->htim->Instance->CCMR2 &= ~TIM_OCMODE_PWM2;
- hCh->htim->Instance->CCMR2 |= ch_mode;
+ hCh->htim->Instance->CCMR2 |= state;
break;
case TIM_CHANNEL_4:
hCh->htim->Instance->CCMR2 &= ~(TIM_OCMODE_PWM2 << 8);
- hCh->htim->Instance->CCMR2 |= (ch_mode << 8);
+ hCh->htim->Instance->CCMR2 |= (state << 8);
break;
default:
break;
}
- // в последнюю очередь включаем выход. Перед этим настраиваем каналы на ШИМ
- if(state == PWM_ENABLE)
- {
- __HAL_TIM_MOE_ENABLE(hCh->htim);
- }
-
return HAL_OK;
}
diff --git a/UPP/Core/UPP/pwm_thyristors.h b/UPP/Core/UPP/pwm_thyristors.h
index 96a7366..1880c7d 100644
--- a/UPP/Core/UPP/pwm_thyristors.h
+++ b/UPP/Core/UPP/pwm_thyristors.h
@@ -54,6 +54,7 @@ typedef struct {
TIM_HandleTypeDef *htim; ///< указатель на соответствующий TIM (hpwm1 или hpwm2)
uint32_t PulseCnt; ///< Счетчик кол-ва импульсов. Инициализируется из структуры @ref PWM_ThyrConfig_t
uint32_t ChMask; ///< TIM_CHANNEL_x
+ uint32_t CurrentMode; ///< Текущий режим канала
struct {
unsigned Ready:1; ///< Флаг готовности тиристора к работе
diff --git a/UPP/Core/UPP/upp_main.c b/UPP/Core/UPP/upp_main.c
index d0337b9..092f558 100644
--- a/UPP/Core/UPP/upp_main.c
+++ b/UPP/Core/UPP/upp_main.c
@@ -175,6 +175,9 @@ int UPP_While(void)
/*======= Состояние В работе =========*/
case UPP_Work:
+ // Разрешаем выход ШИМ
+ __HAL_TIM_MOE_ENABLE(&hpwm1);
+ __HAL_TIM_MOE_ENABLE(&hpwm2);
// Индикация
UPP_DO.Ready(DISABLE);
UPP_DO.Work(ENABLE);
diff --git a/UPP/MDK-ARM/UPP.uvoptx b/UPP/MDK-ARM/UPP.uvoptx
index c3a2b14..ad710d7 100644
--- a/UPP/MDK-ARM/UPP.uvoptx
+++ b/UPP/MDK-ARM/UPP.uvoptx
@@ -385,7 +385,7 @@
11
1
- \\Debug_F417\../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c\uwTick
+ \\Debug_F417\../Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c\uwTick,0x0A
12
@@ -494,6 +494,21 @@
2
upp,0x0A
+
+ 14
+ 2
+ htim5,0x0A
+
+
+ 15
+ 2
+ htim3,0x0A
+
+
+ 16
+ 2
+ htim5.Instance->CNT-2605346416,0x0A
+
0
@@ -515,7 +530,7 @@
0
0
0
- 1
+ 0
0
0
0