After letting it run for a while it's not as dead on as I thought.
Now it's running on a breadboard and crystals are not too happy when they are not well isolated.
I wonder if it's that or something else that's happening.
Here's the code in case anyone ever needs it.
-----------------------------------------------------------------------------
' Version 1.0.0
' Timer.bas
' Test for using an external 32.768Khz oscillator with TIMR0
' by Michael J. Pawlowsky
' Nov 10, 2003
DEFINE __16F628
Include "modedefs.bas"
' Define Oscillator Speed
DEFINE OSC 20
' Set transmit register to transmitter enabled
DEFINE HSER_TXSTA 20h
' Set baud rate
DEFINE HSER_BAUD 9600
' Set the port directions
' 0=output 1=input
TRISA=%00010000 ' Set PORTA A.4 input for oscillator
TRISB=%00000000 ' Set PortB
wsave var byte $20 SYSTEM '$20 Save location for the W register if in bank0
wsave1 var byte $A0 SYSTEM ' Save location for the W register if in bank1
wsave2 var byte $120 SYSTEM ' Save location for the W register if in bank2
ssave var byte Bank0 SYSTEM ' Save location for the STATUS register
psave var byte Bank0 SYSTEM ' Save location for the PCLATH register
INTF var INTCON.1 ' External Interrupt pn RB0/INT
T0IE var INTCON.5 ' TMR0 Overflow Interrupt Enable
T0IF var INTCON.2 ' TMR0 Overflow Interrupt Flag
GIE var INTCON.7 ' Global Interrupt Enable
PS0 var OPTION_REG.0 ' Prescaler division bit-0
PS1 var OPTION_REG.1 ' Prescaler division bit-0
PS2 var OPTION_REG.2 ' Prescaler division bit-0
PSA var OPTION_REG.3 ' Prescaler Assignment (1= assigned to WDT)
T0CS var OPTION_REG.5 ' Timer0 Clock Source Selec
T0SE var OPTION_REG.4 '
hour var byte ' Holds the hours value (0-23)
minute var byte ' Holds the minutes value (0-59)
second var byte ' Holds the seconds value (0-59)
ticks var byte ' Holds the pieces of 1/100th of seconds value (0-59)
flag var bit ' Flag
GOTO Init ' Jump over interrupt routine
' Define interrupt handler
define INTHAND myint
' Assembly language interrupt handler
asm
; Save W, STATUS and PCLATH registers
myint movwf wsave
swapf STATUS, W
clrf STATUS
movwf ssave
movf PCLATH, W
movwf psave
btfss INTCON, T0IF ; Look to see if we have a TIMR0 overflow
goto EndInt ; If not goto EndInt
incf _Ticks ; Increment the TICKS variable
cjbe _Ticks,#127,Clock_Exit ; Have we reached a second yet?
; One second has elasped so update the time variables
clrf _Ticks ; Reset TICKS
incf _Second ; and increment Second
bsf _flag ; set the flag so we update the time
Second cjb _Second,#60,Minute ; Have we reached a minute yet?
clrf _Second ; YES! so reset Seconds
incf _Minute ; and increment Minutes
Minute cjb _Minute,#100,Clock_Exit ; Have we reached an 100 minutes yet?
clrf _Minute ; YES! so reset MINUTES
Clock_Exit bcf INTCON,T0IF ; Clear the TMR0 overflow flag
goto EndInt
EndInt
; Restore PCLATH, STATUS and W registers
movf psave, W
movwf PCLATH
swapf ssave, W
movwf STATUS
swapf wsave, F
swapf wsave, W
retfie
endasm
Init:
Minute=0
Second=0
cSecond=0
Ticks=0
GIE=0 ' Turn off global interrupts
While GIE=1:GIE=0:Wend ' Make sure they are off
PSA=1 ' Assign the prescaler to WDT at 1:1
PS0=0 ' Set the prescaler
PS1=0 ' to increment TMR0
PS2=0 ' every 1 instruction cycle
T0CS=1 ' Assign TMR0 clock to to transition on RA4
T0SE=0 ' Inc on low to high
TMR0=0 ' Clear TMR0 initially
T0IE=1 ' Enable TMR0 overflow interrupt
GIE=1 ' Enable global interrupts
Main:
IF flag = 1 THEN
HSEROUT [0, dec2 Minute, ":", dec2 Second, 13]
Flag = 0
ENDIF
GOTO Main
----------------------------
I'll attach the oscillator circuit as well.
I use a SN74HC04 since I didn't have a 4069.
Let me know if you are able to get it accurate over several hours and how you did it. So far I've been using RTCs for my apps that require accurate timing but I would like it if I could save some pins at times.
Regards,
Mike
Bookmarks