Arduino I2C + DS1307实时时钟

主要特性

DS1307是Maxim的串行、I2C实时时钟芯片。主要特性有:

  • 工作电压:主电源电压4.5~5.5V,电池电压2.0~3.5V
  • 功耗:电池供电、备份模式时<500nA
  • 接口:I2C,最大速率100kbps
  • 可编程方波输出
  • 电源自动切换、失效检测
  • 内置56字节大小、支持电池备份的RAM

管脚定义

  • 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

时间: 2024-12-28 21:00:06

Arduino I2C + DS1307实时时钟的相关文章

I2C实时时钟rx-8025板卡实际应用

rx-8025是片外I2C实时时钟,其应用于9260板卡方法如下.总体思想是配置内核添加驱动(I2C驱动,内核已提供的很完备),板级文件添加设备,添加设备文件以应用程序操作. 1. 配置内核 1)I2C支持(可选择debug信息). 2)I2Chw选择gpio作为I2C硬件. 3)不选择片上RTT,选择芯片RX-8025. 其中rtc0为设备启动时钟. 2. 添加设备 /arch/arm/mach-at91/board-sam9260ek.c中添加以下语句:static struct i2c_b

Maxim实时时钟芯片设计指南5791-关于编写健壮的实时时钟控制代码的提示

用DS12C887设计一个万年历,虽然反复查看说明书,还是出各种的错误. 因此,从美信官网查询资料,翻译的不太通,凑合着对照看. 原文链接 Tips for Writing Bulletproof Real-Time Clock Control Code 关于编写健壮的实时时钟控制代码的提示 摘要 : With the use of proper device initialization and code sequencing, accurate timekeeping and clock a

linux 实时时钟(RTC)驱动【转】

本文转载自:http://blog.csdn.net/yaozhenguo2006/article/details/6820218 这个是linux内核文档关于rtc实时时钟部分的说明,此文档主要描述了rtc实时时钟的作用和编程接口,分别介绍了老的rtc接口和新的rtc类架构.并给出了一个测试rtc驱动的程序.     linux 实时时钟(RTC)驱动                                                                        

【转】VxWorks中高精度实时时钟的实现及C语言汇编混合编程

最近一个项目中需要在VxWorks下使用一个高精度实时时钟,要求精度为1ms,溢 出时间大于5小时.VxWorks提供系统时钟,该时钟在操作系统启动后开始计数,精度为1个tick,可以通过tickGet()获取当前计数值.因为 系统时钟默认工作频率为60Hz,则1个tick相当于16.7ms,不符号我们的精度要求.虽然可以通过sysClkRateSet(1000),把精度提高到1ms,但1kHz的系统时钟中断频率会使得CPU的开销大增.考虑到像nanoSleep()这样的应用其计时精度可以达到纳

STM32学习笔记10(实时时钟RTC)

对于单片机转ARM的同学来说,RTC可能比较少接触.提到实时时钟,更经常想到的是DS1302.当然,在STM32里,自己一个CPU已经足够,不需要DS1302. 实际上,RTC就只一个定时器而已,掉电之后所有信息都会丢失,因此我们需要找一个地方来存储这些信息,于是就找到了备份寄存器.因为它掉电后仍然可以通过纽扣电池供电,所以能时刻保存这些数据.我们在本期教程中将详细讲述RTC原理及例程,以引导大家顺利进入RTC的世界. 1.STM32的RTC模块 RTC模块之所以具有实时时钟功能,是因为它内部维

RTC实时时钟驱动

RTC(Real-Time Clock)实时时钟为操作系统提供了一个可靠的时间,并且在断电的情况下,RTC实时时钟也可以通过电池供电,一直运行下去. RTC通过STRB/LDRB这两个ARM指令向CPU传送8位数据(BCD码).数据包括秒,分,小时,日期,天,月和年.RTC实时时钟依靠一个外部的32.768Khz的石英晶体,产生周期性的脉冲信号.每一个信号到来时,计数器就加1,通过这种方式,完成计时功能. RTC实时时钟有如下一些特性: 1,BCD数据:这些数据包括秒.分.小时.日期..星期几.

STM32F4学习笔记10——RTC实时时钟

RTC实时时钟 实时时钟 (RTC) 是一个独立的 BCD 定时器/计数器.RTC 提供一个日历时钟.两个可编程 闹钟中断,以及一个具有中断功能的周期性可编程唤醒标志.RTC 还包含用于管理低功耗模 式的自动唤醒单元. 两个 32 位寄存器包含二进码十进数格式 (BCD) 的秒.分钟.小时(12 或 24 小时制).星 期几.日期.月份和年份.此外,还可提供二进制格式的亚秒值. 系统可以自动将月份的天数补偿为 28.29(闰年).30 和 31 天.并且还可以进行夏令时 补偿. 其它 32 位寄

RTC实时时钟

作者:宋老师,华清远见嵌入式学院讲师. 1.1 RTC介绍 在 一个嵌入式系统中,通常采用RTC 来提供可靠的系统时间,包括时分秒和年月日等,而且要求在系统处于关机状态下它也能够正常工作(通常采用后备电池供电).它的外围也不需要太多的辅助电 路,典型的就是只需要一个高精度的32.768kHz晶体和电阻电容等,如图10-8所示. 图10-8 RTC外接电路 1.2 RTC控制器 实时时钟(RTC)单元可以通过备用电池供电,因此,即使系统电源关闭,它也可以继续工作.RTC 可以通过STRB/LDRB

cortex_m3_stm32嵌入式学习笔记(十四):RTC实时时钟(秒中断)

STM32 的实时时钟( RTC)是一个独立的定时器. STM32 的 RTC 模块拥有一组连续计数的计数器,在相应软件配置下,可提供时钟日历的功能.修改计数器的值可以重新设置系统当前的时间和日期. 由于时钟只需要配置一次,下次开机不需要重新配置(开发板有电池的情况下),所以需要用到备份区域(BKP)来标记是否配置过时钟 简单介绍BKP:备份寄存器是 42 个 16 位的寄存器( Mini 开发板就是大容量的),可用来存储 84 个字节的用户应用程序数据.他们处在备份域里, 当 VDD 电源被切