• Working clock example using 32K watch crystal

    Looked all over trying to find an example with a second crystal connected to the TIMER1 overflow. This example uses the earlier 18F452 version of the Olimex PIC-WEB board. Ran the clock for a day without gaining or loosing a second! Lots of places where I was not sure what to do. Comments are welcome.
    Regards
    Tim C
    Code:
    ' Name        : TMR1CLK.pbp
    ' Target PIC  : PIC18F452 or similar 18F types
    ' Hardware    : PIC-WEB ver A board with added LCD
    ' Oscillator  : 10MHz crystal. You May have to modify default 18F452 fuses for > 4Mhz
    ' Resolution  : Expect to get +- 5sec/day or better
    ' Description : PicBasic Pro program using external 32K watch xtal and Timer1
    ' interrupt for a real-time clock.
    ' Origional ver from: http://melabs.com/resources/samples/18f/tmr1clk18.htm  
    '
    DEFINE      OSC 10          ' We're using a 10MHz oscillator
    DEFINE      LOADER_USED 1   ' Boot-Loader is being used
    Define        INTHAND myint    ' Define interrupt handler
    Symbol        LED_0 = PORTD.5
    symbol        BUTTON_0 = PORTB.0
    
    wsave        VAR BYTE bankA system   ' Saves W
    ssave        VAR BYTE bankA system   ' Saves STATUS
    
    seconds        VAR BYTE bankA  ' variables within myint must be in bank 0.
    minutes        VAR Byte      ' Elapsed minutes
    hours        var byte
    
    ' LCD config
    Define  LCD_DREG  PORTD
    Define  LCD_DBIT  0
    Define  LCD_RSREG PORTE
    Define  LCD_RSBIT 0
    Define  LCD_EREG  PORTE
    Define  LCD_EBIT  1
    
       ADCON1 = 7          ' Set PORTA and PORTE for digital operation
       Low PORTE.2         ' Enable the LCD
    
       Pause 150           ' Pause to allow LCD to initialize
       LCDOut $fe,1        ' Clear LCD
    
        hours = 2
        minutes = 23       ' Pre Set time here then add seconds to clock using button
        seconds = 0
    
        T1CON.7=0    ' 8 Bit r/w (16 bit seems to cause problems)
        T1CON.5=0    ' Part 1 of 1:1 prescale
        T1CON.4=0    ' Part 2 pf 1:1 prescale
        T1CON.3=1    ' turn on the low freq clock osc
        T1CON.2=1    ' Do not Sync low Freq clock with main clock
        T1CON.1=1    ' use 32Khz xtal as the Timer1 source
        T1CON.0=1    ' enable Timer1
            
        PIE1 = $01         ' Enable TMR1 overflow interrupt
        INTCON  = $C0      ' Finally Enable global interrupt and peripheral interrupts
    
       GoTo mainloop          ' jump over the interrupt handler and sub
    
       ' Assembly language interrupt handler
       ' simplified by Bruce
    @myint                  ; create myint label
       TMR1H.7=1            ' Set TMR1 high bit for 1 second overflows
       seconds = seconds+1  ' Increment seconds
       PIR1.0=0             ' Clear TMR1 int flag
       @ retfie  FAST       ; Return with 'auto restore' of WREG, STATUS and BSR
    
    ' Subroutine to update the time variables
    get_time:
    
        if seconds > 59 then
            seconds = seconds - 60    ' better then making seconds=0
            minutes = minutes + 1
            if minutes > 59 then
                minutes = 0
                hours = hours + 1
                if hours > 12 then    ' simple 12 hour clock format
                    hours = 1
                endif
            endif
        endif      
    
    Return
    
    mainloop:
    
        GoSub get_time      ' Update minutes and seconds
        TOGGLE LED_0
    
        LCDOut $fe,2,"Time: ",DEC hours, ":", DEC2 minutes, ":", DEC2 seconds, "   "
    
        Pause 300           ' Pause to see LED blink. Also help with debounce
        if button_0 = 0 then
            LCDOut $fe,$C0,"+1s "
            seconds = seconds + 1
            else
            LCDOut $fe,$C0,"     "
        endif
        GoTo mainloop       ' Repeat main loop
    
       End
    This article was originally published in forum thread: Working clock example using 32K watch crystal started by timc View original post