180 degree phase shift pwm with variable duty cycle - Page 1
Forum section: electronics / beginners

author: cha1nsaw
author_rank: Newbie
timestamp: September 27, 2019, 06:29:44 pm
content: Hey guys, i'm kinda new to EEVforum, so i think I'll make lots of nooby mistakes. I am doin a two phase buck converter and i have to control it from stm32 (avr is better for me cuz i know it better, but looks like phase shift is impossible on avr atmegas).Honestly, I've no idea which stm32 to choose. So I'm asking for help with phase shift, cuz I've no idea how to realize it properly and which stm32 is needed. Same duty cycle on both pwm channels but it should be from 1% to 99%. Frequency more than 20khz, resolution is not so important. I've tried to research in this question for around a week, but I'm new to stm and can't operate with registers like a god, so it's hard for me to understand this. Thanks in advance

author: fourtytwo42
author_rank: Super Contributor
timestamp: September 27, 2019, 06:57:52 pm
content: I had this very same problem with an STM32F303 that I wanted to use for a digitally controlled half-bridge and to my amazement there much vaunted pwm (that is common to many ARM designs) simply cannot cope with it!I am sorry to say I reverted to using PIC's that have the required flip-flop in there pwm output stages, e.g. PIC24EPxxxMC series.You will also have extreme difficulty accessing functions like this through any kind of hardware abstraction layers so better be prepared for what I understand is now called "bare metal" programming!!

author: cha1nsaw
author_rank: Newbie
timestamp: September 27, 2019, 07:13:24 pm
content: Is there any way to achieve phase shift with external logic? I've seen dflipflop scheme in google, but its mentioned that it works only from 50 to 99 percents of duty cycle, and i understand that cuz it cant afford gaps between pwm fronts, it can only overlap.And if talking about pics, which one is preferred and are there any libraries for standard i2c oled displays and other common stuff?

author: Zero999
author_rank: Super Contributor
timestamp: September 27, 2019, 08:08:29 pm
content: Well if you invert one channel, then it would have a phase shift of 180o, but obviously the duty cycle would be inverted, so can't you simply correct that in software?PWM = 75%CH1 = PWMCH2 = 1-PWMNow CH2 will have a duty cycle of 25% Connect a NOT gate between CH2 and the MOSFET driver, to get it back to 75% but antiphase.No doubt you've thought of a similar scheme before and I've missed something blindingly obvious, since I've never used an MCU to do PWM before.

author: fourtytwo42
author_rank: Super Contributor
timestamp: September 28, 2019, 06:03:32 pm
content: Quote from: Zero999 on September 27, 2019, 08:08:29 pmGood scheme but a tad of deadtime often comes in handyBy the time you add all the bits externally you got more chips than you bargained for unless you go for the expense of an fpga external to the mpu, I know at least one big inverter manufacturer that does just that! Better to start with the right MPU series IMOP that can integrate the lot.

author: Zero999
author_rank: Super Contributor
timestamp: September 28, 2019, 10:28:14 pm
content: Quote from: fourtytwo42 on September 28, 2019, 06:03:32 pmI don't see the need for additional ICs. Choose a dual MOSFET driver, with one channel inverting and the other non-inverting (perhaps the TPS2814?) and the arithmetic can be done in software.http://www.ti.com/lit/ds/symlink/tps2814.pdfAgain, perhaps I've missed something, as I haven't done it before.

author: Ian.M
author_rank: Super Contributor
timestamp: September 28, 2019, 11:02:43 pm
content: Quote from: cha1nsaw on September 27, 2019, 06:29:44 pmIts not impossible on AVR ATmegas with multiple 16 bit counter/timers as they can be synchronised to run in lock-step, either counting identically, or from preloaded offset counts (i.e. phase shifted). See datasheet for GTCCR register TSM and PSRSYNC bits.

author: cha1nsaw
author_rank: Newbie
timestamp: September 29, 2019, 08:12:20 am
content: Thanks for pointing to exact registers! I new i could run two timers with time shift, but i could not find needed registers in datasheet. Now i hope i'll understand how to do it right.

author: cha1nsaw
author_rank: Newbie
timestamp: September 29, 2019, 08:26:40 am
content: Here i've drawn why it won't workMaybe I've mistaken, but this scheme looks inappropriate for me

author: soldar
author_rank: Super Contributor
timestamp: September 29, 2019, 02:12:10 pm
content: I can't download the graphic because my slow internet keeps timing out. It would help if you would edit and compress your graphics.I am attaching the schematic of what I believe to be the same idea. Two signals shifted half cycle. Start with a higher frequency and divide accordingly.

author: cha1nsaw
author_rank: Newbie
timestamp: September 29, 2019, 05:47:58 pm
content: Yeah ofc I've compressed it

author: fourtytwo42
author_rank: Super Contributor
timestamp: October 10, 2019, 07:40:29 am
content: Quote from: cha1nsaw on September 29, 2019, 05:47:58 pmSo now you understand what your looking for at 20Khz you wont be doing it in software! The other element the above schematic does not include is a deadtime generator because it is only working at 50hZ and 50% duty cycle it doesn't need one, again deadtime of a few hundred nS is not realizable in software so you need to find a PWM that incorporates all these features and more in hardware! You will find that your MPU choice is forced by this rather than what you are either familiar with or what your favorite is unless you choose to implement the PWM externally in an FPGA as I suggested before. Other features you will typically need are fault early termination and fault lockout. Some chip designers understand these requirements and some haven't got a clue hence why many PWM's are useless.

author: T3sl4co1l
author_rank: Super Contributor
timestamp: October 10, 2019, 08:43:40 am
content: I made one in discrete parts, seems to work but I haven't done much with it yet -- bit of a back-burner project.General scheme:I forget how this differs from the final version but as you can see, there's a bit more logic here. The timing is quite precise, frequency and phase and dead time are continuously variable (no clock dividers), and it has on-board gate drivers and error amplifiers for PSU application.Here's a power supply using the module (bottom right); there's just a little bit of support circuitry under the module (oh, yeah, actually a bit more than a little, but that's supporting the synchronous rectifier, not required for a basic supply).Hm, it's been two years, I should take that project off the shelf and play with it again.Tim

author: stockvu
author_rank: Newbie
timestamp: June 13, 2023, 12:02:36 am
content: This is an old post but I want to respond because the answer is quite easy to do with MCU's like Uno, Mega2560 and Nano (even a 328 PDIP).Inside these Arduinos are 8 and 16 bit Timers. Timer-1 is free on all of them. Its capable of what you describe using Mode-10 Phase PWM. It has two PWM channels (3 on the Mega) that can be configured to produce 180 degree Phase Shift PWM.Nothing real special is required other than writing some code to change the duty-cycle on the channels. But you do need to figure register values to attain a specific frequency and Mode-10.Channel-A can run as simple PWM while channel-B would run in a Complimentary mode using a mirrored duty-value. (see following image link)For instance Chan-A may get assigned a duty-cycle of 25%. The compliment, Chan-B, would need its duty set for 100-25= 75%. Strange as that sounds, it makes sense when you see it in diagram-form like the below linked Image. The two duty-cyclesalways add to 100%.https://runtimemicro.com/sites/default/files/Forum%20Images/Arduino%20Timer%20Calculator.jpg.EDIT:Sample code for 50 kHz, 180 degree Phase-Shift PWM at the same 25% duty cycle. You can change duty to whatever you need...Code:// Timer-1 16-bit, Mode-10 Phase, Top=ICR// 50,000 Hz Frequency, Clock is 16 MHzTCCR1B = 0x10; // 0001 0000, Disable TimerTCCR1A = 0xB2; // 1011 0010ICR1 = 160-0;OCR1A = (int) (ICR1 * 0.25); // change duty-cycleOCR1B = (int) (ICR1 * 0.75); // change duty-cycleTCNT1=0x0;// UnComment following lines for UNO-NANO Timer-1 Pins// pinMode(9, OUTPUT); // OC1a// pinMode(10, OUTPUT); // OC1b// UnComment following lines for 2560 Timer-1 Pins// pinMode(11, OUTPUT); // OC1a// pinMode(12, OUTPUT); // OC1bTCCR1B |= 1; // Prescale=1, Enable TimerHope that helps someone interested in PSPWM using Arduino...stockvu