2017-01-04 11:25 AM
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.
Solved! Go to Solution.
2017-01-04 01:59 PM
GPIO_Pin_0 = 1 a bit mask
GPIO_PinSource0 = 0 an index
GPIO_PinAFConfig() expects an index between 0 and 15 defining the pin number
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_1);
2017-01-04 12:09 PM
GPIO_PinAFConfig(GPIOB, GPIO_Pin_0, GPIO_AF_1); // Needs to be GPIO_PinSource0 (an index) TIM3_CH3
2017-01-04 01:19 PM
Clive, thanks for the quick response. I am not sure what you are referring to? The datasheet notes that PB0 maps to TIM3_CH3 on page 33 and 37? Note that I am not using the cube to generate code...I am working with some code written a few years ago. I don't think TIM3_CH3 can go into this function. What do you mean by an index?
2017-01-04 01:59 PM
GPIO_Pin_0 = 1 a bit mask
GPIO_PinSource0 = 0 an index
GPIO_PinAFConfig() expects an index between 0 and 15 defining the pin number
GPIO_PinAFConfig(GPIOB, GPIO_PinSource0, GPIO_AF_1);
2017-01-05 09:28 AM
Oh, I see. I thought you were changing syntax because you were referring to a different library. Thanks! That works perfectly.