I think if you add a value to the TMR0 instead of overwriting it you can minimise the error, which presumeably comes from the write being several cycles into the ISR. Alternatively you might resynchronise by adding the residual value of TMR0 to the PC and then having a long string of NOPs. I believe this technique was raised in an early appnote as an alternative to interrupts. It would leave the PC and TMR0 in step so that your ISR code would execute at exactly the right time at the expense of an intel-like interrupt latency. If a prescaler is used I think it is difficult to see how to get rid of the error absolutely as the prescaler gets cleared by writing anything at all to TMR0. To get rid of the error you would need to synchronise to the prescaler, in order that the counts lost when the prescaler was cleared were the same every time. I guess you might try something like first roughly synchronising: X1 BTFSS TMR0,0 GOTO X1 ;TMR0 BIT0 IS NOW KNOWN TO BE SET then synchronising to 2 cycles accuracy. BTFSS TMR0,0 GOTO X2 BTFSS TMR0,0 GOTO X2 BTFSS TMR0,0 GOTO X2 BTFSS TMR0,0 GOTO X2 ;REPEAT PRESCALER/2 TIMES, or insert padding code before the tests. ;THIS NEARLY SYNCHRONISES, BUT WE MIGHT STILL BE ;ONE CYCLE OUT ;BOTTOM BIT OF TMR0 NOW CLEAR X2 ;INSERT N CYCLES OF PADDING CODE BTFSS TMR0,0;IF BOTTOM BIT OF TMR0 IS STILL CLEAR THEN ;WE DETECTED IT EARLY AND SHOULD INSERT ;1 CYCLE DELAY GOTO X3 X3 Without playing with the simulator a lot I cannot tell you what N needs to be, the aim is to reach the last test just before or just after the last transition so we first determine roughly when the transition will occur, then trap it more and more accurately. I think this code might still lose cycles if the bottom bit toggled from set to clear immediately after the first test instruction but I hope you can see the idea and see how to tighten it up. Alternatively you might find it easier to implement a 'postscaler' in software. Personally I think the TMR0 interrupt is not very usefull for generating acurately timed interrupts. If the interrupt is never masked in the main program I presume the uncertainty in the interrupt is only one cycle, which could be corrected by checking when bit TMR0,0 becomes set again, knowing that it could only set on one of two program cycles, corresponding to two locations in the ISR. Can you wear having polls at periodic locations in your main loop, because I think the simplest way to greater timer period accuracy can be achieved by maintaining a TMR0 shadow, which is compared with the TMR0 value, then when (TMR0-shadow) mod256 is positive then execute your 'ISR' code and add an increment to the shadow to set when the next call should occur. By not writing to TMR0 ever the prescalar is left to free-run, so though there will be errors in the call timing they will not accumulate. Oliver. ----- Original Message ----- From: w. v. ooijen / f. hanneman To: Sent: Sunday, August 13, 2000 5:55 PM Subject: [PIC]: TMR0 update dead time > I try to get my 16F84 interrupt routine called at a certain interval, with > 0 cumulative error. The interval is not 256 * the instruction rate (but for > instance N * times, N < 256), so I must update TMR0 inside the interrupt > routine. My first attempt was to set TMR0 to a fixed value, but that does > not work because the interrupt latency varies depending on the instruction > being executed. Now I add a fixed delta to TMR0, but I do no find > sufficient information in the 16F84 datasheet to calculate this delta. > Emperically I come up with ( 5 - N ), which would mean that the update of > TMR0 causes it to miss 5 increments. > > Q1: Can this magical value somehow be derived from the datasheets? > > Q2: Would this value be the same when I use a prescaler factor other than > 1? > > Wouter > > -- > http://www.piclist.com hint: To leave the PICList > mailto:piclist-unsubscribe-request@mitvma.mit.edu > -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu