View Full Version : Real Time Clock
  
I have created a simple clock program which uses the following settings:
External Osc = 4mhz xtal (1000000 operations per second)
Tmr0 = 250
Prescaler = 32
Counter (my variable) = 125
I use Disbale and resume as instructed in the help files 
My counter is incremented each time the timer and prescaler trip over to 0. This mathematically gives exactly 1.0000 second per as a time base.
However, each time I run this code, it is out by as much as 1 second per minute.
Can any one suggest why I get a varience of such a magnitude. Perhaps show mw a reliable time kleepting function or code.
Thanks for any help rendered.
Original
- 17th March 2003, 18:05
Read this site for some explainations:  http://www.romanblack.com/one_sec.htm
I have looked at the sie for Roman Black but no good.
I have checked his code and found that he uses a simple count to tack a little bit onto the end of a second every 4 clocks. This works with the asm code but does not translate into picbasic without the same amount of error.
Thanks anyway.
Maybe I just need to use assembler only and forget the picbasic stuff.
Hi Bob I will see you later with a working code.
From Aaron ;-)
I have created a simple clock program which uses the following settings:
External Osc = 4mhz xtal (1000000 operations per second)
Tmr0 = 250
Prescaler = 32
Counter (my variable) = 125
I use Disbale and resume as instructed in the help files 
My counter is incremented each time the timer and prescaler trip over to 0. This mathematically gives exactly 1.0000 second per as a time base.
However, each time I run this code, it is out by as much as 1 second per minute.
Can any one suggest why I get a varience of such a magnitude. Perhaps show mw a reliable time kleepting function or code.
Thanks for any help rendered.
FADI984
- 29th May 2012, 01:02
In real time application ,the picbasic pro not good...becuse we cant calculate the time exactly in this cases the assemply will be better..
AvionicsMaster1
- 30th May 2012, 15:16
Why won't DT interrupts work?  I don't really understand all the code but it's fairly simple to plug in values to get any time base you'd like.
Just my 2 pennies here but I'd use at least 100 Hz and count pulses until you get to a second.  From what I've read that further reduces timing errors by averaging the error over time.
Best regards
m_flfl
- 2nd June 2012, 05:45
if you want very good accuracy you can use ds 1302 or ds1307 rtc time ic
m_flfl
- 2nd June 2012, 05:52
but you can try this code
' LCD clock program using On Interrupt
'  Uses TMR0 and prescaler.  Watchdog Timer should be
'  set to off at program time and Nap and Sleep should not be used.
'  Buttons may be used to set hours and minutes
Define  LCD_DREG        PORTD   ' Define LCD connections
Define  LCD_DBIT        4
Define  LCD_RSREG       PORTE
Define  LCD_RSBIT       0
Define  LCD_EREG        PORTE
Define  LCD_EBIT        1
hour    var     byte    ' Define hour variable
dhour   var     byte    ' Define display hour variable
minute  var     byte    ' Define minute variable
second  var     byte    ' Define second variable
ticks   var     byte    ' Define pieces of seconds variable
update  var     byte    ' Define variable to indicate update of LCD
i       var     byte    ' Debounce loop variable
        ADCON1 = 7      ' PORTA and E digital
        Low PORTE.2     ' LCD R/W low = write
        Pause 100       ' Wait for LCD to startup
        hour = 0        ' Set initial time to 00:00:00
        minute = 0
        second = 0
        ticks = 0
        update = 1      ' Force first display
' Set TMR0 to interrupt every 16.384 milliseconds
        OPTION_REG = $55        ' Set TMR0 configuration and enable PORTB pullups
        INTCON = $a0            ' Enable TMR0 interrupts
        On Interrupt Goto tickint
' Main program loop - in this case, it only updates the LCD with the time
mainloop:
        PORTB = 0       ' PORTB lines low to read buttons
        TRISB = $f0     ' Enable all buttons
        ' Check any button pressed to set time
        If PORTB.7 = 0 Then decmin
        If PORTB.6 = 0 Then incmin      ' Last 2 buttons set minute
        If PORTB.5 = 0 Then dechr
        If PORTB.4 = 0 Then inchr       ' First 2 buttons set hour
        ' Check for time to update screen
chkup:  If update = 1 Then
                Lcdout $fe, 1   ' Clear screen
                ' Display time as hh:mm:ss
                dhour = hour    ' Change hour 0 to 12
                If (hour // 12) = 0 Then
                        dhour = dhour + 12
                Endif
                ' Check for AM or PM
                If hour < 12 Then
                        Lcdout dec2 dhour, ":", dec2 minute, ":", dec2 second, " AM"
                Else
                        Lcdout dec2 (dhour - 12), ":", dec2 minute, ":", dec2 second, " PM"
                Endif
                update = 0      ' Screen updated
        Endif
        Goto mainloop   ' Do it all forever
' Increment minutes
incmin: minute = minute + 1
        If minute >= 60 Then
                minute = 0
        Endif
        Goto debounce
' Increment hours
inchr:  hour = hour + 1
        If hour >= 24 Then
                hour = 0
        Endif
        Goto debounce
' Decrement minutes
decmin: minute = minute - 1
        If minute >= 60 Then
                minute = 59
        Endif
        Goto debounce
' Decrement hours
dechr:  hour = hour - 1
        If hour >= 24 Then
                hour = 23
        Endif
' Debounce and delay for 250ms
debounce: For i = 1 to 25
        Pause 10        ' 10ms at a time so no interrupts are lost
        Next i
        update = 1      ' Set to update screen
        Goto chkup
' Interrupt routine to handle each timer tick
        disable         ' Disable interrupts during interrupt handler
tickint: ticks = ticks + 1      ' Count pieces of seconds
        If ticks < 61 Then tiexit       ' 61 ticks per second (16.384ms per tick)
' One second elasped - update time
        ticks = 0
        second = second + 1
        If second >= 60 Then
                second = 0
                minute = minute + 1
                If minute >= 60 Then
                        minute = 0
                        hour = hour + 1
                        If hour >= 24 Then
                                hour = 0
                        Endif
                Endif
        Endif
        update = 1      ' Set to update LCD      
tiexit: INTCON.2 = 0    ' Reset timer interrupt flag     
        Resume
        End
 
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.