Arduino I2C + DS1307實時時鍾


主要特性

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 }
View Code

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 }
View Code

程序運行后,通過串口打印當前時間如下圖。

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 }
View Code

與示波器測試的信號圖形相符。


參考資料

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM