PDA

View Full Version : DS1307 12-hour mode with AM/PM divisor



JNOR07
- 30th August 2007, 00:19
Greetings:

I would like to use a DS1307 RTC display the date and time in the following format 11:59:00 AM & 01/01/07 but am unable to figure out how to set 12-hour mode and also display the AM/PM divisor, I have read the DS1307 datasheet and looked at Melanie's DS1307 example that uses three buttons to set the date and time, this example provides far more functionality than I really need, I would prefer to just set the date and time in the PicBasic Pro code (2.47) when I flash the MCU (PIC18F4620).

I am assume the solution has to do with I2CWrite/I2CRead commands but I am unable to figure out the proper syntax, I am including the PicBasic Pro code (2.47) I that I have been working with for your review.

I am a hobbyist trying to teach myself and am fairly new to electronics, microcontrollers, and PicBasic Pro, so any assistance is greatly appreciated.

Thank you,

- JNOR07


-- SNIP --

' Defines

' 40MHz (HSPLL)
Define OSC 40

' Variables

RTCSec Var Byte
RTCMin Var Byte
RTCHour Var Byte
RTCDay Var Byte
RTCDate Var Byte
RTCMonth Var Byte
RTCYear Var Byte
RTCCtrl Var Byte

RTCMode Var Byte
RTCDivisor Var Byte

' Alias and Modifiers

SDA Var PORTB.1
SCL Var PORTB.2

' Other

' LCD R/W line (Write)
Low PORTB.3

' Wait for LCD initialize
Pause 100

' Set initial time (hh:mm:ss) - 11:59:00 AM
' Set initial date (mm/dd/yy) - 01/01/07
RTCSec = $45
RTCMin = $59
RTCHour = $11
RTCDay = $01
RTCDate = $01
RTCMonth = $01
RTCYear = $07
RTCCtrl = 1

' (0) 24-hour & (1) 12-hour
RTCMode = 1
' (0) AM & (1) PM
RTCDivisor = 0

' GoSub SetRTC subroutine
Gosub SetRTC

' Goto MainLoop loop
Goto MainLoop

' SetRTC subroutine
SetRTC:
I2CWrite SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
Return

' GetRTC subroutine
GetRTC:
I2CRead SDA, SCL, $D0, $00, [RTCSec, RTCMin, RTCHour, RTCDay, RTCDate, RTCMonth, RTCYear, RTCCtrl]
Return

' MainLoop loop
MainLoop:

' GoSub GetRTC subroutine
Gosub GetRTC

' Clear display
Lcdout $FE, 1

' Display RTC time
LCDOUT "T: ", hex2 RTCHour, ":", hex2 RTCMin, ":", hex2 RTCSec

' Move cursor to beginning of second line
lcdout $FE, $C0

' Display RTC date
Lcdout "D: ", hex2 RTCMonth, "/", hex2 RTCDate, "/" , hex2 RTCYear

' Wait 250ms
Pause 250

' Goto MainLoop loop
Goto MainLoop

End

-- SNIP --

Bruce
- 30th August 2007, 13:26
To place the 1307 in 12-hour mode, you set bit 6 in the Hours register. To select AM at the
same time, you would clear bit 5. If you wanted to set it for PM, then you would set bit 5.

You have to include these bits with the Hour time when you first write to the 1307. After the
first write, then you only test the AM/PM bit to determine AM or PM. In 12-hour mode, only
bits 4,3,2,1 and 0 of the Hours register are used to indicate the hour.

This should be easy to convert over to the PIC you have. Look at the comments in the
Write_1307 sub-routine side-by-side with the 1307 data sheet, and it will be a lot clearer.


@ DEVICE PIC16F627A,INTRC_OSC,LVP_OFF,WDT_OFF,MCLR_ON,PROTE CT_OFF
DEFINE OSC 4

' Note: use 10K pull-up resistors on both SDA and SCL lines.
' DS1307 control pins
SDA Var PORTB.0 ' DS1307 SDA pin #5
SCL Var PORTB.1 ' DS1307 SCL pin #6

' Variables
DB Var BYTE[8] ' Data byte array
RTCSec Var DB[0] ' alias individual bytes in array
RTCMin Var DB[1]
RTCHour Var DB[2]
RTCDay Var DB[3]
RTCDate Var DB[4]
RTCMonth Var DB[5]
RTCYear Var DB[6]
RTCCtrl Var DB[7]
AMPM Var BIT
AM Con 0
PM Con 1

' Port configuration
TRISB = 0
TRISA = 0
CMCON = %00000111 ' Comparators = off

' 12-hour mode clock routine for the DS1307 RTC
GOSUB Write_1307 ' Write time & date on power-up

Main:
GOSUB Read_1307 ' Read the time & date

' Now display it
HSEROUT ["Time: "]
HSEROUT [DEC((RTCHour>>4)& $01), DEC(RTCHour & $0f),":"]
HSEROUT [DEC((RTCMin>>4)& $0f), DEC(RTCMin & $0f),":"]
HSEROUT [DEC((RTCSec>>4)& $0f), DEC(RTCSec & $0f)]

AMPM = RTCHour.0[5] ' Bit 5 of RCTHour indicates AM or PM

IF AMPM = AM THEN ' If RTCHour.bit5 = 0 it's AM
HSEROUT [" AM",13,10] ' Print AM
ELSE ' Else it's PM
HSEROUT [" PM",13,10] ' Print PM
ENDIF

HSEROUT ["Day: ", DEC(RTCDay & $07),13,10]
HSEROUT ["Date: ", DEC((RTCMonth>>4)& $01), DEC(RTCMonth & $0f),":"]
HSEROUT [DEC((RTCDate>>4)& $03), DEC(RTCDate & $0f),":"]
HSEROUT [DEC(((RTCYear>>4)& $0f)*100),DEC(RTCYear & $0f),13,13,10]
PAUSE 1000
GOTO Main

Read_1307:
' Read order is in Secs,Mins,Hours,Day,Date,Month,Year,Control
I2CRead SDA,SCL,$D0,$00,[STR DB\8] ' Read string of 8 bytes from DS1307
RETURN

Write_1307:
' $71 in the Hours register would make it 11 PM
' $51 in the Hours register would make it 11 AM
'
' Example:
' $51 = %0101 0001 <-- 1's position of hour
' ||||_________ 10's position of hour. 10+1 = 11 O-clock
' |||__________ 1 = PM, 0 = AM (in 12-hour mode)
' ||___________ 1 = 12-hour mode, 0 = 24-hour mode
' |____________ ignore this bit
'
' Set time & date to 11:59:00, Day 2, Date:Month:Year 30:08:2007
I2CWRITE SDA,SCL,$D0,$00,[$00,$59,$51,$02,$30,$08,$27,$90] ' Write to DS1307
RETURN ' Sec Min Hr Day D M Y Control

End