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;