In his reply of Sat, 14 Mar 1998 14:59:19 -0500 Mike Keitz commented: >On Fri, 13 Mar 1998 23:31:42 -0500 Frank McKenney >writes: >>My first thought was that the loss of the prescaler when I re-loaded >>TMR0 was causing (mildly) erratic timing, so I descreased the >>prescaler size. down from 128 to 32. Worst I could lose would be 32 >>Osc/4 clocks, right? Well, using a five-bit prescale counter made the >>distortion _worse_! >This type of uncertainty can be minimized by always resetting the timer >at the same point in the ISR. If the timer interrupt is the only >interrupt, the timer register will be zero and the prescaler a constant >value (probably 3 or 4) when the first instruction in the ISR is >executed. If the time delay from the interrupt to resetting the timer is >always the same, then the number of cycles lost from the prescaler will >also be always the same. Thus the timing will be consistent, but not >necessarily exact unless a further analysis is done to make sure that the >timer is written only when the prescaler is zero. Mike, Thank you for the reminder-of-the-obvious about the prescaler always being (near) zero at the start of the ISR. It's embarassing to admit I hadn't thought about that part of it (;-). At least I have some degree of control over that particular end of the code. Trouble is, if I'm going to implement a general-purpose timer queue, a timer event could be scheduled from _any_ point in the code. Are there only the two choices, then: 1) Ignore the prescaler, and restrict my "timer queue" to events which can live with ther resulting "jitter" (whose magnitude will depend on the prescaler size), or 2) Clean up my ISR to make sure all paths to the TMR0 re-load instruction have the same length, AND put a "busy wait" loop in the Enqueue routine to wait for TMR0 bit 0 to change (ensuring the prescalar is at-or-near-to-0 when I update TMR0). Two odd items which may have some bearing on this... Per the 16F8x PDF file, When {the prescaler is} assigned to the Timer0 Module, all instructions (e.g., CLRF 1, MOVWF 1, BSF 1,x ....etc.) will clear the prescaler. When assigned to WDT, a CLRWDT instruction will clear the prescaler along with the Watchdog Timer. Oddity 1: The MPLab simulator does not set its displayed 'prescaler' value back to 0 when a value is stored into TMR0. Oddity 2: In the MicroChip AppNote 555 (interrupt-driven serial I/0) code, the CLRWDT instruction is used _following_ a store into TMR0 - which should have just set the prescaler back to 0. Item (1) could just be a bug in MPLab, and (2) could be a result of the author of the code misreading that section of the 16F8x PDF file regarding switching the prescaler from TMR0 to the WDT, or the reverse. But I thought I'd bring them up to see if anyone can confirm this. Frank McKenney / OS/2 Advisor (OS2BBS) McKenney Associates / Richmond, Virginia / (804) 320-4887 Internet: rrs0059@ibm.net / TalkLink: WZ01123