Real Time Clock (RTC)
DS1307
There are two almost identical breakout boards available - one from SparkFun for $20 and one from Adafruit for $9. I prefer the one from Adafruit. It is lightly larger, but it is much cheaper, has a better pin layout, and it is better supported.
The Register
It is good to read the complete DS1307 Datasheet
, but here is a summary:
| Address |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Function |
Range |
| 0x00 |
CH |
10 Seconds |
1 Seconds |
Seconds |
0x00-0x59 |
| 0x01 |
0 |
10 Minutes |
1 Minutes |
Minutes |
0x00-0x59 |
| 0x02 |
0 |
12h |
AM/PM |
10 Hour |
1 Hour |
Hours |
0x01-0x12 |
| 24h |
10 Hour |
0x00-0x23 |
| 0x03 |
0 |
0 |
0 |
0 |
0 |
Day |
Day |
0x01-0x07 |
| 0x04 |
0 |
0 |
10 Date |
1 Date |
Date |
0x01-0x31 |
| 0x05 |
0 |
0 |
0 |
10 Month |
1 Month |
Month |
0x01-0x12 |
| 0x06 |
10 Year |
1 Year |
Year |
0x00-0x99 |
| 0x07 |
OUT |
0 |
0 |
SQWE |
0 |
0 |
RS1 |
RS0 |
Control |
- |
| 0x08-0x3F |
RAM |
RAM |
0x00-0xFF |
Bus Pirate
Setup
HiZ> m 4 3 1
I2C (mod spd)=( 0 2 )
Ready
I2C> W
Power supplies ON
I2C> P
Pull-up resistors ON
I2C>
Setting Clock
I2C> [ 0xd0 0 0x00 0x20 0x16 3 0x01 0x09 0x10 0 ]
I2C START BIT
WRITE: 0xD0 ACK
WRITE: 0x00 ACK
WRITE: 0x00 ACK
WRITE: 0x20 ACK
WRITE: 0x16 ACK
WRITE: 0x02 ACK
WRITE: 0x01 ACK
WRITE: 0x09 ACK
WRITE: 0x10 ACK
WRITE: 0x00 ACK
I2C STOP BIT
I2C>
Wire.beginTransmission(DS1307_ADDRESS);
Wire.send(0);
Wire.send(bin2bcd(dt.second()));
Wire.send(bin2bcd(dt.minute()));
Wire.send(bin2bcd(dt.hour()));
Wire.send(bin2bcd(0));
Wire.send(bin2bcd(dt.day()));
Wire.send(bin2bcd(dt.month()));
Wire.send(bin2bcd(dt.year() - 2000));
Wire.send(0);
Wire.endTransmission();
Reading the Clock
I2C> [ 0xd0 0 ] [ 0xd1 r:7 ]
I2C START BIT
WRITE: 0xD0 ACK
WRITE: 0x00 ACK
I2C STOP BIT
I2C START BIT
WRITE: 0xD1 ACK
READ: 0x00 ACK 0x20 ACK 0x16 ACK 0x03 ACK 0x01 ACK 0x09 ACK 0x10
NACK
I2C STOP BIT
I2C>
Wire.beginTransmission(DS1307_ADDRESS);
Wire.send(0);
Wire.endTransmission();
Wire.requestFrom(DS1307_ADDRESS, 7);
uint8_t ss = bcd2bin(Wire.receive() & 0x7F);
uint8_t mm = bcd2bin(Wire.receive());
uint8_t hh = bcd2bin(Wire.receive());
Wire.receive();
uint8_t d = bcd2bin(Wire.receive());
uint8_t m = bcd2bin(Wire.receive());
uint16_t y = bcd2bin(Wire.receive()) + 2000;
DS3231