A 24h timer using the zero-error algorithm on Timer0

2014-05-08
2014-05-10
  • Jacques Nilo

    Jacques Nilo - 2014-05-08
    ; This program display a 24h timer on a 2x16 LCD.
    ; It implements the zero-error 1 sec algorithm from Roman Black using Timer0
    ; See: http://www.romanblack.com/one_sec.htm
    ;
    ; This GCBasic version is derived from:
    ; http://www.sfcompiler.co.uk/wiki/pmwiki.php?n=SwordfishUser.SoftRTC
    ;
    ; JN May 2014
    ;
    ;Chip Settings
    ;#chip 16F1508,8       'Does not work with 16F1508. OSCCON redefined in init sub 
    #chip 16F690,8         'Used with Real PIC simulator
    
    ;Defines (Constants)
    #define LCD_IO 4
    #define LCD_RS PORTB.6
    #define LCD_NO_RW
    #define LCD_Enable PORTB.5
    #define LCD_DB4 PORTC.0
    #define LCD_DB5 PORTC.1
    #define LCD_DB6 PORTC.2
    #define LCD_DB7 PORTC.3
    
    On Interrupt Timer0Overflow Call IncCounter
    
    Dim OneSecond,Cyc_Counter As Long                            ') These are the
    Dim T0Load as byte alias Cyc_Counter                         ') 3 key
    Dim Countdown as word Alias Cyc_Counter_U,Cyc_Counter_H      ') lines !
    Dim hrs,mins,secs as byte
    Dim update As Bit
    
    OneSecond = 2000000-2           ' 1sec = 8MHZ/4 - TMR0 startup adjustment
    ;
    ; The following routine is called after each Timer0 overflow
    ;
    sub IncCounter
       Countdown --
       If Countdown = 0 Then
          Cyc_Counter = OneSecond   ' reload timer
          TMR0 = TMR0 + T0Load      ' include additional TMR0 counts
          If STATUS.0 = 0 Then
             Countdown ++           'if no carry increment "countdown" counter once
          End If
          set update on             ' flag to update clock output
       End If
    End Sub
    ;
    ; Initialization
    ;
    Sub Initialize()
    CLS
    secs = 0
    mins = 0
    hrs = 0
    Cyc_Counter = OneSecond
    set update off
    OPTION_REG = 0b00001000       'PSA on so no prescaler on Timer0
    INTCON = 0b10100000           'GIE on, T0IE on (turn interrupts on)
    ; Following statement only needed for 16F1508
    ;OSCCON = 0b01110000           'Insure running at 8Mhz with internal osc on 1508
    TMR0 = 0                      'Timer0 set to 0
    End Sub
    ;
    ; Display a 24H timer on a 2x16 LCD display. Format is HHhMMmSSs
    ;
    Sub Clock24()
        secs ++
        If secs = 60 Then            'Check each tally for rollover
           secs = 0
           mins ++
           If mins = 60 Then
              mins = 0
              hrs ++
              If hrs = 24 Then
                 hrs = 0
              End If
           End If
        End If
        locate 1,0
        Print pad0(hrs)+"h"
        Locate 1,3
        Print pad0(mins)+"m"
        Locate 1,6
        Print pad0(secs)+"s"
        set update off
    End Sub
    ;
    ; Does what it is named after :-)
    ;
    function pad0(in var) as string
      if var < 10 then
        pad0="0"+str(var)
      else
        pad0=str(var)
      end if
    end Function
    ;
    ; Main Program
    ;
    Initialize
    Do
      if update then
        Clock24
      end if
    Loop
    
     
    Last edit: Jacques Nilo 2014-05-19
  • Anonymous - 2014-05-09

    Thanks! I'm looking forward to playing with this, timekeeping being one of my hobbies.

     
  • Jacques Nilo

    Jacques Nilo - 2014-05-10

    I am also discovering the fascinating world of timers :-)
    I changed the code of my initial post to replace the 16F1508 by a more traditional 16F690 in order to avoid the OSCCON compile problem with this chip. I then compiled the stuff, imported the Hex file into real pic simulator, initialized a virtual LCD screen with the code ports setup (RS=PORTB,PIN6 / E=PORTB,PIN5 / D4=PORTC,PIN0 ...) and run. Et voila ! Here is the result and I was then able to check my clock against the one of my PC...

     
    Last edit: Jacques Nilo 2014-05-10
  • Chuck Hellebuyck

    Timers can be really interesting to work with.
    Recognize though that when you run it in the simulator it's using the PC clock as the time base so they should match up. When you run it on an actual PIC it will be less accurate over time due to the crystal accuracy.

     

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks