James, I was wondering for many times why is very difficult to obtain a long time accurate clock even using 32768 or multiply Xtal. The answer is on code but not only. External temperature affect dramatic the xtal stability. It's imperative to use an external trimpot circuitry and to measure & adjust the Xtal frequency at value you take in computation. For code I'm not an expert but I've made a 16x84 web clock collection from you may inspire at http://www.geocities.com/vsurducan/pic.htm Also Jinx ( Joe Colquitt ) is an expert in clock's... One of my precious clock have Xtal thermostated at about 50...60 C and works in harsh environement: external temperatures between -20C and +45C Vasile On Tue, 20 Feb 2001, James wrote: > I am programming an interrupt service for 16F84A which provides a time base in units of seconds. My project is to make . . . yet another clock, but this "time" using a 4.000 MHZ xtal, which is not the most natural choice, but offers some > challenge, maybe more than I thought. Have not yet produced accurate time :-( and don't know why. Off by about 1 to 2 percent. > > Me thinking is thus: > > (1) XTAL is 4.000MHZ > > (2) Instruction cycle is therefore 4.000/4 = 1.000 MHZ > > (3) Need to divide 1.000 MHZ by 250, then by 250 again, then by 16 to get 1.000 second cycle rate. 1000000/(250*250*16) = 1 cycle/second > > (4) Must "preload" TMR0 with literal 6 so it will have a cyclic period of 250 (256-6). But wait, must compensate by loading TMR0 with 6+2 = 8 because the timer increment is latent for > 2 instruction cycles after a write to TMR0 (see data sheet) > > (5) In the same isr, set up a register "clocked" that decrements upon every TMR0 overflow. And every time that register underflows to zero, it is to be preloaded with 249 to give it a period of 250. > > (6) The final divide by 16 is done by picking off the desired bit of another register "clocked_2" that is decremented each time "clocked" underflows. The "picked off" bit is written to port in the "main" loop to wink an LED (not shown > below) > > (7) The timer prescaler was not used, it offers no help in this case. Therefore the prescaler was tossed (assigned) to the dog. > > Here is my humble and most unworthy interrupt routine: > ;**************************************************************** > isr: ORG h'0004' ;interrupt service routine invoked each time TMR0 overflows 255 > > movlw d'8' ;preload TMR0 with 8 (8-2 dead cycles=6?) > > movwf TMR0 ;write preload to timer (want cycle of 250) > > decfsz clocked, 1 ;decrement clocked_2 and preload clocked each time TMR0=zero > > goto cont ;skipped on clocked=0 > > movlw d'249' > movwf clocked ;preload clocked with 249 (250 cyclic) > > decf clocked_2, 1 ;decrement clocked_2 > > cont: bcf intcon,TOIF ;clear Timer Overflow Interrupt Flag TOIF > > retfie > ;*************************************************************** > > Seems to me that this should work, and it does run, but not accurately. What might I be missing? Maybe someone can point me to some .asm code example that shows writing to the timer, including the necessary 2 instruction cycle > compensation. > > THX! > James > > -- > http://www.piclist.com hint: To leave the PICList > mailto:piclist-unsubscribe-request@mitvma.mit.edu > > -- http://www.piclist.com hint: The list server can filter out subtopics (like ads or off topics) for you. See http://www.piclist.com/#topics