cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 PWM output high on startup

philpem
Associate II
Posted on March 10, 2014 at 02:52

Hi,

I'm using the PWM (driven by the DMA controller) to run a line of LEDs. These devices interpret a long high pulse as a start of packet. A pull-down resistor keeps the output in a 'safe' state until the I/Os are initialised. Unfortunately when I initialise the timer for PWM (mode 1), the STM32F407VG (on a Discovery board) drives the PWM output high, confusing the LEDs. I can force the line low if I enable the timer, then immediately disable it:

#define PWM_TIMER TIM3
#define TIM_COMPARE_LOW 9
TIM_SetCompare1(PWM_TIMER, TIM_COMPARE_LOW);
TIM_Cmd(PWM_TIMER, ENABLE);
TIM_Cmd(PWM_TIMER, DISABLE);

But this still results in a momentary high glitch between the GPIO initialisation and the PWM bodge above. Is there a better way to do this? I'm also interested if there's a better way to get the clock frequency of TIM3 -- at the moment I'm doing this, which is reliant on the code being updated if/when the stm32f4xx_system.c file is updated:

/* Compute the prescaler value */
RCC_ClocksTypeDef clocks;
RCC_GetClocksFreq(&clocks);
PrescalerValue = (uint16_t) ((clocks.SYSCLK_Frequency / 4) / 24000000) - 1;

Here is my init code, for reference:

#define PWM_TIMER TIM3
#define DMA_STREAM DMA1_Stream2
#define DMA_TCIF DMA_FLAG_TCIF2
#define DMA_CHANNEL DMA_Channel_5
#define DMA_SOURCE TIM_DMA_Update
#define TIM_PERIOD 29
#define TIM_COMPARE_HIGH 18
#define TIM_COMPARE_LOW 9
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStructure;
uint16_t PrescalerValue;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
/* GPIOB Configuration: PWM_TIMER Channel 1 as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_TIM3);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* Compute the prescaler value */
RCC_ClocksTypeDef clocks;
RCC_GetClocksFreq(&clocks);
PrescalerValue = (uint16_t) ((clocks.SYSCLK_Frequency / 4) / 24000000) - 1;
/* Time base configuration */
TIM_TimeBaseStructure.TIM_Period = TIM_PERIOD; 
// 800kHz 
TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(PWM_TIMER, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(PWM_TIMER, &TIM_OCInitStructure);
// PAP: Start up TIM1 so that the PWM output is forced low (it starts out high)
TIM_SetCompare1(PWM_TIMER, TIM_COMPARE_LOW);
TIM_Cmd(PWM_TIMER, ENABLE);
TIM_Cmd(PWM_TIMER, DISABLE);

#stm32f4-pwm-output-high-stuck
2 REPLIES 2
Posted on March 10, 2014 at 03:01

Don't these relate to the state of the pin?

TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // ??

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // ??

You can also choose when to associate the pin with the timer, and when the pin is in GPIO or AF mode. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
philpem
Associate II
Posted on March 10, 2014 at 21:19

TIM_OutputState determines whether the output is enabled or disabled. It sets or clears the CCxNE timer configuration bit for the respective timer.

TIM_OCPolarity determines whether the output is direct-acting or inverted (active-high or active-low -- increasing PWM count increases pulse width or vice versa).

It looks like I might be better off putting the GPIO into normal output mode with the pin state cleared, then assign it to the AF once the timer is configured. It's a bit of a roundabout way to do things (and will need to be documented) but that may be the best option.

Thanks.