主要特性
DS1307是Maxim的串行、I2C實時時鍾芯片。主要特性有:
- 工作電壓:主電源電壓4.5~5.5V,電池電壓2.0~3.5V
- 功耗:電池供電、備份模式時<500nA
- 接口:I2C,最大速率100kbps
- 可編程方波輸出
- 電源自動切換、失效檢測
- 內置56字節大小、支持電池備份的RAM
- 封裝:8-Pin SO/PDIP
管腳定義

- X1、X2: 接32.768kHz晶體,要求晶體負載電容12.5pF
- Vcc:主電源,范圍4.5~5.5V。當需要對DS1307讀寫時,需要接Vcc。
- VBAT:接電池,范圍2.0~3.5V。
- GND:地
- SDA、SCL:I2C接口數據線、時鍾線。
- SQW/OUT:方波輸出腳、通過寫寄存器來使能。
與Arduino的連接
采用I2C接口與Arduino連接。SQW/OUT腳亦為開漏(open-drain)設計,需要接上拉電阻。

DS1307的VCC腳接Arduino UNO的5V;GND腳接Arduino UNO的GND;SDA腳接Arduino UNO的A4(SDA);SCL腳接Arduino UNO的A5(SCL)。
功能調試
1. 寫寄存器時,先寫入寄存器指針(Register pointer),之后依次寫入寄存器內容。每寫入一個字節,Register pointer都自動加一。
2. 讀寄存器時,也是先寫入Register pointer,之后發Sr(Repeated start),依次讀出寄存器內容。同樣的,每讀出一個字節,Register pinter都自動加一。
測試代碼
1. 首先設置DS1307時間。代碼中timeDec數組保存的是當前時間,根據實際調整。
1 /* 2 real time clock using DS1307 3 function: set the time 4 */ 5 6 #include <Wire.h> 7 8 #define ADDRESS_DS1307 0x68 9 10 byte timeDec[] = {15, 1, 15, 5, 19, 20, 0}; 11 byte timeBcd[] = {0, 0, 0, 0, 0, 0, 0}; 12 //time = {year, month, date, day, hours, minutes, seconds}; 13 14 void setup() 15 { 16 Wire.begin(); 17 Serial.begin(9600); 18 19 //convert decimal to BCD code 20 int i; 21 for (i = 0; i < 7; i++) 22 { 23 timeBcd[i] = DecToBcd(timeDec[i]); 24 } 25 26 //set the time 27 Wire.beginTransmission(ADDRESS_DS1307); 28 Wire.write(0x00); 29 for (i = 0; i < 7; i++) 30 { 31 Wire.write(timeBcd[6-i]); 32 } 33 Wire.endTransmission(); 34 35 Serial.println("Time has been set."); 36 37 } 38 39 void loop() 40 { 41 delay(4000); 42 } 43 44 // Convert normal decimal numbers to binary coded decimal 45 byte DecToBcd(byte val) 46 { 47 byte res; 48 if ((val <= 99) && (val >= 0)) 49 { 50 res = ((val/10)<<4) | (val%10); 51 } 52 else 53 { 54 res = 0; 55 Serial.println("Error"); 56 } 57 return res; 58 } 59 // Convert binary coded decimal to normal decimal numbers 60 byte BcdToDec(byte val) 61 { 62 byte res; 63 if (val <= 0x99) 64 { 65 res = (val >> 4)*10 + (val & 0x0F); 66 } 67 else 68 { 69 res = 0; 70 Serial.println("Error"); 71 } 72 return res; 73 }
2. 之后可以向DS1307獲取實時時間。
1 /* 2 real time clock using DS1307 3 function: read the time 4 */ 5 6 #include <Wire.h> 7 8 #define ADDRESS_DS1307 0x68 9 10 byte timeBcd[] = {0, 0, 0, 0, 0, 0, 0}; 11 //time = {year, month, date, day, hours, minutes, seconds}; 12 13 void setup() 14 { 15 Wire.begin(); 16 Serial.begin(9600); 17 } 18 19 void loop() 20 { 21 //read the time 22 Wire.beginTransmission(ADDRESS_DS1307); 23 Wire.write(0x00); 24 Wire.endTransmission(); 25 Wire.requestFrom(ADDRESS_DS1307, 7); 26 if (Wire.available() >= 7) 27 { 28 for (int i = 0; i < 7; i++) 29 { 30 timeBcd[6-i] = Wire.read(); 31 } 32 } 33 34 //print 35 Serial.print("20"); Serial.print(timeBcd[0], HEX); Serial.print("/"); 36 Serial.print(timeBcd[1], HEX); Serial.print("/"); Serial.print(timeBcd[2], HEX); 37 Serial.print(" "); Serial.print(BcdToDay(timeBcd[3])); Serial.print(" "); 38 Serial.print(timeBcd[4], HEX); Serial.print(":"); 39 Serial.print(timeBcd[5], HEX); Serial.print(":"); 40 Serial.print(timeBcd[6], HEX); Serial.println(); 41 42 delay(1000); 43 } 44 45 46 // Convert binary coded decimal to day 47 String BcdToDay(byte val) 48 { 49 String res; 50 switch(val) 51 { 52 case 1: res = "Sunday"; break; 53 case 2: res = "Monday"; break; 54 case 3: res = "Tuesday"; break; 55 case 4: res = "Wednesday"; break; 56 case 5: res = "Thursday"; break; 57 case 6: res = "Friday"; break; 58 case 7: res = "Saturday"; break; 59 default: res = "Error!"; 60 } 61 return res; 62 }
程序運行后,通過串口打印當前時間如下圖。

3. 通過設置控制寄存器,可以設置SQW/OUT管腳輸出高電平、低電平或某個頻率的方波。方波支持的頻率有1Hz、4.096kHz、8.192kHz、32.768kHz。以下代碼設置的頻率為32.768kHz。
1 /* 2 real time clock using DS1307 3 function: output the square-wave 4 */ 5 6 #include <Wire.h> 7 8 #define ADDRESS_DS1307 0x68 9 #define CONTROL_REGISTER 0x07 10 11 void setup() 12 { 13 Wire.begin(); 14 Serial.begin(9600); 15 16 //set the time 17 Wire.beginTransmission(ADDRESS_DS1307); 18 Wire.write(CONTROL_REGISTER); 19 Wire.write(0b00010011); //frequency = 32.768kHz 20 Wire.endTransmission(); 21 22 Serial.println("Square-wave output is enabled."); 23 } 24 25 void loop() 26 { 27 delay(4000); 28 }
與示波器測試的信號圖形相符。

參考資料
Maxim - DS1307 64x8、串行、I²C實時時鍾
Tutorial – Using DS1307 and DS3231 Real-time Clock Modules with Arduino
Digital Clock with Arduino and DS1307
Assemble an Adafruit DS1307 Real Time Clock Kit
