cancel
Showing results for 
Search instead for 
Did you mean: 

RESOLVED: Changing TIM PWM pulse width on the fly

selmesal
Associate II
Posted on October 14, 2016 at 01:13

Hello, 

I am using STM32F4 Discovery board (with STM32F407VGTx) with the latest HAL libraries. 

I am interested in varying PWM pulse width (duty ratio) in a while loop. 

Looking at MX_TIM3_Init function (also attached below), I see that sConfigOC.Pulse can be varied to change the pulse width. 

Can I simply do the following to vary the pulse width:

while(1)

 

{

 

  HAL_Delay(1000);

 

  sConfigOC.Pulse = 100;

 

  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);

 

 

  HAL_Delay(1000);

 

  sConfigOC.Pulse = 400;

 

  HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2);

 

 

}

//Here is the MX_TIM3_Init section:

static void MX_TIM3_Init(void)

{

  TIM_ClockConfigTypeDef sClockSourceConfig;

  TIM_MasterConfigTypeDef sMasterConfig;

  TIM_OC_InitTypeDef sConfigOC;

  htim3.Instance = TIM3;

  htim3.Init.Prescaler = 83;

  htim3.Init.CounterMode = TIM_COUNTERMODE_UP;

  htim3.Init.Period = 1350;

  htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

  if (HAL_TIM_Base_Init(&htim3) != HAL_OK)

  {

    Error_Handler();

  }

  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;

  if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)

  {

    Error_Handler();

  }

  if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)

  {

    Error_Handler();

  }

  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;

  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;

  if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)

  {

    Error_Handler();

  }

  sConfigOC.OCMode = TIM_OCMODE_PWM1;

  sConfigOC.Pulse = 100;

  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;

  sConfigOC.OCFastMode = TIM_OCFAST_ENABLE;

  if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)

  {

    Error_Handler();

  }

  HAL_TIM_MspPostInit(&htim3);

}
2 REPLIES 2
Walid FTITI_O
Senior II
Posted on October 14, 2016 at 12:19

Hi Sel,

Try to do the update into interrput and not in the while loop.

You can change these on the fly :

/* update the pulse value*/
TIM3->CCR1 = (Period * dutyCycle);

The new values will not take effect until the next update event (UEV).

To avoid a writing delay to the CCR1 register which can be the origin of a glitch, you should ensure that you have enabled the output compare preload OC1PE. In that way,Read/Write operations access the preloadregister, and TIMx_CCR1 preload value is loaded in the active register at each update event (UEV).

/* Enable the output compare 1 Preload */
TIM1->CCMR1 |= TIM_CCMR1_OC1PE;

-Hannibal-

This worked fine for me! Thanks!