EmbeddedRelated.com
Forums

Precision PWM in microcontroller

Started by The Mind Factory INC December 28, 2003
Ville Voipio <vvoipio@kosh.hut.fi> writes:

> I started thinking about this after my earlier post. You are right, > a simple division is just fine. Something like this: > > steps = (accu / incr) + 1; > accu -= steps * incr;
Silly me. Seems that I've already used all brain capacity reserved for this year... Once again... With a few lines of modulo calculations, a much simpler algorithm is revealed. The division can be made beforehand to avoid calculations. rembase = ofvalue % incr; stepbase = ofvalue / incr; where ofvalue is the overflow value of the accumulator. It may be rather handy to choose it so that a single step is, say, 100 uHz. Each interrupt carries the following calculations: OUTPUT = !OUTPUT; rem = rem + rembase; steps = stepbase; if (rem >= incr) { rem = rem - incr; steps = steps + 1; } And that's it. Fast, simple, and can use smaller integers in many cases. (And familiar, see Bresenham :) In practice, the counter can be preloaded with "stepbase" and then adjusted by one when necessary.
> complicated "which octant" thinking. However, I could not find a reason > why it should preserve the duty cycle. By thinking of a graphics analogy, > it is possible to make it go 2:3:2:3:2:3:2:3...
... and this can be avoided by the choice of the overflow value and the increment. The same problems apply to the DDS with certain overflow values and increments, as the algorithm is the same. - Ville -- Ville Voipio, Dr.Tech., M.Sc. (EE)