Published: Saturday, 04 April 2009
Written by Digital DIY
The DS1307 is a great piece of kit, it provides real time date and clock values, and interfaces with the PIC micro via I2C. The values it holds for date/time are, Secs, Mins, Hours, Day, Date, Month and Year. I hear you asking, why use this when you could make a small program do the same with a PIC;
- The DS1307 has leap year compensation until 2100
- A 32.768Khz crystal is far more accurate than a 4Mhz+ crystal
- In back-up mode, the DS1307 consumes less than 500nA
Example of interfacing with a DS1307. Note that on the DS1037 Pin 8 is connected to 5V, Pin 4 is connected to GND and Pin 3connected to ground if no backup battery is used!
(LCD, 5v Regulator and Contrast Control not shown for ease of illustration)
If you wish to use a battery backup for the DS1307, then connect the positive of the battery to Pin 3, and the earth to Pin 4. When ever Vcc (Pin 8) is lower than Pin 3 (Batt), the device will enter backup mode and consume less than 500nA.
Notice that the DS1307 also requires an external oscillator, both the chip and crystal (part# CRY32) can be found at Futurlec. Be sure to connect the 4.7K pull-up resistors on SCL and SDA as shown aswell.
Device = 18F452
Clock = 20
// some LCD options...
#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3
// import LCD library...
Second As Byte // Second (0..59)
Minute As Byte // Minute (0..59)
Hour As Byte // Hour (0..11 or 0..23)
Day As Byte // Date (0..31)
Month As Byte // Month (1..12)
Year As Byte // Year (0..99)
DayOfWeek As Byte // day of the week (1..7)
Dim Time As TTime,
Date As TDate,
Seconds_Poll As Byte
Sub SetTime(Hour, Minute, Second, DayOfWeek, Day, Month, Year As Byte)
I2C.WriteByte(%11010000) // Send the RTC address, and put it in write mode
I2C.WriteByte($00) // Move the pointer to first register
I2C.WriteByte(DecToBCD(Second)) // Write each byte
Time.Second = BCDToDec(I2C.ReadByte(I2C_ACKNOWLEDGE))
Time.Minute = BCDToDec(I2C.ReadByte(I2C_ACKNOWLEDGE))
Time.Hour = BCDToDec(I2C.ReadByte(I2C_ACKNOWLEDGE))
Date.DayOfWeek = BCDToDec(I2C.ReadByte(I2C_ACKNOWLEDGE))
Date.Day = BCDToDec(I2C.ReadByte(I2C_ACKNOWLEDGE))
Date.Month = BCDToDec(I2C.ReadByte(I2C_ACKNOWLEDGE))
Date.Year = BCDToDec(I2C.ReadByte(I2C_NOT_ACKNOWLEDGE))
// Start Of Program...
SetAllDigital // Make all pins digital I/O's
I2C.Initialize() // Set up the I2C
If Time.Second = Seconds_Poll Then
GoTo Main // If there is update in Secs, display time and Date
// Display the new details on the LCD
WriteAt(1,1,"Time: ", DecToStr(Time.Hour,2), ":", DecToStr(Time.Minute,2), ":", DecToStr(Time.Second,2))
WriteAt(2,1,"Date: ", DecToStr(Date.Day,2), "-", DecToStr(Date.Month,2), "-", DecToStr(Date.Year,2))
Seconds_Poll = Time.Second // Update the seconds polling register