cancel
Showing results for 
Search instead for 
Did you mean: 

How to generate two PWM with 180Deg phase shift with STM32F30303 advance timer

mukesh
Associate
Posted on May 14, 2013 at 10:26

Hello All,

I am very new to STM32F303 device. I want to generate two PWM from Advance timer TIM1 or TIM8, with same frequency, Same duty cycle but 180deg phase shift. 

Can any one help me out to configure the timer or help me out how i can generate the same as required. 

I will appreciate your replies.

Regards

Mukesh

#stm32f303 #phase-shifted-pwm
4 REPLIES 4
Posted on May 14, 2013 at 11:07

There are perhaps a couple of ways of doing this. Given they share a common synchronous clock source you can develop/control a phase relationship via the TIMx->CNT registers. If the frequency isn't too high you could also use the Update interrupt to alternate the firing of each, which would permit the signal to be generated by two channels of the same timer.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
frankfrank956
Associate III
Posted on May 14, 2013 at 12:59

Don't TIM1 and TIM8 offer complementary outputs already. 

Section 

16.3.14   in the Reference Manual D02258 Rev 2:

''

The advanced-control timers (TIM1/TIM8) can output two complementary signals andmanage the switching-off and the switching-on instants of the outputs. ''

Posted on May 14, 2013 at 17:08

I'm not sure that complementary and 180-degree phase shift mean the same thing.

0690X00000602liQAA.jpg

There may be a slick way of doing this, but would like to see how others might solve it.

So say Period has 100 ticks. A & B have a 180-degree phase shift.

A ON for 40 ticks, OFF for 60 ticks.

B OFF for 50 ticks, ON for 40 ticks, OFF for 10 ticks.

Repeat

I can solve this with PWM and interrupts, but it might be solvable with complementary signals and dead time, and ideally without software intervention. I played with it, but it's not my problem.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
david
Associate II
Posted on May 16, 2013 at 08:24

I'm investigating something similar.

I wanted two signals 180 degrees apart with deadtime AND individually controllable dutycycles. Just using the complementary outputs would solve the first part but you can't control the duty cycles individually using the complementary signal.

The solution I came up with for my project is using TIM1_CH1 and TIM2_CH2 and as long as we don't use longer duty cycles than 50% we're golden. But we've lost some of the safety functions from using the complemntary outputs :( I'm still not completely convinced it isn't doable with the complimentary outputs...)

The way I set it up is i set the counter mode to Center-aligned mode 3 (CMS[1:0]=11 in TIM1_CR1). And then use PWM mode 1 for TIM1_CH1 (OC1M = 0110 in TIM1_CCMR1) and PWM mode 2 for TIM1_CH2 (OC2M = 0111). Now they'll share the same frequency and if you use the same pulse length in TIM1_CCR1 and TIM1_CCR2 they´ll have the same duty cycle as well.

Here's some copy paste:

    TIM_TimeBaseStructure.TIM_Prescaler = 0;

    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned3;

    TIM_TimeBaseStructure.TIM_Period = TimerPeriod;

    TIM_TimeBaseStructure.TIM_ClockDivision = 0;

    TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

    

    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;

    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

    TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;

    TIM_OCInitStructure.TIM_Pulse = Channel1Pulse;

    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

    TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;

    TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;

    TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;

    

    TIM_OC1Init(TIM1, &TIM_OCInitStructure);

    

    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;

    TIM_OCInitStructure.TIM_Pulse = Channel2Pulse;

    

    TIM_OC2Init(TIM1, &TIM_OCInitStructure);