Here is an example taken from one of my projects. I don't confess to writing the tightest of code, but for the reasons mentioned above, it helps when or if I need to update the code, or use it for something else a year later !
This uses a DS1307 RTC chip. There are stacks of diagrams on the net that show you haw to wire one up to a PIC micro so I won't bother you with those details
First define some variables
Code:
;----[Variables/Aliases - Time]-------------------------------------------------
RTCSec var byte ' Seconds
RTCMin var byte ' Minutes
RTCHour var byte ' Hours
RTCWDay var byte ' Weekday
RTCDay var byte ' Day
RTCMonth var byte ' Months
RTCYear var byte ' Year
RTCCtrl var byte ' Control
SetTime var byte ' 12/24 Hour Clock
SetSec var byte ' Seconds
SetMin var byte ' Minutes
SetHour var byte ' Hours
TimeH var byte ' Variable to store current hour for comparison to drop temp time
TimeM var Byte ' Variable to store current minutes for comparison to drop temp time
Set some values for the basic hours and minutes and write it to the chip (14:00 in this case)
Code:
RTCSec=0
RTCMin=0
RTCHour=14
I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
Now to set up the LCD so the time is displayed. This example uses a 2 x 16 LCD, and its connected to port B of the micro
Code:
DEFINE LCD_DREG PORTB ' LCD Data port
DEFINE LCD_DBIT 0 ' starting Data bit (0 or 4)
DEFINE LCD_EREG PORTB ' LCD Enable port
DEFINE LCD_EBIT 5 ' Enable bit (on EasyPIC 5 LCD)
DEFINE LCD_RSREG PORTB ' LCD Register Select port
DEFINE LCD_RSBIT 4 ' Register Select bit (on EasyPIC 5 LCD)
DEFINE LCD_BITS 4 ' LCD bus size (4 or 8 bits)
DEFINE LCD_LINES 2 ' number of lines on LCD
DEFINE LCD_COMMANDUS 2000 ' Command delay time in us
DEFINE LCD_DATAUS 50 ' Data delay time in us
LCDOUT $FE,1:FLAGS=0:PAUSE 250:LCDOUT $FE,1:PAUSE 250 ' Initialize LCD
Where possible I've used self explanitary variable, ie RTCHour etc.
Code:
I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl] ; read DS1307 chip
If RTCHour.6=1 then
CounterA=(RTCHour>>4)&$01 ' Work-Out 12 or 24 hour Display for Hours
else
CounterA=(RTCHour>>4)&$03
endif
CounterA=CounterA*10+(RTCHour&$0F) ' Display Hours appropriately for 12 or 24 hour Mode
timeH=(RTCHour>>4) 'convert the BCD format of the hours register and store in variable timeH
timeH=(timeH &$03)*10
timeH=timeH+(RTCHour&$0F)
timeM=(RTCMin>>4)
timeM=(timeM &$07)*10
timeM=timeM+(RTCMin&$0F) 'convert the BCD format of the mins register and store in variable timeM
If RTCHour.6=1 then
LCDOut $FE,$C0+11,#CounterA
else
LCDOut $FE,$C0+11,#CounterA Dig 1,#CounterA Dig 0
endif
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F
To set the time to the current time rather than the preset used in the variables you need some form of menu, and three buttons, one to cycle through the hours, second to cycle through the minutes, and the 3rd to store the settings in the variables.
Code:
time:
LCDOUT $FE,1
LCDOUT $FE,2,"Set Time"
inp3:
IF H_butt = 0 THEN GOSUB IncHours
IF M_butt = 0 THEN GOSUB IncMinutes
SetHour=Hours
SetMin=Minutes
LCDOUT $FE,$C0,#SetHour DIG 1,#SetHour DIG 0,":",#SetMin DIG 1,#SetMin DIG 0
pause 200
If S_butt = 0 then
pause 250
goto savetime
endif
goto inp3
savetime:
' Save 12/24 Hours to BCD DS1307's Format
' ---------------------------------------
CounterA=SetHour
If SetTime=1 then
If CounterA>12 then CounterA=CounterA-12
If CounterA=0 then CounterA=12
endif
Gosub ConvertBCD
RTCHour=CounterB
' Save the Hours Value
If SetTime=1 then
RTCHour.6=1
' Save the 12 Hour Mode Flag
If SetHour=>12 then RTCHour.5=1
' Save the 'PM' Flag
endif
'
' Save Minutes
' ------------
CounterA=SetMin
Gosub ConvertBCD
RTCMin=CounterB
CounterA=SetSec
Gosub ConvertBCD
RTCSec=CounterB
I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
IncHours:
Hours = Hours + 1
IF Hours = 24 THEN Hours = 0
pause 250
RETURN
IncMinutes:
Minutes = Minutes + 1
IF Minutes = 60 THEN Minutes = 0
pause 250
RETURN
This will get you as far as setting and displaying the hours and minutes on an LCD. As far as logging the time and other data for an incubator, I'll let you figure that one out... I've been building vivarium controllers and thermostats with the help of these nice guys on the forum for some years now, and a lot of the projects have been discussed and documented in this forum. So I'll let you do some research and look forward to seeing your code in the future, but in the meantime I hope this helps
Bookmarks