# How to generate 4-channels phase-shifted PWM with 150kHz frequency

I'm designing a PCB on which I need to generate 4 'independent' PWM signals:

• All powered with the same clock
• Fixed frequency, any between 97kHz and 150kHz (ideally)
• At least 256 duty cycle steps (more - better)
• All with independent on and off times
• It is not going to drive leds, so it can't be constant-current solution

At first I was looking at PCA9685. It suits all my needs, except maximum frequency = ~2kHz which is 50 times to low.

Then, I came up with PCA9635, which is fast enough (97kHz max), however it does not allow to set independent on and off times.

My next idea was to use two PCA9635s signals for each channel and put logic gates and flip-flops to Enable output by first signals slope and Disable by seconds. However this is going to be very complex, since edge-triggered S-R latch consists of at least 8 gates.

Right now I also have atmega88pa onboard, so:

• I'm looking for something with digital interface (spi / i2c / ...)
• I can't use built-in timer because their resolution and frequency is too low
• I can't use bit-bang because the uC has other tasks
• ADP1046 or its bigger brother? – winny Sep 13 '16 at 18:53
• What is this for? A small FPGA would be good for this. Or look at PLL chips. – MadHatter Sep 13 '16 at 20:00
• @winny can I use it just like a PWM Generator, nothing more? – peku33 Sep 14 '16 at 10:23
• Sure thing. They are highly flexible. If you want all four channels freely programmable you need the bigger brother in the same series. If you don't plan to switch, phase shift and regulate, you are perhaps better of with a fast MCU or FPGA. They are cheaper but it takes longer to get started. The ADPs are expensive but very easy to get started. – winny Sep 14 '16 at 12:08

So I came up with solutions myself.

Instead of atmega88pa I'm going to use AT90PWM3B. It has 3 'Power Stage Controllers', each implemented as double 12bit high frequency PWM generator, powered by 64MHz PLL.

With 150kHz frequency I'm able to get ~450 steps.

All power stages can be synchronized, each channel has S(et) and R(eset) value.

You could consider a $25MHz$ MSP430 with a B7 timer. (Timer B is pretty fancy and on many parts includes 7 separate capture/compare registers tied to a counter.) I compute that $97kHz \times 256 = 24.832MHz$, so this suggests that it's doable with these MSP430 parts. Some can run on $32MHz$ crystals, as well, which would allow a higher frequency. (Or an external source can supply that clock.) So there is some margin available. (Might be some still faster ones I don't know about right now.) If you go this route, you MUST select a device with a Timer B, as they are the only ones I know about that support four or more capture/compares off of a single clock.

The IAR Kickstart toolchain is completely free and is extremely good, very easy to use, and supports assembly, C, and C++. You would have to keep the code under some limit in size when using C or C++, but there is no limit with assembly coding, with their free version. The assembler is also top-quality, with all the features you could hope for.

But it would be a separate toolchain to add and that does complicate things. You could also hire that software task out -- it is really an easy project, to be honest. I've done it so many times, it's almost doable in my sleep -- it's that easy to achieve.

This would allow a single part to do the job. You'd need to define the communications, of course. But that's minor. There may be a noticeable phase shift, the outputs relative to the driving clock source, if you drive the MSP430 from an external clock source.