Code:
''****************************************************************
'* Name : RTC2620.PBP *
'* Author : KVLV *
'* Notice : Copyright (c) 2010 [select VIEW...EDITOR OPTIONS] *
'* : All Rights Reserved *
'* Date : 6/11/2010 *
'* Version : 1.0 *
'* Notes : *
'* : *
'****************************************************************
'Jun11.2010 this program was created using parts of another big program
'for displaying and adjusting RTC chip DS1307. displaying RTC on a 2x20 LCD
'the pic chip used pic18f2620
'press the minus key will get to setting up RTC at startup or after reset
'some parts or all are copied from the forum and modified<< Thanks.
'the program can only display the clock in 12hr format with am/pm indicator
'the day of the week in word ex. Sunday as Sun (also start of week)
'the month is also in word ex: June as Jun
'here is the example of the display
'
'11:19:00PM
'Fri Jun 11 2010
' the clock is refresh every 100ms
'
'------------------------------------------------------------------
DEFINE LOADER_USED 1 'for bootstrap loader
DEFINE OSC 20
' Define LCD pins
DEFINE LCD_DREG PORTB '
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 3
DEFINE LCD_EREG PORTC
DEFINE LCD_EBIT 5
Define LCD_COMMANDUS 2000
' Command Delay (uS)
Define LCD_DATAUS 100 ' Data Delay (uS)
'-----------------------------------------------------
Line var byte
Line1 con $80
Line2 con $c0
ButOK var PortB.0
ButPlus var PortB.1
ButMinus var PortB.2
Debounce con 250
'---------------------------------------
CounterA var byte
CounterB var byte
CounterC var byte
CounterD var byte
'CounterX var byte
EEpromByte var byte
TimeOut var word
'---------------------------------------------
SetMonth var byte
SDA var PORTC.1 ' RTC data
SCL var PORTC.0 ' RTC clock
DB0 var byte[10]
RTCTemp var byte
SetYear var byte ' Year
'-----------------------------------------------------------------------------
' EEPROM 41,[%11111111] ' xxxx xxx0 = RTC is not set
'xxxx xxx1 = RTC is set
'xxxx xx0x = timer is not set
'xxxx xx1x = timer is set
' eeprom 50,["ROOM1ROOM2CLOAKDECALEARTHFLUIDGLASSHEARTINLETJUICE"]
eeprom 100,["JanFebMarAprMayJunJulAugSepOctNovDec"]
eeprom 136,["SunMonTueWedThuFriSat"]
'------------------------------------------
'initialization
PORTA=00
LATA=$ff
TRISA=%00000000 '0=output
TRISB=%00000111 '1 = input
TRISC=%00000000
ADCON0=%11000000
ADCON1=%00000111
CMCON =%00000111 ' Comparators = off
INTCON2.7=0 ' Enable Pull-Up's PIC18F2620 'VERIFIED
'-----------------------------------------------------
lcdout $fe,1
LATA=%11111011 'turn on backlight to lcd, turn all relays off
'' gosub write1307
'press the (-) minus key, will take to the routine of adjusting the RTC
MinusPressed:
if butminus=0 then
gosub AdjustRTC 'this one works
'lcdout $fe, $0c 'turn off cursor
endif
'-------------------------------------------------------
lcdout $fe, $0c 'turn off cursor
lcdout $fe,1
Main:
' for counterx=1 to 5
gosub ReadDisplayRTC
pause 100
' next counterx
goto main
'------------------------------------------------
'eeprom 100,["JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC"]
'eeprom 136,["SUNMONTUEWEDTHUFRISAT"]
AdjustRTC:
gosub waitbutrelease
lcdout $fe,line1,"RTC ADJUSTMENT"
lcdout $fe,line2,"-/+:CHANGE OK:SAVE "
pause 2000
' gosub waitbutrelease
lcdout $fe,1
RPTAdjustRTC:
LCDOUT $FE,$0F 'TURN ON lcd cursor
while butok<>0 'adjust day of week
GOSUB ReadDisplayRTC
lcdout $fe,line2+0
counterc=db0[3]
if butplus=0 then
counterc=counterc + 1
if counterc>7 then counterc=1
endif
if butminus=0 then
counterc=counterc - 1
if counterc=0 then counterc=7
endif
db0[3]=counterc
gosub settime
'I2CWRITE SDA,SCL,$D0,$00,[db0[0],db0[1],db0[2],counterc,db0[4],db0[5],db0[6],db0[7],db0[8],$90]
pause debounce
wend
gosub rtcwaitnext
while butok<>0 'adjust month
GOSUB ReadDisplayRTC
lcdout $fe,line2+4
counterc=db0[5] 'month
rtctemp =(counterc>>4)*10+(counterc & $0F) 'convert BCD into Decimal
if butplus=0 then
rtctemp=rtctemp+1 'increment by 1
If rtctemp>12 then '
rtctemp=1
endif 'reset to 0
endif
if butminus=0 then
rtctemp=rtctemp-1 'decrement by 1
If rtctemp=0 then '
rtctemp=12
endif
endif
countera=rtctemp
gosub ConvertBCD
db0[5]=counterb
gosub settime
pause debounce
wend
gosub rtcwaitnext
LCDOUT $FE,$0F 'TURN ON lcd cursor
while butok<>0 'adjust date of the month
GOSUB ReadDisplayRTC
lcdout $fe,line2+8
counterc=db0[4]
rtctemp =(counterc>>4)*10+(counterc & $0F) 'convert BCD into Decimal
if butplus=0 then
rtctemp=rtctemp+1 'increment by 1
setmonth=db0[5]
setyear=db0[6]
gosub finddays
If rtctemp>countera then 'If minutes exceeds 59
rtctemp=1
endif 'reset to 0
endif
if butminus=0 then
rtctemp=rtctemp-1 'decrement by 1
If rtctemp=0 then 'If minutes exceeds 59
setmonth=db0[5]
setyear=db0[6]
gosub finddays
rtctemp=countera
endif
endif
countera=rtctemp
gosub ConvertBCD
db0[4]=counterb
gosub settime
'I2CWRITE SDA,SCL,$D0,$00,[db0[0],db0[1],db0[2],db0[3],Counterb,db0[5],db0[6],db0[7],db0[8],$90]
pause debounce
wend
gosub rtcwaitnext
while butok<>0 'adjust the century (100th) year
GOSUB ReadDisplayRTC
lcdout $fe,line2+11
counterc=db0[8]
' rtctemp =(counterc>>4)*10+(counterc & $0F) 'convert BCD into Decimal
rtctemp=counterc
if butplus=0 then
rtctemp=rtctemp+1 'increment by 1
If rtctemp>99 then 'If minutes exceeds 59
rtctemp=1
endif 'reset to 0
endif
if butminus=0 then
rtctemp=rtctemp-1 'decrement by 1
If rtctemp=00 then 'If minutes exceeds 59
rtctemp=99
endif
endif
' countera=rtctemp
' gosub ConvertBCD
db0[8]=rtctemp
gosub settime
'I2CWRITE SDA,SCL,$D0,$00,[db0[0],db0[1],db0[2],db0[3],db0[4],db0[5],counterb,db0[7],db0[8],$90]
pause debounce
wend
gosub rtcwaitnext
while butok<>0 'adjust the year
GOSUB ReadDisplayRTC
lcdout $fe,line2+13
counterc=db0[6]
rtctemp =(counterc>>4)*10+(counterc & $0F) 'convert BCD into Decimal
if butplus=0 then
rtctemp=rtctemp+1 'increment by 1
If rtctemp=100 then 'If minutes exceeds 59
rtctemp=0
endif 'reset to 0
endif
if butminus=0 then
rtctemp=rtctemp-1 'decrement by 1
If rtctemp=$ff then 'If minutes exceeds 59
rtctemp=99
endif
endif
countera=rtctemp
gosub ConvertBCD
db0[6]=counterb
gosub settime
'I2CWRITE SDA,SCL,$D0,$00,[db0[0],db0[1],db0[2],db0[3],db0[4],db0[5],counterb,db0[7],db0[8],$90]
pause debounce
wend
gosub rtcwaitnext
LCDOUT $FE,$0F 'TURN ON lcd cursor
while butok<>0 'adjust the hour
GOSUB ReadDisplayRTC
lcdout $fe,line1+0
counterc=db0[2]
counterd=db0[2]
rtctemp=counterc & %00011111
if rtctemp=$10 then rtctemp=10
if rtctemp=$11 then rtctemp=11
if rtctemp=$12 then rtctemp=12
if butplus=0 then
rtctemp=rtctemp+1 'increment by 1
if rtctemp>12 then rtctemp=1
if counterd.5=1 and rtctemp=12 then
counterd.5=0
goto _donesethr
endif
if counterd.5=0 and rtctemp=12 then
counterd.5=1
goto _donesethr
endif
endif
if butminus=0 then
rtctemp=rtctemp-1 'decrement by 1
If rtctemp=0 then rtctemp=12
if counterd.5=1 and rtctemp=11 then
counterd.5=0
goto _donesethr
endif
if counterd.5=0 and rtctemp=11 then
counterd.5=1
goto _donesethr
endif
endif
_DoneSetHR:
if rtctemp=10 then rtctemp=$10
if rtctemp=11 then rtctemp=$11
if rtctemp=12 then rtctemp=$12
db0[2]=(counterd & %01100000) | rtctemp
gosub settime
'I2CWRITE SDA,SCL,$D0,$00,[db0[0],db0[1],counterb,db0[3],db0[4],db0[5],db0[6],db0[7],db0[8],$90]
pause debounce
wend
gosub rtcwaitnext
LCDOUT $FE,$0F 'TURN ON lcd cursor
while butok<>0 'adjust the minute
GOSUB ReadDisplayRTC
lcdout $fe,line1+3
counterc=db0[1]
rtctemp =(counterc>>4)*10+(counterc & $0F) 'convert BCD into Decimal
if butplus=0 then
rtctemp=rtctemp+1 'increment by 1
If rtctemp>59 then 'If minutes exceeds 59
rtctemp=0
endif 'reset to 0
endif
if butminus=0 then
rtctemp=rtctemp-1 'decrement by 1
If rtctemp=$ff then 'If minutes exceeds 59
rtctemp=59 '??????????????
endif
endif
countera=rtctemp
gosub ConvertBCD
db0[1]=counterb
gosub settime
'I2CWRITE SDA,SCL,$D0,$00,[db0[0],counterb,db0[2],db0[3],db0[4],db0[5],db0[6],db0[7],db0[8],$90]
pause debounce
wend
gosub rtcwaitnext
LCDOUT $FE,$0F 'TURN ON lcd cursor
while butok<>0 'adjust the second
GOSUB ReadDisplayRTC
lcdout $fe,line1+6
counterc=db0[0]
rtctemp =(counterc>>4)*10+(counterc & $0F) 'convert BCD into Decimal
if butplus=0 then
rtctemp=rtctemp+1 'increment by 1
If rtctemp>59 then 'If minutes exceeds 59
rtctemp=0
endif 'reset to 0
endif
if butminus=0 then
rtctemp=rtctemp-1 'decrement by 1
If rtctemp=$ff then 'If minutes exceeds 59
rtctemp=59
endif
endif
countera=rtctemp
gosub ConvertBCD
db0[0]=counterb
gosub settime 'I2CWRITE SDA,SCL,$D0,$00,[counterb,db0[1],db0[2],db0[3],db0[4],db0[5],db0[6],db0[7],db0[8],$90]
pause debounce
wend
gosub rtcwaitnext
' goto RPTAdjustrtc
'-------------------------------------------------
ExitAdjustRTC:
pause debounce
return
RTCWaitNext:
' LCDOUT $FE,$0F
' lcdout $fe,line2+16,"NEXT",$FE,LINE2+16
' PAUSE 500
WHILE BUTOK<>0
pause 1
timeout=timeout+1
if timeout=10000 then Exit 'RTCWAitNext
WEND
pause debounce
'ExitRTCWAitNext:
return
'-------------------------------------------------
' Subroutine Converts back to BCD
' -------------------------------
' CounterA is the entry variable
' CounterB holds the converted BCD result on exit
ConvertBCD:
CounterB=CounterA DIG 1
CounterB=CounterB<<4
CounterB=CounterB+CounterA DIG 0
Return
'
' Subroutine works out Number of Days in the Month
' ------------------------------------------------
' SetYear - entry variable containing year (0-99)
' SetMonth - entry Variable Containing Month (1-12)
' CounterA - exits with number of days
FindDays:
LookUp SetMonth-1,[31,28,31,30,31,30,31,31,30,31,30,31],CounterA
' Above line gives the 'usual' days of the Month
' Section below adjusts for Leap-Year
If SetMonth=2 then
If (SetYear&$03)=0 then
CounterA=29
endif
endif
Return
'---------------------------------------
'setup db0 to db8
'db0[0]=second
'db0[1]=minute
'db0[2]= hour
'db0[3]=day of the week, start day=1 for Sunday
'db0[4]=date of the month
'db0[5]=month from 1 to 12
'db0[6]=year from 00 to 99
'db0[7]=control for the RTC
'db0[8]=the century (100th of the year)
SetTime:
I2CWRITE SDA,SCL,$D0,$00,[db0[0],db0[1],db0[2],db0[3],db0[4],db0[5],db0[6],db0[7],db0[8],$90]
return
''------------------------------------------------
'---------------------------------------------
WaitButRelease:
lcdout $fe,1,"PLEASE RELEASE",$FE,LINE2,"THE BUTTON"
_waitButRelease:
while butminus<>1
wend
while butplus<>1
wend
WHILE BUTOK<>1
WEND
return
''-----------------------------------------------------------------
'------------------------------------------------------------------------------------------------
RTCHOUR VAR BYTE
RTCMIN VAR BYTE
RTCSEC VAR BYTE
ReadDisplayRTC: ' Read time Secs,Mins,Hours,Day,Date,Month,Year,Control
I2CREAD SDA,SCL,$D1,$00,[STR DB0\9] ' Read 8 bytes from DS1307
RTCHOUR=DB0[2]
RTCMIN=DB0[1]
RTCSEC=DB0[0]
LCDOut $FE,$80
If RTCHour.6=1 then
' Work-Out 12 or 24 hour Display for Hours
CounterA=(RTCHour>>4)&$01
else
CounterA=(RTCHour>>4)&$03
endif
CounterA=CounterA*10+(RTCHour&$0F)
If RTCHour.6=1 then
if countera<10 then
LCDOut $fe,line1," ",#CounterA
endif
if countera>9 then
LCDOut #CounterA Dig 1,#CounterA Dig 0
endif
endif
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F '," "
IF RTCHour.6=1 then
If RTCHour.5=1 then
LCDOut "PM"
else
LCDOut "AM"
endif
endif
lcdout $fe,line2
gosub displaydayinword:lcdout " "
gosub DisplayMonthInWord :lcdout " " 'LOC5
lcdout hex2 DB0[4]," ",dec2 db0[8],hex2 db0[6] 'bit 4=day, bit 5=month, bit 6=year
return
'----------------------------------------------------------
'-----------------------------------------------------------------
DisplayDayInWord:
' eeprom 136,["SUNMONTUEWEDTHUFRISAT"]
'Sunday start at 1
'-----------------------
' DB0[3]= day in hex number 'input
' day in words 'out
' db0[3] won't change
counterb=0
counterb=((db0[3]*3)-3)+136
for countera=0 to 2
read counterb+countera, eeprombyte
lcdout eeprombyte
next countera
return
'-----------------------------------------------------------------
''------------------------------------------------------------
DisplayMonthInWord:
' DB0[5]= MONTH in hex number 'input
' month in words 'out
'what will happen when the month after October >10
' db0[5] won't change for the month of oct, nov, dec
' hserout [hex2 db0[5]," "]
if db0[5]=$10 then db0[5]=10
if db0[5]=$11 then db0[5]=11
if db0[5]=$12 then db0[5]=12
counterb=0
counterb=((db0[5]*3)-3)+100
for countera=0 to 2
read counterb+countera, eeprombyte
lcdout eeprombyte
next countera
if db0[5]=10 then db0[5]=$10
if db0[5]=11 then db0[5]=$11
if db0[5]=12 then db0[5]=$12
return
'------------------------------------------------
'''-----------------------------------------------------
''Write1307:
'' read 41,eeprombyte
'' if eeprombyte.0=0 then
'' ' Set time & date to 19:00:00 14th Feb 2010
'' ' set time to 9:00:00PM, date to 30.05.10, year as register 08h in the ds1307
'' I2CWRITE SDA,SCL,$D0,$00,[$00,$10,%01101100,$01,$06,$06,$10,00,20,$90] ' Write to DS1307
'' pause 10
'' eeprombyte=eeprombyte and $ff
'' write 41,eeprombyte
'' endif
''RETURN
'-----------------------------------------------------------------
Bookmarks