cancel
Showing results for 
Search instead for 
Did you mean: 

pin level when disabling pwm

DAlvarez
Associate II

I'm using a general-purpose timer to generate low level pulses, configuring one channel as PWM. The problem is when I disable the channel, the signal goes low, and I want it to remain high.

I played with the OCPolarity and PWM modes 1 and 2, but only take effect when the PWM is running, when disabling the pin always goes low

any suggestion?

MCU STM32F722ZETx (Nucleo F722ZE)

main

  LL_TIM_EnableCounter(TIM9);
  bool active_inactive = false;
  while (1) {
    if (HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin) == GPIO_PIN_SET){
      while(HAL_GPIO_ReadPin(USER_Btn_GPIO_Port, USER_Btn_Pin) == GPIO_PIN_SET);
      if(active_inactive){
        LL_TIM_CC_EnableChannel(TIM9, LL_TIM_CHANNEL_CH1);
        LL_TIM_ClearFlag_UPDATE(TIM9);
        LL_TIM_EnableIT_UPDATE(TIM9);
      }
      else{
        LL_TIM_DisableIT_UPDATE(TIM9);
        LL_TIM_CC_DisableChannel(TIM9, LL_TIM_CHANNEL_CH1);
      }
      active_inactive = !active_inactive;
      HAL_Delay(50);
    }
    HAL_Delay(1);
  }

Configuration generated by cubeMX

/**
  * @brief TIM9 Initialization Function
  * @param None
  * @retval None
  */
static void MX_TIM9_Init(void)
{
 
  /* USER CODE BEGIN TIM9_Init 0 */
 
  /* USER CODE END TIM9_Init 0 */
 
  LL_TIM_InitTypeDef TIM_InitStruct = {0};
  LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
 
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* Peripheral clock enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM9);
 
  /* TIM9 interrupt Init */
  NVIC_SetPriority(TIM1_BRK_TIM9_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
  NVIC_EnableIRQ(TIM1_BRK_TIM9_IRQn);
 
  /* USER CODE BEGIN TIM9_Init 1 */
 
  /* USER CODE END TIM9_Init 1 */
  TIM_InitStruct.Prescaler = 0;
  TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
  TIM_InitStruct.Autoreload = 647;
  TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
  LL_TIM_Init(TIM9, &TIM_InitStruct);
  LL_TIM_DisableARRPreload(TIM9);
  LL_TIM_SetClockSource(TIM9, LL_TIM_CLOCKSOURCE_INTERNAL);
  LL_TIM_OC_EnablePreload(TIM9, LL_TIM_CHANNEL_CH1);
  TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM2;
  TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_DISABLE;
  TIM_OC_InitStruct.OCNState = LL_TIM_OCSTATE_DISABLE;
  TIM_OC_InitStruct.CompareValue = 5;
  TIM_OC_InitStruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;
  LL_TIM_OC_Init(TIM9, LL_TIM_CHANNEL_CH1, &TIM_OC_InitStruct);
  LL_TIM_OC_EnableFast(TIM9, LL_TIM_CHANNEL_CH1);
  /* USER CODE BEGIN TIM9_Init 2 */
 
  /* USER CODE END TIM9_Init 2 */
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOE);
  /**TIM9 GPIO Configuration
  PE5   ------> TIM9_CH1
  */
  GPIO_InitStruct.Pin = LL_GPIO_PIN_5;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  GPIO_InitStruct.Alternate = LL_GPIO_AF_3;
  LL_GPIO_Init(GPIOE, &GPIO_InitStruct);
 
}

4 REPLIES 4
Javier1
Principal

this is a common problem when implementing six steps trapezoidal control for BLDC motors.

If my memory doesnt fail me i ended up doing something like @Antypas.Peter​ said here https://community.st.com/s/question/0D50X00009sW6qlSAC/hal-pwm-stop-with-defined-pin-output

we dont need to firmware by ourselves, lets talk
AScha.3
Chief III

set CH idle state - then you get hi idle

in cube:

0693W00000UnakSQAR.pngmaybe you need setting in break also:

0693W00000Unal1QAB.png...enable off state sel.

If you feel a post has answered your question, please click "Accept as Solution".

Or just switch the given pin to GPIO Out with whatever level you want.

[EDIT] Oh that's the same what Javier suggested above. [/EDIT]

JW

DAlvarez
Associate II

Thanks for the answers. What @AScha.3​ suggests is only for advance timers and I'm using a general purpose one (I'm regrating this, but the PCB is already made)

So I will reconfigure the pin as gpio output and change the level before stopping the timer. Thanks again.