cancel
Showing results for 
Search instead for 
Did you mean: 

PWM problem

oe
Associate II
Posted on September 28, 2009 at 09:26

PWM problem

7 REPLIES 7
oe
Associate II
Posted on May 17, 2011 at 13:24

I'm triing to get a PWM from tim 3 channel1 on PC6. But I can't get it to work. I'm clearly missing somthing. Do anyone have a hint? Any clock I have missed??

//Configure PC.6 as output push-pull

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC, &GPIO_InitStructure);

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

TIM_OCInitTypeDef TIM_OCInitStructure;

// TIM3 clock enable

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

// Enable the TIM3 CH1 Pins Software Remapping

GPIO_PinRemapConfig(GPIO_FullRemap_TIM3, ENABLE);

// AFIO clocks

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

// Time base configuration

TIM_TimeBaseStructure.TIM_Period = 999;

TIM_TimeBaseStructure.TIM_Prescaler = 0;

TIM_TimeBaseStructure.TIM_ClockDivision = 0;

TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

// PWM Mode configuration: Channel1

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_Channel = TIM_Channel_1;

TIM_OCInitStructure.TIM_Pulse = 0;

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OCInit(TIM3, &TIM_OCInitStructure);

TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);

TIM_ARRPreloadConfig(TIM3, ENABLE);

// TIM3 enable counter

TIM_Cmd(TIM3, ENABLE);

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_Channel = TIM_Channel_1;

TIM_OCInitStructure.TIM_Pulse = 100; //Ratio

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OCInit(TIM3, &TIM_OCInitStructure);

Thanks!

smart
Associate II
Posted on May 17, 2011 at 13:24

why are you re initializing the timer again with these lines you have already done that one time you dont need to define which one is correct and put everything before you enable the counter not after that.

Other than that code looks Ok

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

TIM_OCInitStructure.TIM_Channel = TIM_Channel_1;

TIM_OCInitStructure.TIM_Pulse = 100; //Ratio

TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

TIM_OCInit(TIM3, &TIM_OCInitStructure);

mohith
Associate II
Posted on May 17, 2011 at 13:24

What 'smart' said is right, you don't need to re-initialize the output channel... this is how I would do it.

Code:

void InitTheWholeTimer()

{

//Enable clocks to the desired modules

{

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,

ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO,

ENABLE);

}

//Initialise the GPIO

{

GPIO_InitTypeDef stGPIOInit;

stGPIOInit.GPIO_Mode = GPIO_Mode_AF_PP;

stGPIOInit.GPIO_Pin = GPIO_Pin_6;

stGPIOInit.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC,

&stGPIOInit);

}

//Pin remap

{

GPIO_PinRemapConfig(GPIO_FullRemap_TIM3,

ENABLE);

//I don't really trust the above function. So... if it still don't work

/*AFIO->MAPR |= AFIO_MAPR_TIM3_REMAP_FULLREMAP;*/

}

//Initialise time-base

//Lets say we need a 150Khz square wave with 40% duty cycle

//My APB1 is running at 36MHz

//Hence value for period should be

// period = ((2 * APB1) / (prescaler * frequency) - 1)

// = ((2 * 36,000,000) / (prescaler * 150,000) - 1)

//

//I would divide the timer clock by 32 without having to

//sacrifice the precision in duty cycle. Hence

// period = (72,000,000 / (32 * 150,000) - 1)

// = (15 - 1) = 14

//

//Theoretically, lower the clock, lesser the power consumption!

{

TIM_TimeBaseInitTypeDef stTimebase;

stTimebase.TIM_ClockDivision = TIM_CKD_DIV1; //0

stTimebase.TIM_CounterMode = TIM_CounterMode_Up;

stTimebase.TIM_Period = 14;

stTimebase.TIM_Prescaler = 31;

TIM_TimeBaseInit(TIM3,

&stTimebase);

}

//Initialise output channel

{

TIM_OCInitTypeDef stOCInit;

stOCInit.TIM_OCMode = TIM_OCMode_PWM1;

stOCInit.TIM_OCPolarity = TIM_OCPolarity_High;

stOCInit.TIM_OutputState = ENABLE;

stOCInit.TIM_Pulse = 6; //15 * 40 / 100

TIM_OC1Init(TIM3,

&stOCInit);

}

//Start the timer (and get the waveform)

TIM_Cmd(TIM3,

ENABLE);

}

I am not quite sure about the preload configuration, but that may be the one causing you trouble!

mohith
Associate II
Posted on May 17, 2011 at 13:24

Plus you were doing the pin remap first and then enabling the clock to AFIO module, shouldn't enabling the clock be the first one to appear?

oe
Associate II
Posted on May 17, 2011 at 13:24

Thanks for the feedback. But unfourtunaly it have not resolved my problems... Mohith I have tested your code, but it have the same problem as mine...

If I check the timer in my debuger, I can see that it's counting, and I can alse see in the AFIO_MARP register that the pin remap is active.

Any ideas??

tomas23
Associate II
Posted on May 17, 2011 at 13:24

What about the

TIM_InitStructure.TIM_OutputState = TIM_OutputState_Enable; ?

Is the I2S2 switched off?

oe
Associate II
Posted on May 17, 2011 at 13:24

Tank you for youre inputs.

It turned out to be a hardware problem, on my other evabord it worked fine...