cancel
Showing results for 
Search instead for 
Did you mean: 

PWM output high when duty cycle is 0 [STM32G474RET]

Riccardo Franceschetto
Associate III

Hi, i'm implementing a PWM signal using STM32, the problem i'm facing is that when i set the duty cycle of the pulse to zero... i get the pin to stay high, even if i disable the timer associated with the PWM output.

This are my setting:

RiccardoFranceschetto_2-1729155164355.png

My APB2 Bus is set to 170 MHz, i scaled that down to 1 Mhz with prescaler then to 100Hz with ARR.

This is the timer init function :

 

 

static void MX_TIM5_Init(void)
{

  /* USER CODE BEGIN TIM5_Init 0 */

  /* USER CODE END TIM5_Init 0 */

  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_OC_InitTypeDef sConfigOC = {0};

  /* USER CODE BEGIN TIM5_Init 1 */

  /* USER CODE END TIM5_Init 1 */
  htim5.Instance = TIM5;
  htim5.Init.Prescaler = 170-1;
  htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim5.Init.Period = 9999;
  htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
  {
    Error_Handler();
  }
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim5, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_TIM_PWM_Init(&htim5) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
  sConfigOC.Pulse = 0;
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  if (HAL_TIM_PWM_ConfigChannel(&htim5, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
  {
    Error_Handler();
  }
  __HAL_TIM_DISABLE_OCxPRELOAD(&htim5, TIM_CHANNEL_3);
  /* USER CODE BEGIN TIM5_Init 2 */

  /* USER CODE END TIM5_Init 2 */
  HAL_TIM_MspPostInit(&htim5);

}

 

 

I want to have a minimum of 100 ms for 1% of the duty cycle, the value of SetPower is 1/100, so i calculate the CCR3 value as follows:

 

 

Compare_register = (SetPower*(htim5.Init.Period+1))/100; // CCR3
TIM5->CCR3 = Compare_register;

 

 

 

i'm shutting of the timer when the SetPower value is at zero.

In debugging monitoring the htim5.ChannelState[2], i see it busy when is outputting signal with duty>0 then ready when duty = 0;

My question is why the channel stays high when the timer is stopped.

1 ACCEPTED SOLUTION

Accepted Solutions
Sarra.S
ST Employee

Hello @Riccardo Franceschetto,

When you set the duty cycle to zero, the output compare register (CCR) is set to zero, which means the PWM signal will not generate any pulses, but the output can remain in a high state depending on the configuration of the output compare mode.

You are usingTIM_OCMODE_PWM1, so the output is set high when the counter is less than the compare value and set low when the counter is equal to or greater than the compare value. If the compare value is zero, the output will remain high which is the case

Try to manually set the the output pin to low when the duty cycle is zero

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

View solution in original post

6 REPLIES 6
Sarra.S
ST Employee

Hello @Riccardo Franceschetto,

When you set the duty cycle to zero, the output compare register (CCR) is set to zero, which means the PWM signal will not generate any pulses, but the output can remain in a high state depending on the configuration of the output compare mode.

You are usingTIM_OCMODE_PWM1, so the output is set high when the counter is less than the compare value and set low when the counter is equal to or greater than the compare value. If the compare value is zero, the output will remain high which is the case

Try to manually set the the output pin to low when the duty cycle is zero

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Thanks, but why the pin stays high even if the timer is stopped?

Sarra.S
ST Employee

When you stop the timer, the last state of the GPIO pin is retained, which in your case is high

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

So you suggest to stop the timer and reset the state of the gpio pin, right?

Thanks for the insights.

Sarra.S
ST Employee

yes, I suggest to modify the Compare register calculation: 

When the duty cycle is zero, stop the timer and manually set the GPIO pin to low

When the duty cycle is non-zero, start the timer and configure the GPIO pin for PWM output

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I cant use the classic HAL_GPIO_WritePin(LOOP_EN_micro_GPIO_Port,LOOP_EN_micro_Pin , GPIO_PIN_RESET)  right?

LOOP_EN_micro is the label i gave to the TIM5_CH3 in the IOC configurator.