PIC clock, help

Thread Starter

warcuz

Joined Jul 10, 2008
7
About PIC, is there a possibility to include a timer(like a clock) inside a PIC so it will know when it will execute a command in specified time. Because Im making a project that is time based, for example : on a specific time of a day
I need the LED to turn ON lets say 8:00AM and when it is 9:30AM the LED would turn off. how could I make the PIC conscious that its 8:00AM to turn the LED ON and 9:30AM to let it turn OFF the LED?

Is it with the use of interrupts??, if you do know some example related to this would you kindly post it?


I understand that the PAUSE command isn't the best answer for my problem.
Im using PIC16F628A
 

Zaraphrax

Joined Mar 21, 2009
49
I have seen people program simple alarm clocks with PICs etc. I tracked down the source for one, you could probably pick the bones out of that for the timing engine. - http://www.metricmind.com/clock/clock.htm (there's a link the the source a bit further down the page).

That should get you started. I don't know whether that will port straight onto your controller, so you might have to make some changes to it before it'll work. Once you've got a simple clock running on it, it'd be pretty easy to setup a comparison condition so the LED is on between x and y and off the rest of the time.
 

joeyla

Joined Nov 14, 2006
2
If you require something with any great accuracy then use something like Dallas DS1302 RTC.

Is more accurate as has 32768Hz external clock (nice and slow).

If micro has internal clock then it is not good enough for time sensitive apps. Clocks will have ratings plus or minus X PPM ( pulses per million ). If you have a 4Mhz external clock then those pulses per million add up and could loose a couple of minutes per day.

Another thought. If only function of PIC is to keep track of time and switch LED then could use 32768Hz crystal to clock the PIC
 
Last edited:

Thread Starter

warcuz

Joined Jul 10, 2008
7
Im using PIC BASIC...is it possible to use interrupts?

and how can I know the time being eaten alone by mg program, I understand that it would definitely affect the result of what I intend to do

thnx
 

spinnaker

Joined Oct 29, 2009
7,830
Im using PIC BASIC...is it possible to use interrupts?

and how can I know the time being eaten alone by mg program, I understand that it would definitely affect the result of what I intend to do

thnx

Yes you can. Check this thread. The sample is in C but you should be able to follow it. It uses an internal clock, you should use an external clock as suggested, but the sample will at least show how to do timer interrupts. You may need to modify it a bit for your particular PIC.
 

Art

Joined Sep 10, 2007
806
PicBasic implementation based on Roman Black's One second timer:

Rich (BB code):
'PROGRAM: EZCLOCK1
' Paul R. Borgmeier, PhD
' Crux analysis & design, LLC
' www.cruxanalysis.com
' June 02, 2005
' Initial Release
'***********************************************************
'DESCRIPTION: This bare bones program demonstrates how to
' create a very simple yet accurate clock without the use of 
' a RTC IC.  
'
' This version of the code displays the time in an HH:MM format
' with a blinking colon - a common serial alphanumeric LCD is
' used for the display (Scott Edwards Electronics BPI-216). Other 
' serial displays should work equally as well.  The code also
' could easily be updated to work with parallel displays since the
' instruction set is essentially the same.  For larger display
' options, GOOGLE SEARCH "Serial LCD 4 Digit"
' 
' This version requires a 4.000 MHz Xtal - accuracy is
' controlled 100% by Xtal tolerance: (schematic is below)
'
' 100ppm tolerance gives < 9 sec/day error
'  50ppm tolerance gives < 5 sec/day error
'  30ppm tolerance gives < 3 sec/day error
'  20ppm tolernace gives < 2 sec/day error
'
'***********************************************************  
'HOW IT WORKS: This clock is based on Roman Black's "Zero-error
' One Second Timer!" (www.romanblack.com) but has been optimized
' for simplicity and implementation using PicBasic Pro. This
' program keeps track of .5 second intervals so that a blinking
' colon can be used to show that the clock is active. On the
' whole second, the time is udated (as needed) and the colon
' turned on. On the half second, the colon is turned off.
'
' The version here makes use of TMRO with a prescaler of 256 and
' manual polling for TMRO overflow (interrupts could easily by
' added if needed).  This makes the TMRO period equal to 65,536
' microseconds(65.536 mSec), which gives the user lots of time to 
' do other stuff as well as update the clock on a serial LCD between
' TMRO overflows.

' Note that although the overall accuracy of the clock is as accurate 
' as the Xtal tolerance, individual seconds are not and vary slightly 
' from second to second - however,the cummulative error of the second
' to second variation appraoches ZERO! Each half second calculated by
' the program is either 0.4588 seconds or 0.5243 seconds in length.
' The program combines these so that the total error approaches zero
' when compared to a perfect timer - the only error left is due to
' crystal tolerance. Note that the longer the program runs, the  more
' accurate the clock becomes.  For example, after 1000 seconds, the
' total error is just 0.0052% (this equates to 52mSec—not bad!). 
'
' The news gets even better. If you cannot live with this accuracy,
' for example in a timer application, once the timer or program has
' been stopped, the error can be determined in software and corrected.
' The correction can be determined from the values of TMRO, HzTimer,
' and Col at the time of interest.  Most will not have to deal with
' this correction because the error approaches zero the longer the
' clock runs anyway.  The value of the error from any second is always
' less than 65.5mSec regardless of the elapsed time.
'
' Black's timer uses three separate byte-sized variables to track the
' instruction counts for one second periods.  His method is fast and
' clever, but requires manually watching and maintaining addition
' overflows and carries between three variables.
'
' With a 4 MHz crystal, 0.5 seconds equals 500,000 instructions (h7A120),
' which is larger than a word-sized variable in PicBasic Pro. The TMRO
' time period used in the code is 65,536 (h10000). The trick used here is
' to divide both the instruction count and timer count by 16 (h10), which
' makes the instruction count trackable in the single word-sized variable,
' HzTimer.
'
' This bare bones program demonstrates how to implement this clock.  

' The program is divided into two sections:
'
'  (1) Input time and display on SMARD4  (@ 9600 baud) using momentary
' push button.
'
'	The User:  
'     	a) Pushes and holds button to set hours (variable HH).
'    	b) Pushes and holds button to set minutes (variable MM).
'     	c) Pushes button to start clock.
'
'  (2) Maintains time display on LCD including colon blink
'
' The user can add code to perform tasks as noted in the code itself. 
' 
' Most of the code below is dedicated to setting the initial time. This
' part of the code is not optimized but works well enough for most
' applications. The actual time keeping code is amazingly short—just about
' 30 lines of code, which includes colon blinking (and maintaining the
' display)!
'
'***********************************************************
'PIC: 12F629
' GP0: SERIAL LCD LINE (I used a SEETRON BPI-216 at 9600 baud)
' GP1: Momentary Push Button direct to GND
' GP2:
' GP3: (MCLR Internal)
' GP4: XTAL 4.0000 Hz (w/tolerance = 30 ppm) w/ cap to GND
' GP5: XTAL 4.0000 Hz (w/tolerance = 30 ppm) w/ cap to GND
'
'         -_-
'   +5V--|   |--GND
'   Xtal-|12F|-- to Serial LCD (at n9600)
'   Xtal-|629|--/ --GND (momentary button direct to GND)
'       -|   |-
'         ---
' (Xtal caps to GND not shown)
'
' CONFIGURATION SETUP
'  Oscillator:          XT
'  Watchdog Timer:      OFF
'  Power up Timer:      OFF
'  Master Clear Enable: Internal
'  Brown Out Detect:    OFF
'  Code Protect:        OFF
'  Data EE Read Protect:OFF
'**********************************************************

CMCON=7                'all digital
GPIO=0
TRISIO=2               'GP1 = input for button 
OPTION_REG=%00000111   'weak pullups on, TMRO prescale = 256
INTCON=0               'interrupts off

HzTimer VAR Word       '1/2 second counter (2 Hz)
       
HH VAR Byte  ' Hours 1-12
MM VAR ByTE  ' Minutes 0-59
SS VAR Byte  ' Seconds 0-59
X VAR Byte   ' temp variable

col VAR Bit  ' colon 1=on, 0=0ff

HzTimer=$7A12        'for 1/2 Sec
HH=0:MM=0:SS=0:col=0 'initial conditions

Pause 1000           'settle Time for Serial LCD

' **************************************************************
'SET INITIAL TIME WITH PUSH BUTTON (PART 1 of Program)

Serout GPIO.0,6,[254,1]
Pause 100
SEROUT GPIO.0,6,[72,72,58,77,77]   'Display HH:MM

WHILE GPIO.1=1    'Wait here until user pushes button
    PAUSE 150
    SEROUT GPIO.0,6,[254,128,72,72]
    PAUSE 150
    SEROUT GPIO.0,6,[254,128,32,32]  
WEND 

SetHH: 'Set hours, HH

HH=HH+1
IF HH=13 THEN
    HH=1
    SEROUT GPIO.0,6,[254,128,32]
ENDIF
IF HH>9 THEN
    X=128
  ELSE
    X=129
ENDIF
SEROUT GPIO.0,6,[254,X,#HH]    
PAUSE 1000
IF GPIO.1=0 THEN SetHH

PAUSE 30

WHILE GPIO.1=1    'Wait here until user pushes button
    PAUSE 150
    SEROUT GPIO.0,6,[254,131,77,77]
    PAUSE 150
    SEROUT GPIO.0,6,[254,131,32,32]  
WEND 

SEROUT GPIO.0,6,[254,131,48]

SETMM: 'Set Minutes, MM

MM=MM+1
IF MM=60 THEN
    MM=0
    SEROUT GPIO.0,6,[254,131,48]
ENDIF
IF MM>9 THEN
    X=131
ELSE
    X=132
ENDIF
SEROUT GPIO.0,6,[254,X,#MM] 
PAUSE 1000
IF GPIO.1 = 0 THEN SetMM

StartLoop: IF GPIO.1=1 THEN StartLoop  'Push to start clock

OPTION_REG.7=1    'Turn off weak pullups
TRISIO.1=0        'Make button pin output
GPIO.1=0          'Set GP1 low
TMR0=0	          'Reset TMRO
INTCON.2= 0       'Clear TMRO overflow flag

' **************************************************************
'TIME KEEPING LOOP (PART 2 of Code)

'Requires variables, HH for Hours 1-12, and MM for minutes 0-59
'(HH and MM manually set above in Part 1; SS & col = 0 from above)

Main:
ClockLoop: IF INTCON.2=0 THEN ClockLoop ' Wait for TMRO overflow
INTCON.2=0 'Clear TMRO overflow flag

HzTimer = HzTimer - $1000  'decrement timer

IF HzTimer<$1000  THEN
    IF Col=1 THEN 'update time'
        SS=SS+1
        IF SS=60 THEN
            SS=0 
            MM=MM+1
            IF MM=60 THEN
                MM=0
                HH=HH+1
                IF HH=13 THEN
                    HH=1
                ENDIF
            ENDIF
            IF HH>9 THEN
                SEROUT GPIO.0,6,[254,128,#HH,58]
            ELSE
                SEROUT GPIO.0,6,[254,128,32,#HH,58]
            ENDIF
            IF MM>9 THEN
                SEROUT GPIO.0,6,[254,131,#MM]
            ELSE
                SEROUT GPIO.0,6,[254,131,48,#MM]
            ENDIF
         ELSE
             Serout GPIO.0,6,[254,130,58]   'colon on
         ENDIF
    ELSE
        Serout GPIO.0,6,[254,130,32]    ' Colon off
    ENDIF
    Col=Col+1
    HzTimer=HzTimer+$7A12
ELSE
    'Do something here but must be less than 65,500 instructions 
    '(e.g., less than 65.5 mSec total time)
ENDIF

GOTO Main
' **************************************************************
END
 

Thread Starter

warcuz

Joined Jul 10, 2008
7
PicBasic implementation based on Roman Black's One second timer:

Rich (BB code):
'PROGRAM: EZCLOCK1
' Paul R. Borgmeier, PhD
' Crux analysis & design, LLC
' www.cruxanalysis.com
' June 02, 2005
' Initial Release
'***********************************************************
'DESCRIPTION: This bare bones program demonstrates how to
' create a very simple yet accurate clock without the use of 
' a RTC IC.  
'
' This version of the code displays the time in an HH:MM format
' with a blinking colon - a common serial alphanumeric LCD is
' used for the display (Scott Edwards Electronics BPI-216). Other 
' serial displays should work equally as well.  The code also
' could easily be updated to work with parallel displays since the
' instruction set is essentially the same.  For larger display
' options, GOOGLE SEARCH "Serial LCD 4 Digit"
' 
' This version requires a 4.000 MHz Xtal - accuracy is
' controlled 100% by Xtal tolerance: (schematic is below)
'
' 100ppm tolerance gives < 9 sec/day error
'  50ppm tolerance gives < 5 sec/day error
'  30ppm tolerance gives < 3 sec/day error
'  20ppm tolernace gives < 2 sec/day error
'
'***********************************************************  
'HOW IT WORKS: This clock is based on Roman Black's "Zero-error
' One Second Timer!" (www.romanblack.com) but has been optimized
' for simplicity and implementation using PicBasic Pro. This
' program keeps track of .5 second intervals so that a blinking
' colon can be used to show that the clock is active. On the
' whole second, the time is udated (as needed) and the colon
' turned on. On the half second, the colon is turned off.
'
' The version here makes use of TMRO with a prescaler of 256 and
' manual polling for TMRO overflow (interrupts could easily by
' added if needed).  This makes the TMRO period equal to 65,536
' microseconds(65.536 mSec), which gives the user lots of time to 
' do other stuff as well as update the clock on a serial LCD between
' TMRO overflows.

' Note that although the overall accuracy of the clock is as accurate 
' as the Xtal tolerance, individual seconds are not and vary slightly 
' from second to second - however,the cummulative error of the second
' to second variation appraoches ZERO! Each half second calculated by
' the program is either 0.4588 seconds or 0.5243 seconds in length.
' The program combines these so that the total error approaches zero
' when compared to a perfect timer - the only error left is due to
' crystal tolerance. Note that the longer the program runs, the  more
' accurate the clock becomes.  For example, after 1000 seconds, the
' total error is just 0.0052% (this equates to 52mSec—not bad!). 
'
' The news gets even better. If you cannot live with this accuracy,
' for example in a timer application, once the timer or program has
' been stopped, the error can be determined in software and corrected.
' The correction can be determined from the values of TMRO, HzTimer,
' and Col at the time of interest.  Most will not have to deal with
' this correction because the error approaches zero the longer the
' clock runs anyway.  The value of the error from any second is always
' less than 65.5mSec regardless of the elapsed time.
'
' Black's timer uses three separate byte-sized variables to track the
' instruction counts for one second periods.  His method is fast and
' clever, but requires manually watching and maintaining addition
' overflows and carries between three variables.
'
' With a 4 MHz crystal, 0.5 seconds equals 500,000 instructions (h7A120),
' which is larger than a word-sized variable in PicBasic Pro. The TMRO
' time period used in the code is 65,536 (h10000). The trick used here is
' to divide both the instruction count and timer count by 16 (h10), which
' makes the instruction count trackable in the single word-sized variable,
' HzTimer.
'
' This bare bones program demonstrates how to implement this clock.  

' The program is divided into two sections:
'
'  (1) Input time and display on SMARD4  (@ 9600 baud) using momentary
' push button.
'
'    The User:  
'         a) Pushes and holds button to set hours (variable HH).
'        b) Pushes and holds button to set minutes (variable MM).
'         c) Pushes button to start clock.
'
'  (2) Maintains time display on LCD including colon blink
'
' The user can add code to perform tasks as noted in the code itself. 
' 
' Most of the code below is dedicated to setting the initial time. This
' part of the code is not optimized but works well enough for most
' applications. The actual time keeping code is amazingly short—just about
' 30 lines of code, which includes colon blinking (and maintaining the
' display)!
'
'***********************************************************
'PIC: 12F629
' GP0: SERIAL LCD LINE (I used a SEETRON BPI-216 at 9600 baud)
' GP1: Momentary Push Button direct to GND
' GP2:
' GP3: (MCLR Internal)
' GP4: XTAL 4.0000 Hz (w/tolerance = 30 ppm) w/ cap to GND
' GP5: XTAL 4.0000 Hz (w/tolerance = 30 ppm) w/ cap to GND
'
'         -_-
'   +5V--|   |--GND
'   Xtal-|12F|-- to Serial LCD (at n9600)
'   Xtal-|629|--/ --GND (momentary button direct to GND)
'       -|   |-
'         ---
' (Xtal caps to GND not shown)
'
' CONFIGURATION SETUP
'  Oscillator:          XT
'  Watchdog Timer:      OFF
'  Power up Timer:      OFF
'  Master Clear Enable: Internal
'  Brown Out Detect:    OFF
'  Code Protect:        OFF
'  Data EE Read Protect:OFF
'**********************************************************

CMCON=7                'all digital
GPIO=0
TRISIO=2               'GP1 = input for button 
OPTION_REG=%00000111   'weak pullups on, TMRO prescale = 256
INTCON=0               'interrupts off

HzTimer VAR Word       '1/2 second counter (2 Hz)
       
HH VAR Byte  ' Hours 1-12
MM VAR ByTE  ' Minutes 0-59
SS VAR Byte  ' Seconds 0-59
X VAR Byte   ' temp variable

col VAR Bit  ' colon 1=on, 0=0ff

HzTimer=$7A12        'for 1/2 Sec
HH=0:MM=0:SS=0:col=0 'initial conditions

Pause 1000           'settle Time for Serial LCD

' **************************************************************
'SET INITIAL TIME WITH PUSH BUTTON (PART 1 of Program)

Serout GPIO.0,6,[254,1]
Pause 100
SEROUT GPIO.0,6,[72,72,58,77,77]   'Display HH:MM

WHILE GPIO.1=1    'Wait here until user pushes button
    PAUSE 150
    SEROUT GPIO.0,6,[254,128,72,72]
    PAUSE 150
    SEROUT GPIO.0,6,[254,128,32,32]  
WEND 

SetHH: 'Set hours, HH

HH=HH+1
IF HH=13 THEN
    HH=1
    SEROUT GPIO.0,6,[254,128,32]
ENDIF
IF HH>9 THEN
    X=128
  ELSE
    X=129
ENDIF
SEROUT GPIO.0,6,[254,X,#HH]    
PAUSE 1000
IF GPIO.1=0 THEN SetHH

PAUSE 30

WHILE GPIO.1=1    'Wait here until user pushes button
    PAUSE 150
    SEROUT GPIO.0,6,[254,131,77,77]
    PAUSE 150
    SEROUT GPIO.0,6,[254,131,32,32]  
WEND 

SEROUT GPIO.0,6,[254,131,48]

SETMM: 'Set Minutes, MM

MM=MM+1
IF MM=60 THEN
    MM=0
    SEROUT GPIO.0,6,[254,131,48]
ENDIF
IF MM>9 THEN
    X=131
ELSE
    X=132
ENDIF
SEROUT GPIO.0,6,[254,X,#MM] 
PAUSE 1000
IF GPIO.1 = 0 THEN SetMM

StartLoop: IF GPIO.1=1 THEN StartLoop  'Push to start clock

OPTION_REG.7=1    'Turn off weak pullups
TRISIO.1=0        'Make button pin output
GPIO.1=0          'Set GP1 low
TMR0=0              'Reset TMRO
INTCON.2= 0       'Clear TMRO overflow flag

' **************************************************************
'TIME KEEPING LOOP (PART 2 of Code)

'Requires variables, HH for Hours 1-12, and MM for minutes 0-59
'(HH and MM manually set above in Part 1; SS & col = 0 from above)

Main:
ClockLoop: IF INTCON.2=0 THEN ClockLoop ' Wait for TMRO overflow
INTCON.2=0 'Clear TMRO overflow flag

HzTimer = HzTimer - $1000  'decrement timer

IF HzTimer<$1000  THEN
    IF Col=1 THEN 'update time'
        SS=SS+1
        IF SS=60 THEN
            SS=0 
            MM=MM+1
            IF MM=60 THEN
                MM=0
                HH=HH+1
                IF HH=13 THEN
                    HH=1
                ENDIF
            ENDIF
            IF HH>9 THEN
                SEROUT GPIO.0,6,[254,128,#HH,58]
            ELSE
                SEROUT GPIO.0,6,[254,128,32,#HH,58]
            ENDIF
            IF MM>9 THEN
                SEROUT GPIO.0,6,[254,131,#MM]
            ELSE
                SEROUT GPIO.0,6,[254,131,48,#MM]
            ENDIF
         ELSE
             Serout GPIO.0,6,[254,130,58]   'colon on
         ENDIF
    ELSE
        Serout GPIO.0,6,[254,130,32]    ' Colon off
    ENDIF
    Col=Col+1
    HzTimer=HzTimer+$7A12
ELSE
    'Do something here but must be less than 65,500 instructions 
    '(e.g., less than 65.5 mSec total time)
ENDIF

GOTO Main
' **************************************************************
END
I cant seem to understand this, there are some variables I cant figure out
the GPIO=0
TRISIO=2

and I dont need to display the clock in the LCD, I just want to have a clock in my program to have an accurate timed program. Im using 16f628a I use the above program revised it and it lead to a queer display in my hyperterminal, some character I dont recognized which shows every half a second T T, is interrupt really this hard?
 

Markd77

Joined Sep 7, 2009
2,806
Just substitute TRISIO and GPIO for TRISA and PORTA.
The first 2 are what microchip calls the ports on chips with only 1 port.
 

Thread Starter

warcuz

Joined Jul 10, 2008
7
ok Ill try that...but can it be ports other than that you mentioned or is it a need to have that specific port
 

Markd77

Joined Sep 7, 2009
2,806
You can use any port, that was just an example. You may have to make other changes because code written for 1 PIC doesn't always run on another. A thing that is often different is the banks that various SFRs are in.
 
Top