Fitting pulses into a time slot
Scott Dattalo email (remove spam text)
On Tue, 3 Sep 2002, Jinx wrote:
The accumulator, or more accurately phase-accumulator, works with the
reciprocal of the IC/pulse ratio.
For example, so far the discussion has been mostly around the number of
Instruction Cycles (IC) per pulse or IC/pulse. Using integer arithmetic
you'll quantize this ratio to an integer. Unfortunately, the tiny error in
the quantization accumulates into a large error after repeated additions.
So the phase accumulator works by keep track of these tiny errors, i.e. it
accumulates the error, and when the accumulated value reachs a threshold
the quantum output is adjusted.
In this particular application you present the example of 1781 pulses in
147465 instruction cycles (the total instructions in 32 ms for your
particular crystal). The instruction cycles per pulse ratio is:
147465/1781 = 82.79
As you noted in the original example, the .79 fractional part is a
nuisance. Now, suppose you look at the reciprocal:
1781/147465 = 0.0120774
You still have a fraction - but let's ignore that for the moment...
Suppose you were able to add 0.0120774 to a variable every instruction
cycle. If the variable (phase accumulator) starts off at zero, then in 82
cycles the count will be 0.99035 and in 83 would be 1.0024. When the phase
accumulator exceeds 1.0, toggle the pulse and subtract 1.0 from the
accumulator. Now the accumulator is 0.0024. Repeat this process. Most
pulses will be 83 instructions wide. However, occasionally the accumulated
error will bias the phase accumulator such that for some iterations the
pulses will be 82 cycles!
In this particular example, the 0.79 remainder in the division of
147465/1781 means that roughly 8 out of 10 pulse will be 83 cycles wide
and 2 out of 10 will be 82 cycles wide. For example, the first few
iterations of the phase accumulator would yield:
82 5.000061 <== shorter pulse
In other words, whenever the fractional portion exceeds 0.012077 you lose
one instruction cycle!
There are a couple of practicle issues here.
- dividing by 147465 (or however many cycles are in 32 ms ) can be
simplified by multiplying by the reciprocal - it's a constant
- Rolling over at "1.0" isn't too useful. It's easier to scale the
numbers so that you rollover at 2^n
- Getting single instruction cycle precision delays is tricky.
(see the PWM code on my web page). If you can use TMR1, then
you could write an interrupt routine that will reload the
period register at every cycle.
http://www.piclist.com hint: To leave the PICList
In reply to: <001801c25313$0623f8e0$369ca7cb@joe>
See also: www.piclist.com/techref/microchip/time.htm?key=time
You must be a member of the
piclist mailing list
(not only a www.piclist.com member) to post to the