Hi- This is what I had in mind. Thanks Scott for doing a better job than I can! David Scott Dattalo wrote: > On Tue, 3 Sep 2002, Jinx wrote: > > > > I think you can probably do it with an accumulator. Then add in > > > a number, such that you generate a pulse each time the accumulator > > > overflows. The remainders are taken care of automatically > > > > Explain further please > > > > ============================================== > > > > One method I thought of for an F877 is to use Timer1 to generate > > the space and T0CKI + Timer2 to count pulses (using the roll-over > > flags). Presently with the F628 I use Timer1 and simple decrementation / > > testing for the number of pulses. I'm not particularly fussy how it's done > > as long as it's calculable, repeatable and reliable > > 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: > > pw phase > ----------- > 83 1.002427 > 83 2.004855 > 83 3.007283 > 83 4.009711 > 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. > > Scott > > -- > http://www.piclist.com hint: To leave the PICList > mailto:piclist-unsubscribe-request@mitvma.mit.edu -- David Harris OmniPort Home Page: http://www3.telus.net/OmniPort1/ Discussion egroup: http://groups.yahoo.com/group/OmniPort Swiki: http://omniport.swiki.net/1 -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu