DS1307:

Read routine.

Projects Home

 

  The DS1307 datasheet is quite confusing because the read routine seems not to be the same as with an i²c EEPROM. However, it is, basically. So when reading from the DS1307 (=Slave) and seen by the PIC's point of view (=Master), we have to:

1) Send a START, write the device address (0xd0) (last bit is 0 for write), wait for ACK.

2) Write the word address (sets the first register to read from, which is 0x00 here), wait for ACK.

3) Send a REPEATED START, write the device address again (0xd1) (last bit is 1 for read), wait for ACK.

4) Read the first byte, wait for ACK.

5) Repeat step 4) for next bytes.

6) Read the last byte, no wait for ACK, send STOP.

 

We have to repeat this whole cycle each time we start reading the DS1307 registers, otherwise they will be incremented automatically, and not set to zero.

Also see the EEPROM 24C256 datasheet, and figure 8-2, Random Read. Only difference is we have to omit the "address low byte" part for the DS1307.

 

Hi-Tech PICC:

void rtc_read(unsigned char *rtc_buffer)

SEN = 1;                                   // 1) send start bit START    
while(SEN);                             // and wait for it to clear
ACKDT = 0;                            // acknowledge bit

SSPIF = 0;                                //  
SSPBUF = 0xd0;                     // set device address 0xd0 // write SLAVE ADDRESS
while(!SSPIF);                        // wait for interrupt
SSPIF = 0;                               // then clear it.

SSPBUF = 0;                          //
2) write to address 0 = register 0, WORD ADDRESS - control 1
while(!SSPIF);                       // wait for interrupt
SSPIF = 0;                              // then clear it.

RSEN = 1;                               //
3) send repeated start bit REPEATED START
while(RSEN);                         // and wait for it to clear

SSPIF = 0;
SSPBUF = 0xd1;                   // set device address - write WORD ADDRESS - CONTROL 2
while(!SSPIF);                      // wait for interrupt
SSPIF = 0;                             // then clear it.

RCEN = 1;                                 //
4) start receiving READ & ACK buffer 0
while(!STAT_BF);                  // wait for data
rtc_buffer[0] = SSPBUF;        // and get it              // buffer 0
ACKEN = 1;                             // start acknowledge sequence
while(ACKEN);                       // wait for ack. sequence to end

// 5)

RCEN = 1;                                         // 6) start receiving READ LAST & NO ACK buffer 7
while(!STAT_BF);                          // wait for data
rtc_buffer[7] = SSPBUF;                // and get it     // buffer 7
ACKDT = 1;                                    // not acknowledge for last byte

PEN = 1;                                           // send stop bit STOP
while(PEN);