malc-c
- 14th February 2010, 22:19
I have an EasyPIC5 development board and one of the Microelectonica RTC2 add on modules which has been breadboarded and needed to be tested as part of an ongoing project. The following example simply shows todays date (14/2/10) and starts running from 19:00 hrs.
Although this example was simply used to test the comms between PIC and Module, it should be a simple matter to add a few tweaks to allow the date and time to be set.
'************************************************* ***************
'* Name : RTCtest877A.BAS *
'* Author : Malcolm Crabbe *
'* Notice : Copyright (c) 2010 M.Crabbe *
'* : All Rights Reserved *
'* Date : 14/02/2010 *
'* Version : 1.0 *
'* Notes : Test of breadboarded RTC2 Module to prove *
'* : hardware *
'* Target : 16F877A
'************************************************* ***************
@ __config _HS_OSC & _WDT_ON & _LVP_OFF & _CP_OFF
DEFINE OSC 20
CLEAR
;----[LCD definitions]------------------------------------------------------
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
SDA var PORTC.1 ' RTC data
SCL var PORTC.0 ' RTC clock
TRISC= %11111111
DB0 var byte[8]
CMCON = %00000111 ' Comparators = off
gosub write_1307
read_1307: ' Read time Secs,Mins,Hours,Day,Date,Month,Year,Control
I2CREAD SDA,SCL,$D1,$00,[STR DB0\8] ' Read 8 bytes from DS1307
lcdout $fe,1,"Time=",hex2 DB0[2],":",hex2 DB0[1],":",hex2 DB0[0] 'bit 0=sec, bit 1=min, bit 2=hrs
lcdout $fe,$c0,"Date=",hex2 DB0[4],":",hex2 DB0[5],":",hex2 db0[6] 'bit 4=day, bit 5=month, bit 6=year
goto read_1307
end
Write_1307: ' Set time & date to 19:00:00 14th Feb 201
I2CWRITE SDA,SCL,$D0,$00,[$00,$00,$19,$7,$14,$2,$10,$90] ' Write to DS1307
pause 10
RETURN
Rogerio
- 25th February 2010, 11:40
Hi Malcolm.
I'm trying this code but can't make it work. It only displays:
Time= 00:00:00
Date= 00:00:00
but does not show the date and time that was set or advance.
Tried grounding DS1307's Vbat pin and using a lithium battery between this pin and ground. Tried 1k, 4.7K and 10k resistors to Vcc from SCL & SDA.
I know I can write to the DS1307 and I know it's ticking since I can make the SQWE pin stop or go 1 Hz by changing the last byte while writing, I just don't seem to be able to read from it.
I'm using a 16F887 at 4 mhz, pin PortB.1 is SCL, pin PortB.2 is SDA.
Any ideas?
Thanks!
Rogerio
DEFINE OSC 4
CLEAR
;----[LCD definitions]------------------------------------------------------
DEFINE LCD_DREG PORTC ' LCD Data port
DEFINE LCD_DBIT 0 ' starting Data bit (0 or 4)
DEFINE LCD_EREG PORTD ' LCD Enable port
DEFINE LCD_EBIT 0 ' Enable bit (on EasyPIC 5 LCD)
DEFINE LCD_RSREG PORTD ' LCD Register Select port
DEFINE LCD_RSBIT 1 ' 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
SDA var PORTB.2 ' RTC data
SCL var PORTB.1 ' RTC clock
DB0 var byte[8]
TRISB= %11111111
gosub write_1307
read_1307: ' Read time Secs,Mins,Hours,Day,Date,Month,Year,Control
I2CREAD SDA,SCL,$D1,$00,[STR DB0\8] ' Read 8 bytes from DS1307
lcdout $fe,1,"Time=",hex2 DB0[2],":",hex2 DB0[1],":",hex2 DB0[0] 'bit 0=sec, bit 1=min, bit 2=hrs
lcdout $fe,$c0,"Date=",hex2 DB0[4],":",hex2 DB0[5],":",hex2 db0[6] 'bit 4=day, bit 5=month, bit 6=year
goto read_1307
end
Write_1307: ' Set time & date to 19:00:00 14th Feb 201
pause 1000
I2CWRITE SDA,SCL,$D0,$00,[$00,$00,$19,$7,$14,$2,$10,$80] ' Write to DS1307
pause 10
RETURN
KVLV
- 12th June 2010, 07:35
''************************************************ ****************
'* 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
'-----------------------------------------------------------------
financecatalyst
- 1st January 2011, 20:27
Little confused with BCD to Decimal conversion and vice versa.
Please clarify, if I have 3 variables sec, minu, hrs and want decimal values in them, is the following correct?
AIM: To get the decimal values inside sec (0-59), minu (0-59) & Hrs (0-23)
The first thing my code is doing is resetting DS1307 with the following line of code:
I2CWRITE SDA,SCL,$D0,$00,[$17,$3B,$17,$01,$00,$00,$00,$90]
The above line only executes once only when PIC is powered for the first time only.
As you can see I choose a 24Hr format for my time. I also want to start my time with 23:59:23. I am only interested in hrs,min,sec,day only.
Now if I read back the time:
I2CREAD SDA,SCL,$D1,$00,[STR DB0\8]
and want decimal values in my variables, please guide what is the correct way of doing it as the following is not working
temp=db0[0]
sec =(temp>>4)*10+(temp & $0F)
temp=db0[1]
minu =(temp>>4)*10+(temp & $0F)
temp=db0[2]
hrs=(temp>>4)*10+(temp & $0F)
Lcdout $FE,1,DEC2 sec," : ",DEC2 minu," : ",DEC2 hrs
Powered by vBulletin® Version 4.1.7 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.