cancel
Showing results for 
Search instead for 
Did you mean: 

PWM with phase shift on STM32 F410 using CUBEMX

RJha.1
Associate II

Hi I want to generate two PWM having phase shift between them. I am using stm32f410 and cubemx as platform. Could anyone please help.

17 REPLIES 17

I want duty cycle 50%.

RJha.1
Associate II

Thank you for comments. Could you please elaborate how to configure the registers step wise. I am new at this platform.

For 50% duty, simply set both channels to Output Compare / Toggle mode, and set the respective CCRx registers to values apart the required phase shift.

Note, that Toggle means one edge per timer period, so you need to set time period to half of the required PWM period.

This probably can be clicked on CubeMX, maybe only the CCRx registered would need to be set manually.

JW

Thank you so much, its working now. I really appreciate your comments.

I implemented your solution and it works for a fixed phase shift, independently of its value. The begins when I change the phase shift over time. Frequently the phase swithces from the value I want to its exact complement (if X is the shift I want, 180 - X would be the complement). Is there a safe way of changing the phase shift whithout turning off the timer?

I think I found the solution to my problem on the reference manual. I just had to enable the "Output compare preload" option on both channels I am using.

tech_andy
Associate

I have found a way to do this on one advanced timer with variable duty. If anyone is interested. it works on stm32f1 and stm32f4 not tried on other mcu

set one channel to pwm ch# the other to pwm ch#n (i have used ch1 and ch2n also ch1 and ch3n both worked)

set counter mode to Centre Aligned Mode1

set repitition counter to 2 (one for each channel is how i think that works but it works!)

brk state disable

brk polarity high

brk and dead time disable,disable,disable and off

set first channel polarity high the other low, then in software calculate the overflow

uint8_t T_1_duty = 1-50; //percent duty

 

HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_#);

HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_#);

(do calculation for overflow)

 

T1_CH#_ccr = (uint16_t)( T_1_overflow * T_1_duty / 100);

T1_CH#_ccr = (uint16_t)(T_1_overflow * (100-T_1_duty) / 100);

 

this works with 180 because we are counting up and down in centre aligned and the second channel is inverted and so is the on time there are about 3 other ways to get same results i think, by changing polarity , pwm1 pwm2 and using ch# instead of ch#n but this is where i first ended up so i stuck with it.

hope this helps someone, It took me months to figure out, but got help from a lot of

"search engineering" but quite simple really looking from outside the box or from the box inverted lol! Good Luck and God Bless!

 

Andy

RLD
Associate III

Hi
I have implemented it with one timer as you suggested. But in my application i need to change the frequency on the run, i.e. also the compare value to keep the 50% duty cycle. When updating the values, I stop the timer and then restart it. Now I have the problem you predicted that the polarity is swapping. When do I have to change the values and restart the timer so that this doesn't happen?