PWM stop state problem - I want to instantaneously stop a complimentary PWM in a low state F042, timer1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-04-04 10:53 AM
I want to generate bursts of complimetary PWM to drive a half bridge. I have the PWM working fine, with deatime etc... but when I call:
HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);
HAL_TIMEx_PWMN_Stop(&htim1,TIM_CHANNEL_1);
Rather than stopping to a defined state, it goes to (I think) reset state and drifts down to 0V. I want it to pull both lines LOW when I stop the PWM, so that the Half-Bridge goes to floating.
Timer init code is:
static void MX_TIM1_Init(void)
{
TIM_MasterConfigTypeDef sMasterConfig;
TIM_OC_InitTypeDef sConfigOC;
TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
htim1.Instance = TIM1;
htim1.Init.Prescaler = 0;
htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
htim1.Init.Period = 256;
htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim1.Init.RepetitionCounter = 0;
htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 500;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sConfigOC.Pulse = 0;
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
sBreakDeadTimeConfig.DeadTime = 5;
sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_LOW;
sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
HAL_TIM_MspPostInit(&htim1);
}
- Labels:
-
TIM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-04-04 11:37 AM
How about turn the output as output GPIO with low level?
Or short the output with another GPIO which is open drain and force a low level whenever needed?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-04-04 12:16 PM
These would both potentially work, but turning the output to GPIO involves resetting all the pinstates and re-running the init funcitons (slow, tedious...surely there's a better way?)
Shorting the output with a GPIO 1) uses extra GPIO and 2) 1 messup and your chip is dead.
On the Atmel chips (for example) there is a bitmask where you can just write enable alternative function and otherwise it just goes to the state as if the timer was not running PWM.
I tried initialising the pins as GPIO and writing low before initialising the timer, but no luck. As soon as you init the timer PWM, the old GPIO init is essentially dead...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-04-04 12:27 PM
De-initialising the timer is also not an option, I need to keep the other channels running PWM.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-04-04 12:57 PM
> On the Atmel chips (for example) there is a bitmask where you can just write enable alternative function and otherwise it just goes to the state as if the timer was not running PWM.
It's the same in STM32, if you ditch Cube and read the reference manual (GPIOx_MODER).
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2019-04-04 2:02 PM
OK,
So, init()ing as GPIO, then writing GPIO on PA7 and 8 low... Then init()ing timer, then in while(1) loop I put:
HAL_Delay(1);
GPIOA->MODER &= ~0b00000000000000111100000000000000;
GPIOA->MODER |= 0b00000000000000010100000000000000;
HAL_Delay(1);
GPIOA->MODER &= ~0b00000000000000010100000000000000;
GPIOA->MODER |= 0b00000000000000101000000000000000;
I get the desired effect. I think this should scale to the other GPIOs/timer channels.
Cheers Jan!
