Code:
' Name : PI.pbp
' Compiler : PICBASIC PRO Compiler 2.5
' Assembler : MPASM
' Target PIC : PIC16F628A or similar type
' Hardware : VeroBoard
' Oscillator : 4Megs Internal
' Keywords : I2CREAD, I2CWRITE, LCDOUT
' Description : PICBASIC PRO program for an LCD clock program
' using the Dallas DS1307 I2C RTC.
' Define LCD pins
DEFINE LCD_EREG PORTA
DEFINE LCD_EBIT 6
' Alias pins
SDA Var PORTB.1
SCL Var PORTB.4
wakebutton var PORTB.0 'shake
lcdandrtc var PORTA.6 'LCD and RTC ON/OFF
timeout1 var byte
'timeout2 var byte
PrevTime var byte 'Holds previously read RTCMin
CurTime var byte 'Holds currently read RTCMin
TimeoutMax var byte 'You can change this to a constant if it is not changed during execution
WakeupFlag var bit 'Used for wakeup/reset tracking for timer
TimeoutMax = $02 'You can delete this if TimeoutMax is a constant
WakeupFlag = 1 'Preset to true
' Allocate variables
RTCYear Var Byte
RTCMonth Var Byte
RTCDate Var Byte
RTCDay Var Byte
RTCHour Var Byte
RTCMin Var Byte
RTCSec Var Byte
RTCCtrl Var Byte
TRISA=0 'outputs
TRISB=15 'Bit 0,1,2,3 inputs
CMCON=7 'turns off analogs
wakeup: INTCON=%00010000 'RB0 is interrupt
OPTION_REG.6=0 'Trig on falling
OPTION_REG.7=0 'Enables pull ups
Pause 500 ' Wait for LCD to startup
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "WELCOME TO" ' Display WELCOME TO
Lcdout $fe, $C0, " PI DAY" ' Display PI Day
Pause 2000 ' Wait 2 seconds
Lcdout $fe, 1 ' Clear LCD screen
timeout1 = TimeoutMax 'Preset timeout1 for countdown
'Set initial time
RTCYear = $15
RTCMonth = $03
RTCDate = $03
RTCDay = $06
RTCHour = $20
RTCMin = $46
RTCSec = 0
RTCCtrl = 0
'Gosub settime ' Set the time
Goto mainloop ' Skip over subroutines
' Subroutine to write time to RTC
'settime:I2CWrite SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
' Return
' Subroutine to read time from RTC
gettime:I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
'timeout1=rtcmin
CurTime = RTCMin '
if WakeupFlag = 1 then '1st time after a wakeup/reset
PrevTime = CurTime 'Set PrevTime after wakeup/reset
WakeupFlag = 0 'Clear the flag
endif
Return
' Main program loop
mainloop:
Gosub gettime ' Read the time from the RTC
' Display time on LCD
'Lcdout $fe, 1, hex2 RTCMonth, "/", hex2 RTCDate, "/" , hex2 RTCYear,_
'" ", hex2 RTCHour, ":", hex2 RTCMin, ":", hex2 RTCSec
Lcdout $fe, 1, HEX2 RTCDate, "/", HEX2 RTCMonth," ", HEX2 RTCHour, ":", HEX2 RTCMin, ":", HEX2 RTCSec
IF RTCHour <=$12 then gosub morning
IF RTCHour >=$13 then gosub afternoon
IF RTCHour=$03 and RTCMin=$14 Then CACHE ' Morning Cache
IF RTCHour=$15 and RTCMin=$14 Then CACHE ' Afternoon Cache
'if rtcmin=(timeout1+2) then bedtime
If CurTime > PrevTime Then
timeout1 = timeout1 - (CurTime - PrevTime)
PrevTime = CurTime
else
'Oops something happened. Current time is less than Previous time
'This should take care of the rollover from 59 to 00 minutes and unexpected delays
'If timeout1 = 0 no need to do anything, the timeout1 test below will put the unit to sleep
'The WakeupFlag will be set when we go to sleep and PrevTime and CurTime will be set properly
'after we wakeup and proceed through the mainloop
if timeout1 > 0 then
timeout1 = timeout1 - 1 'decrement the timeout value
PrevTime = CurTime 'Reset Previous time to a valid number for the countdown timer
endif
endif
if timeout1 = 0 then 'Timeout reached
WakeupFlag = 1 'Reset the flag
goto bedtime 'countdown has reached 0, go to sleep
endif
Pause 500 ' Do it about 2 times a second
Goto mainloop ' Do it forever
morning: Lcdout $fe, $C0, "CACHE @ 3:14AM"
return
afternoon: Lcdout $fe, $C0, "CACHE @ 3:14PM"
return
CACHE: Lcdout $fe, 1 ' Clear LCD screen
LCDOUT "CONGRATULATIONS"
Lcdout $fe, $C0, "CACHE IS LOCATED"
PAUSE 2000
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "N XX",$DF, " YY.ZZZ " ' Display N 123° 456.789
Lcdout $fe, $C0, "W XX",$DF, " YY.ZZZ " ' Display W 123° 456.789
PAUSE 20000
bedtime:high lcdandrtc 'turn of lcd and rtc
INTCON.1=0 'reset RB0 interupt flag
@ sleep
@ NOP
@ NOP
pause 500 'wakeup delay
goto wakeup
end
Bookmarks