Chips: DS1307 I2C real-time clock

Posted on Friday, September 4th, 2009 in Bus Pirate, Chips by Ian


This is an old version, see the latest version on the documentation wiki.

The DS1307 is a simple, inexpensive I2C real-time clock, it’s somewhat similar to the PCF8563 that was previously demonstrated with the Bus Pirate.

This chip has some nice features. It has internal capacitors on both oscillator pins, the only required external part is a 32.768kHz time-keeping crystal. It also has a backup battery input so it can keep time during power failures. The battery backup also applies to 56byte of general purpose RAM.

Keep reading for a complete DS1307 demo using the Bus Pirate universal serial interface. If you’re not using a Bus Pirate, that’s OK, you can still follow along and get a better understanding of how to implement this chip in your own application.

Chip: DS1307, I2C real-time clock.
Bus: I2C, pull-up resistors required.
Power requirements: 5volts (4.25-5.525volts).
References: datasheet [PDF].
Complete Bus Pirate session log for this demonstration.



The schematic above shows the DS1307 pinout and minimum circuit. The oscillator has internal capacitors, so an external 32.768kHz crystal is the only required external component. The chip requires a 5volt power supply.

Bus Pirate DS1307 (pin)
+5volts, Vpullup +5volts (8)

Connect the Bus Pirate to the DS1307 as shown in the table. We powered the DS1307 from the Bus Pirate’s 5volt supply, and used the on-board pull-up resistors to hold the I2C bus high.

I2C>W<< power supplies on
I2C>p<< configure pull-up resistors
1. Pull-ups off
2. Pull-ups on
(1) >2
Pull-up resistors ON
I2C>(1)<< address scan macro
Searching 7bit I2C address space.
Found devices at:
0xD0(0x68 W) 0xD1(0x68 R)

In the Bus Pirate terminal select the mode menu (m) and choose I2C. Choose software I2C, any speed 400kHz or less is fine. Turn on the Bus Pirate power supplies (big W) and enable the pull-up resistors (p). We used the I2C scan macro (1) to find the DS1307 address, you could also refer to the datasheet.

If you’re not using a Bus Pirate, that’s OK, you can still follow along and get a better understanding of how to implement this chip in your own application.



Table 2 from page 9 of the datasheet shows the location of values in the DS1307 memory. The first 8 bytes hold the time and configuration settings (0x00-0x07), the upper bytes are blank and can be used as extra RAM (0x08-0x3f).

Set the time by writing to the first eight memory locations of the DS1307.

I2C>[0xd0 0 0 0b00110000 0b00001001 0b00000010 0b00000111 0b00001001 0b00001001 0]
WRITE: 0xD0 ACK<< DS1307 write address
WRITE: 0x00 ACK<< location to write
WRITE: 0x00 ACK<< 0 seconds, reset CH bit to 0
WRITE: 0x30 ACK<< 30 minutes
WRITE: 0x09 ACK<< 9 hours, 24 hour clock mode
WRITE: 0x02 ACK<< Monday (day 2)
WRITE: 0x07 ACK<< 7th (date)
WRITE: 0x09 ACK<< September (month)
WRITE: 0x09 ACK<< ’09 (year)
WRITE: 0x00 ACK<< Set control register to 0

0xd0 is the write address, followed by the memory location to write (0). Next come the time settings: 9:30:00 Monday 09/07/09.

Note that the numbers are represented as digits on a clock, rather than as decimal numbers. To represent 35minutes write 3 to bits 4-6, and write 5 to bits 0-3.

The CH bit of address 0x00 indicates a power failure, and is reset by our update. Bit 6 of address 0x02 toggles between 12 and 24 hour time, we cleared it for 24 hour time. The control register configures the square wave output pin (pin1), see page 9 of the datasheet for an overview of its functions.

Now, read back the time.

I2C>[0xd0 0 [0xd1 rrrrrrrr]
WRITE: 0xD0 ACK<< DS1307 write address
WRITE: 0x00 ACK<< set write pointer
WRITE: 0xD1 ACK<< DS1307 read address
READ: 0x30 ACK<< 30 seconds
READ: 0x30 ACK<< 30 minutes
READ: 0x09 ACK<< 9 hours, 24 hour clock mode
READ: 0x02 ACK<< Monday (day 2)
READ: 0x07 ACK<< 7th (date)
READ: 0x09 ACK<< September (month)
READ: 0x09 ACK<< ’09 (year)
READ: 0x00 NACK<< Control register

Read the time by setting the address pointer to 0 with a partial write operation ([0xd0 0), then reading 8 bytes from the read address (0xd1). We could have used a repeated read command (r:8), but we wanted to address each individual byte in the demonstration. We did this immediately after setting the time, so only 30 seconds have elapsed: 9:30:30 Monday 09/07/09.

The DS1307 also has a bit of additional RAM that can be used for general purpose storage.

I2C>[0xd0 8 3 2 1]
WRITE: 0xD0 ACK<< DS1307 write address
WRITE: 0x08 ACK<< set write pointer to 0x08
WRITE: 0x03 ACK<< write these values

The RAM starts at memory address 0x08, and continues to 0x3f. Write to it just like the previous registers: send the I2C write address (0xd1), the location to start writing (8), and the values to store (3 2 1).

I2C>[0xd0 8 [ 0xd1 r:3]
WRITE: 0xD0 ACK<< DS1307 write address
WRITE: 0x08 ACK<< set write pointer to 0x08
WRITE: 0xD1 ACK<< DS1307 read address
READ 0x03 BYTES:<< read back three values
0x03 ACK 0x02 ACK 0x01 NACK

Reading from the RAM is also straight forward. Set the starting memory address with a partial write command ([0xd0 8), then read data from the read address ([0xd1 r:3]). We got the same values we entered (3 2 1).

If you liked this chip demonstration, there’s a bunch more in the Bus Pirate manual. We love special requests, please post them in the comments.

This entry was posted on Friday, September 4th, 2009 at 8:44 am and is filed under Bus Pirate, Chips. You can follow any responses to this entry through the RSS 2.0 feed. You can skip to the end and leave a response. Pinging is currently not allowed.

8 Responses to “Chips: DS1307 I2C real-time clock”

  1. Mike says:

    I am trying this on BPir 3 and get no response. The scan for address (1)
    goes thru all addresses. I can see the clock on the Cheap Logic Analyzer, but the Data is pulled high. No action on the data line?
    I have tried pullups with BP and with Resistors. No difference.

    • Ian says:

      Hey Mike – I’m not sure about this one. Pull-up resistors are the go-to problem for I2C. What version of the firmware are you using? Does the Bus Pirate pass the self-test? Feel free to post your session output in the forum and I’ll take a look at it.

      • Mike says:

        Thanks, I got the Example to the DS1307 working now!
        I had no data BECAUSE I was using the wrong PIN on BP for DATA!
        Stupid me, have a hard time reading the print on the pcb!

        I am using Real Term and using the mouse copied and pasted the date time setting and reading examples directly from the demo!
        I had no idea that would work?

        Neat, I would like a Macro? I don’t know how to batch things in real term, but the chip looks like it is working like the demo!

        Amazing! I am using the your v3 BP with 4.1 bootloader and firmware.
        Awaiting the new Logic Sniffer! How is the build going?

        Thanks for the help and very interesting projects!

  2. Mike says:

    “Searching 7bit I2C address space.
    Found devices at:
    0xD0(0×68 W) 0xD1(0×68 R)”

    From example and it works on my hardware!

    I am having problems understanding this address search?

    0xD0 is 1101 | 0000 and MASK B7 off is 0101 | 0000 which is 0x50?

    I am confused about the read and write addresses in the DS1307 to be
    I have been looking at the data sheet, but still don’t understand the addressing!


  3. Kandarp Thaker says:

    Please send me C code of above explaination…on my email id…
    thank you

  4. clara says:

    Please, someone can help me to use this RTC with Jennic…????? I spent 3 weeks, and i havent work it. I try with a lot of codes!!! thanks!!

Leave a Reply

Notify me of followup comments via e-mail. You can also subscribe without commenting.

Recent Comments

  • lostengineer: hahaha an entire article just saying to heat-shrink your wires or glue them if they might move around a lot. When did common sense die?
  • readybrek: They're tasty tasty very very tasty... they're very tasty.
  • hli: Sunday++
  • Chamod: Check on your buddy. Make sure they don't forget their lunchbox.
  • Kurt: But February made me shiver With every paper I'd deliver Bad news on the doorstep I couldn't take one more step