AnsweredAssumed Answered

PWM for PB0 not firing, stm32f051

Question asked by blesener.daniel on Jan 4, 2017
Latest reply on Jan 5, 2017 by blesener.daniel

I am not sure why the following code is not working. I have used it before for a different pin, but I believe my modifications would allow this to work? I am running the code on the stm32f051 discovery board using uvision5 with kiel. 

 

void init_pwm(void)
{

GPIO_InitTypeDef GPIO_InitStructure;

/* GPIOA, GPIOB and GPIOE Clocks enable */
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB, ENABLE);

/* GPIOA Configuration: Channel 1, 2, 3, 4 and Channel 1N as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOB, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOB, GPIO_Pin_0, GPIO_AF_1);

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

//These vars are inited in the PWM timer section because the must be initalized rior to the running the PWM
//If we do this in the variable init it is easy to forget to setup the pwm after the variable
TimerPeriod = (pclk / 600 ) - 1;


// Compute CCR1 value to generate a duty cycle at 50% for channel 1 and 1N
phasea_duty = (uint16_t) (((uint32_t) 5 * (TimerPeriod - 1)) / 10); // 5/10 is 50%

/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 , ENABLE);

/* Time Base configuration */
TIM_TimeBaseStructure.TIM_Prescaler = TIM_ICPSC_DIV2;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1; // Mode 1 means interrupt requests are generated only during down count, mode 2 -> only during up count, mode 3 -> both
TIM_TimeBaseStructure.TIM_Period = TimerPeriod;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

// Channel 1, 2 and 3 Configuration in PWM mode
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // if set ChannelxPulse to 25% of timer period we are at 25% PWM duty
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = phasea_duty; // duty cycle
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

TIM_OC3Init(TIM3, &TIM_OCInitStructure); // init TIM3_CH1

/* TIM3 counter enable */
TIM_Cmd(TIM3, ENABLE);
}

 

I set the pwm with the following function:

//Enter value from 0 thru 1000 corresponding to 0 thru 100%
void set_PWM(int val)
{

val = (uint16_t) (((uint32_t) val * (TimerPeriod - 1) / 1000));
TIM_SetCompare3(TIM3, val ); // use CCR1 value to generate a duty
//TIM_SetCompare1(TIM3, phasea_duty);

return;
}

 

FYI-  pclk = 12000000. 

Outcomes