From 3b0f1fef0539893ece68597b8b3f2589be2fde64 Mon Sep 17 00:00:00 2001 From: cfif Date: Thu, 21 May 2026 11:14:35 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=BB=D0=B0=D1=82=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B0=20V2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Inc/PwmFlagchip.h | 2 ++ Src/PwmFlagchip.c | 75 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 67 insertions(+), 10 deletions(-) diff --git a/Inc/PwmFlagchip.h b/Inc/PwmFlagchip.h index f2da62c..9980d60 100644 --- a/Inc/PwmFlagchip.h +++ b/Inc/PwmFlagchip.h @@ -20,6 +20,8 @@ typedef struct { uint8_t TPU_PWM_CHANNEL; + bool isDisabled; + } tPwmFlagchip; diff --git a/Src/PwmFlagchip.c b/Src/PwmFlagchip.c index 67d32de..a155fe0 100644 --- a/Src/PwmFlagchip.c +++ b/Src/PwmFlagchip.c @@ -7,7 +7,8 @@ void Get_Set_Tpu_PwmCallback(tPwmFlagchip *env) { - if (env->updatePending) { + // Обновляем только если есть запрос и канал не отключен + if ((env->updatePending) && (!env->isDisabled)) { env->etpu_pwmconfig_tbl.u32ActiveTime = env->pendingActiveTime; env->updatePending = false; } @@ -16,6 +17,24 @@ void Get_Set_Tpu_PwmCallback(tPwmFlagchip *env) { env->etpu_pwmconfig_tbl.u32PeriodTime); } + +// Функция для полной остановки ШИМ на канале +static void TPU_StopChannel(uint8_t channel) { + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + // Отключаем выход буфера канала + TPU_E_HWA_EnableChOutputBuf(pTPUE, channel, (bool)false); + // Опционально: устанавливаем выход в безопасное состояние + // (нужно определить, какое состояние безопасно для вашей системы) +} + +// Функция для запуска конкретного канала +static void TPU_StartChannelSpecific(uint8_t channel) { + TPU_E_Type *const pTPUE = TPU_E_BASE_PTRS; + // Включаем выход буфера канала + TPU_E_HWA_EnableChOutputBuf(pTPUE, channel, (bool)true); +} + + void PWM_Initial( tPwmFlagchip *env, bool isDeInit, @@ -26,8 +45,6 @@ void PWM_Initial( TPU_EventCallbackType Bsp_Tpu_PwmCallback, TPU_TCR1OverflowCallbackType Bsp_Tpu_OverflowCallBack) { - //env->q_u32ActiveTime = osMessageQueueNew(1, sizeof(uint32_t), NULL); - env->etpu_pwmconfig_tbl.eTBS1 = TPUE_EQUAL_ONLY_CAPBASE_TCR1_MATCHBASE_TCR1; env->etpu_pwmconfig_tbl.eTBS2 = TPUE_EQUAL_ONLY_CAPBASE_TCR1_MATCHBASE_TCR1; env->etpu_pwmconfig_tbl.bPwmUseTCR1 = (bool) true; @@ -47,7 +64,9 @@ void PWM_Initial( env->etpu_Int_config_tbl.eChTrigType = TPUH_ANY_EVENT_GATED_BY_MSRTSR; env->TPU_PWM_CHANNEL = TPU_PWM_CHANNEL; - + env->isDisabled = false; + env->updatePending = false; + env->pendingActiveTime = 0; if (isDeInit) { TPU_DeInit(); @@ -56,6 +75,8 @@ void PWM_Initial( TPU_PwmModeInit(TPU_PWM_CHANNEL, &env->etpu_pwmconfig_tbl); TPU_InitChannelInterrupt(TPU_PWM_CHANNEL, &env->etpu_Int_config_tbl); + TPU_StopChannel(env->TPU_PWM_CHANNEL); + if (TPU_PWM_CHANNEL <= 7) { NVIC_SetPriority(TPU0_CH0_7_IRQn, TPU_PRIORITY); NVIC_EnableIRQ(TPU0_CH0_7_IRQn); @@ -72,18 +93,40 @@ void PWM_Initial( } -static void vPwmRun(tPwmFlagchip *env) { +static void vPwmAllRun(tPwmFlagchip *env) { TPU_StartChannel(); } static void setActivePercent(tPwmFlagchip *env, uint8_t percent) { uint8_t final_percent; - // Ограничения - if (percent > 90) + // Обработка отключения (0%) + if (percent == 0) { + // Если канал уже отключен, ничего не делаем + if (!env->isDisabled) { + // Отключаем канал ШИМ + TPU_StopChannel(env->TPU_PWM_CHANNEL); + env->isDisabled = true; + } + return; + } + + // Для всех ненулевых значений (1-100) + // Принудительно ограничиваем до 95% максимум + if (percent > 95) { percent = 95; - if (percent < 10) - percent = 5; + } + + // Минимальное значение - 1% (не ниже) + if (percent < 1) { + percent = 1; // Минимальный рабочий процент + } + + // Если был отключен, включаем заново + if (env->isDisabled) { + TPU_StartChannelSpecific(env->TPU_PWM_CHANNEL); + env->isDisabled = false; + } // Для active LOW (bActiveHigh = false) нужна инверсия // 10% → 90%, 20% → 80% и т.д. @@ -95,16 +138,28 @@ static void setActivePercent(tPwmFlagchip *env, uint8_t percent) { // Расчет времени активности в тактах uint32_t activeTime = env->etpu_pwmconfig_tbl.u32PeriodTime * final_percent / 100; + + + // Защита от выхода за пределы + if (activeTime == 0) { + activeTime = 1; // Минимальное значение, чтобы не остановить счетчик + } + if (activeTime >= env->etpu_pwmconfig_tbl.u32PeriodTime) { + activeTime = env->etpu_pwmconfig_tbl.u32PeriodTime - 1; + } + + // Не обновляем напрямую, а ставим флаг env->pendingActiveTime = activeTime; env->updatePending = true; + } tPwmIO vPwmGetIo(tPwmFlagchip *env) { tPwmIO io = { .env = env, - .run = (PwmIOTransaction) vPwmRun, + .run = (PwmIOTransaction) vPwmAllRun, .setActivePercent = (PwmIOTransactionSetActivePercent) setActivePercent }; return io;