16F DS1307 Example

    The DS1307 is a great piece of kit, it provides real time date and clock values, and interfaces with the PIC micro via I2C. For this project, the 16F876A was used. 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 3 is connected to ground if no backup battery is used!

Note the PIC's power supply/oscillator are not shown

Click here too see this circuit in action!

    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.

    Datasheet for the DS1307

    Datasheet for the 16F876A

    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 pull-up resistors on SCL and SDA as shown aswell.

Device = 16F876
Xtal = 4
ALL_DIGITAL = True
PORTB_PULLUPS = True

' Setup the LCD
LCD_DTPIN = PORTB.4
LCD_RSPIN = PORTB.2
LCD_ENPIN = PORTB.3
LCD_INTERFACE = 4
LCD_LINES = 2
LCD_TYPE = 0
 
' Define I2C bus ports
SDA_Pin = PORTA.0 'DS1307 SDA pin
SCL_PIN =PORTA.1 'DS1307 SCL pin

Dim Temp1 As Byte
Dim Temp2 As Byte
Dim TempVal As Byte

Dim Secs As Byte
Dim Mins As Byte
Dim Hrs As Byte
Dim day As Byte
Dim Date As Byte
Dim Month As Byte
Dim Year As Byte
Dim Ctrl As Byte

Dim Secs_last As Byte

'Initialize LCD

Delayms 100
Cls

' Set initial DS1307 time / Date

Secs = 0 ' Set seconds
Mins = 30 ' Set minutes
Hrs = 12 ' Set hours

Day = 1 ' Set day of week value

Date = 30 ' Day of month value
Month = 11 ' Month value
Year = 6 ' Year value

Ctrl = 0 ' Set the control byte (leave as 0 in this example)


' The DS1307 works with data in BCD format, so convert BIN to BCD

TempVal=Secs
GoSub BIN_TO_BCD
Secs=TempVal

TempVal=Mins
GoSub BIN_TO_BCD
Mins=TempVal

TempVal=Hrs
GoSub BIN_TO_BCD
Hrs=TempVal

TempVal=Day
GoSub BIN_TO_BCD
Day=TempVal

TempVal=Date
GoSub BIN_TO_BCD
Date=TempVal

TempVal=Month
GoSub BIN_TO_BCD
Month=TempVal

TempVal=Year
GoSub BIN_TO_BCD
Year=TempVal

BStart

' The datasheet specifies the first byte is 1101000x where x is read(1) or write(0).
' The second byte tells the DS 1307 where to start reading, 0 is at the start.
' The Ctrl byte contains advanced features, read the datasheet for more info
Busout 11010000, 0, [Secs, Mins, Hrs, day, Date, Month, Year, Ctrl]
'Write initial values for time / Date

BStop

Delayms 20

Main:

BStart
' The datasheet specifies the first byte is 1101000x where x is read(1) or write(0).
' The second byte tells the DS 1307 where to start reading, 0 is at the start.
BusIn 11010001, 0, [Secs, Mins, Hrs, day, Date, Month, Year, Ctrl]

BStop

' The DS1307 sends it data in BCD, therefore it must be changed to
' BIN so that it can be easily used (eg, print onto an LCD)

TempVal=Secs
GoSub BCD_TO_BIN
Secs=TempVal

TempVal=Mins
GoSub BCD_TO_BIN
Mins=TempVal

TempVal=Hrs
GoSub BCD_TO_BIN
Hrs=TempVal

TempVal=Date
GoSub BCD_TO_BIN
Date=TempVal

TempVal=Month
GoSub BCD_TO_BIN
Month=TempVal

TempVal=Year
GoSub BCD_TO_BIN
Year=TempVal


 
'If there is update in Secs, display time and Date
If Secs - Secs_last = 0 Then Goto Main

' The Dec2 modifier makes sure that each value will have 2 characters, eg 1 becomes 01
Print At 1,1,"Time: ",Dec2 Hrs, ":", Dec2 Mins,":", Dec2 Secs
Print At 2,1,"Date: ", Dec2 Date, "-", Dec2 Month, "-", Dec2 Year

Secs_last = Secs

Goto Main

BCD_TO_BIN:                         ' Convert the BCD values into BIN

Temp1 = $0F & TempVal ' Clear off the top four bits
Temp1 = DIG Temp1, 0
Temp2 = TempVal >> 4 ' Shift down four to read 2 BCD value
Temp2 = DIG Temp2, 0
TempVal = Temp2 * 10 + Temp1

Return

BIN_TO_BCD:

Temp1 = Dig TempVal, 0         ' GET THE DEC DIGIT FOR THE FIRST NIBBLE
Temp2 = Dig TempVal, 1         ' GET THE DEC DIGIT FOR THE FIRST NIBBLE
Temp2 = Temp2 << 4             ' MOVE NUMBER OVER TO 2ND NIBBLE

' XOR THEM TOGTHER TO MAKE THE WHOLE BCD NUMBER
TempVal = Temp1 ^ Temp2        

Return

Where you can get the components;

 Skip Navigation Links.

Collapse Site Tutorial IndexSite Tutorial Index
Collapse 16F PIC Examples16F PIC Examples
LED's
Switches
Keypads
LCD's
7 Seg Displays
ADC
DAC
Expand MotorsMotors
Expand ThermometersThermometers
DS1307 RTC Chip
DS275
EEPROM's
RF Modules
RGB LED's
Code Snippets
Expand Code SnippetsCode Snippets
Expand 18F PIC Examples18F PIC Examples
Expand Handy TipsHandy Tips