cancel
Showing results for 
Search instead for 
Did you mean: 

Proper way to turn off PWM channel

Posted on September 27, 2016 at 13:35

Hello there,

I am using STM32F4 to drive a 3 phase BLDC motor. With this motor when using block driving (or trapezoidal), one of the 3 outputs should always float. What registers should be set exacly in order to turn off one of the 3 PWM channels? Now, I am setting an appropriate bit in the DIER register (TIM1 or 😎 ie. CC1IE, CC2IE or CC3IE. Doing this doesnt seem to turn off the pwm generation synchronously. I need both outputs (main and complementary) to output low state at the very same time in sync with the main timer. Is that possible?

4 REPLIES 4
mark239955_stm1
Associate II
Posted on September 27, 2016 at 13:55

In order to make a GPIO pin float, you would make it an input.  You do this by clearing the bits that control that pin's operating mode in the GPIOx->MODER register.  When you want the pin to become a PWM output again, you set those bits to 0b10 (decimal 2).  The register supports 32-bit accesses so you can simultaneously change the operating mode of any or all of the pins by setting the register contents to some new value.

How well-synchronized the GPIOx->MODER change is to your timebase is a separate problem.  You can do it in a timer interrupt, but that won't necessarily give you acceptable timing consistency if you have other, higher-priority, interrupt sources.

Posted on September 27, 2016 at 14:04

I expressed mysalfe wrong. When I want the channel off, I need both of the PWM inputs (regular and complementary) to be set as output LOW state.

Posted on September 27, 2016 at 14:43

I am using this HAL function in order to stop a certain channel:

/**
* @brief Stops the PWM signal generation in interrupt mode.
* @param htim: pointer to a TIM_HandleTypeDef structure that contains
* the configuration information for TIM module.
* @param Channel: TIM Channels to be disabled.
* This parameter can be one of the following values:
* @arg TIM_CHANNEL_1: TIM Channel 1 selected
* @arg TIM_CHANNEL_2: TIM Channel 2 selected
* @arg TIM_CHANNEL_3: TIM Channel 3 selected
* @arg TIM_CHANNEL_4: TIM Channel 4 selected
* @retval HAL status
*/
HAL_StatusTypeDef HAL_TIM_PWM_Stop_IT (TIM_HandleTypeDef *htim, uint32_t Channel)
{
/* Check the parameters */
assert_param(IS_TIM_CCX_INSTANCE(htim->Instance, Channel));
switch (Channel)
{
case TIM_CHANNEL_1:
{ 
/* Disable the TIM Capture/Compare 1 interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC1);
}
break;
case TIM_CHANNEL_2:
{
/* Disable the TIM Capture/Compare 2 interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC2);
}
break;
case TIM_CHANNEL_3:
{
/* Disable the TIM Capture/Compare 3 interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC3);
}
break;
case TIM_CHANNEL_4:
{
/* Disable the TIM Capture/Compare 4 interrupt */
__HAL_TIM_DISABLE_IT(htim, TIM_IT_CC4);
}
break;
default:
break; 
}
/* Disable the Capture compare channel */
TIM_CCxChannelCmd(htim->Instance, Channel, TIM_CCx_DISABLE);
if(IS_TIM_ADVANCED_INSTANCE(htim->Instance) != RESET) 
{
/* Disable the Main Output */
__HAL_TIM_MOE_DISABLE(htim);
}
/* Disable the Peripheral */
__HAL_TIM_DISABLE(htim);
/* Return function status */
return HAL_OK;
}

I wonder either this is an optimal way.
mark239955_stm1
Associate II
Posted on September 28, 2016 at 10:48

If you set the GPIOx->MODER bitfield for each pin to 0b01, they will become outputs.  You could then write to the GPIOx->BSRR register to clear both output latches, driving both pins low.  Again, they can be restored to PWM operation by setting the MODER bitfields to 0b10 to restore their Alternate Function behaviour.