Hi, > > From: Mark K Sullivan > > > Note: when a new value is loaded into TMR0, there is a 2-cycle latency > before the counter starts updating again. Thus for a 154-cycle loop, > load TMR0 with 256+2-154 = 104. As Microchip notes in the data sheet > this will compensate for the latency. I have used this technique to > generate exact 100us loops with no jitter. You will still have jitter of 3 clocks if you sample or (I guess) 1 clock if you interrupt due to the occasional goto 2 cycle instruction but if you use the and method you will have long term absolute accuracy as the current value is used for setting the new timing point. > Another important note: do not merely load TMR0 with a new value, since > the actual timings then become dependent on the number of cycles executed > in the interrupt routine before the TMR0 reload (i.e. you will have to > count cycles). It's a matter of taste, but I prefer to ADDWF a constant > to TMR0 since it is then independent of interrupt latency etc. Use the > following since it worked for me with a PIC16C84: > CYCLES equ 154 > ... > movlw 259-CYCLES > addwf TMR0,f > > The desired number of cycles are subtracted from 259 to compute the > amount by which to bump the clock forward. As I mentioned on this list > way back, there is a discrepancy between the 259 constant versus the > expected 258. 259 is required (at least in the '84), implying that the > device actually has a 3-cycle latency, not 2 as the doc would have > it). I get different results with MPLAB-SIM and the 16C84 silicon by a count of one, I erad about this problem and erroneously thought that it had been fixed in the version I downloaded a few weeks later so if you have to get 1 cycle accuracy just check if your measured error is or the same magnitude as one change in your count value and adjust it (if you were using the simulator to count cycles). Also the Add to TMR0 might be responsible fot the extra cycle as it might read the timer at phase 1, and the timer might get incremented but the old value is used for the Add instruction and then you loose the extra tick when you write the TMR0 value back. Also remember that If you use the prescaler it will be cleared when you write to TMR0 and you cannot find out what the value was and cannot correct for the lost sub-counts. SO do not write to the TMR0 unless you have no prescaler if you want 1 clock long term accuracy. > At 32768Hz, 154 cycles is 601.56125ms. The 600ms required is quite > extraordinary (why not use 500ms since it can be generated exactly?). > If this is indeed required, one way I have used to generate timings > at frequencies which are not simple divisions of the clock frequency > is to generate 'corrections' every now and again. In this example, > since the clock is running 'slow' at 601.6ms, every few times through > the loop the timer should be cut short i.e. use loop delay of 153 > cycles = 597.65625ms. Find the smallest integer constants A and B > such that (A+B)*600 = A*601.56125 + B*597.65625. If A and/or B are too > large, pick different loop times. Ideally, one of A or B should be > 1 since this simplifies the loop logic. > > [Anyone got a good algorithm for finding A and B?] Microsoft Excel does a good job with the solver tool :-) I have put up a calculator on my web site, have a look and let me know, PIC web page coming soon with all sorts of usefull information. http://www.ip.co.za/people/kalle/files/delayc.xls You will need Microsoft Excel or similar. Cheers -- Kalle Pihlajasaari kalle@data.co.za Interface Products Box 15775, Doornfontein, 2028, South Africa +27 (11) 402-7750 Fax: +27 (11) 402-7751