亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Manufacturing Technology >> 制造工艺

基于 RTC 的时钟

组件和用品

Arduino Nano R3
× 1
实时时钟 (RTC)
我使用了基于ds1307的RTC模块。使工作轻松很多。但是你可以自己做一个很容易。
× 1
4 位七段 LED 显示屏
× 1
女性表头单行
× 3
穿孔板
如果你想焊接这个项目并让它呈现出来,请获取这个。为了使焊接容易获得具有像面包板一样的痕迹的焊锡板。
× 1
跳线(通用)
× 25
男性标题 40 位置 1 行 (0.1")
× 1

必要的工具和机器

烙铁(通用)
万用表
每个项目都需要一个万用表。所以投资一个标准对,它至少可以使用 4 年,如果你知道如何修理它可能会更多。您将需要它来检查焊接的连通性并检查电路吸收的电流。

应用和在线服务

Arduino IDE
Arduino Fritzing

关于这个项目

这是一个非常简单、易于组装的数字时钟,使用 RTC DS1307 IC 创建。带液晶显示器。它只是在 4 位七段显示器上显示时间。代码也可以很容易地调整以赋予它额外的功能,比如警报,你需要的只是一点想象力和独创性。这个项目只是为了更好和更复杂的东西的垫脚石,而且我想制作一些很酷的东西,放在我的房间里展示。

说了这么多,我将在这篇文章中包含每一个小细节,包括我在将其焊接到 PCB 上时遇到的问题以及我如何解决这些问题。

第 1 步:组件

RTC 模块

DS1307 芯片真的很棒,因为它即使在断电期间也能跟踪时间。它很容易与 Arduino 连接,并且有很多库可用于处理这个模块。 RTC 通过 I2C 协议与 Arduino 接口。不用担心Arduino nano上的引脚A4和A5用于I2C通信的协议细节。

  • SDA - A4
  • SCL - A5

我们将不需要此项目的 DS 引脚。

唯一的缺点是它不像我们希望的那样准确。芯片很容易受到时间漂移的影响,很容易随着温度的变化偏离实际时间。

注意 - 确保正确连接 GND 和 Vcc 引脚。 Vcc 放置在(在模块中)GND 引脚之前。我以相反的极性连接了我的几次,它变得非常热非常快。因此,如果您将极性接反,只需在打开纽扣电池时触摸纽扣电池,并在感觉到它变热时迅速将其关闭。

移位寄存器 (74HC595)

  • 移位寄存器 74HC595 是使之成为可能的芯片,这要归功于多路复用技术。初学者不要害怕这个看起来很吓人的术语,它很有趣,你会很高兴你学会了它。
  • 595 有 16 个引脚,我们将使用两个移位寄存器与 4 位 7 段显示器进行交互。
  • 第一个移位寄存器用于点亮段,第二个移位寄存器用于选择 I 将点亮的数字。
  • 多亏了多路复用技术,数字之间的切换速度如此之快。似乎所有数字都同时显示。

注意:这些芯片非常可靠,但我碰巧遇到了几个有问题的芯片。在某些芯片中,Q0 和 Q1 不起作用。有些将 Q3 内部接地(构造错误)。我现在项目中的那些也不完全完美。其中一个的 Q7 有问题,所以当我和他们一起工作时,我必须确保我的连接是准确的,当他们仍然不工作时,我使用万用表的连续性功能检查引脚。总而言之,我没有抱怨,因为在做项目时学会克服小障碍都是一种手段。

4位七段显示

我使用了一个通用的 4 位数段(普通阳极 )。它有 12 个引脚,编号从左下角开始,到左上角引脚结束。每个段都能够显示数字和小数点。因此,由于我没有数字时钟典型的酷炫冒号,因此我不得不使用第二位数字的小数点。当您的主要目标是显示数字时,这些是很好的显示。

注意:这些对于初学者来说可能非常棘手,因为段 a-g 不在同一行。小心,不要在没有任何限流电阻的情况下将它们连接到 5v 电源。

我已经包含了一个原理图,它非常不言自明。

原理图的显示类型与我在项目中使用的显示类型不同,因此这里是从移位寄存器到段的引脚连接。

段 引脚号在显示屏上 移位寄存器引脚

A 11 15

乙7 1

的C 4 2

d 2 3

ë1 4

˚F10 5

克5 6

十进制3 7

D1 12 15(第二595)

D2 9 1(第2 595)

D3 8 2(第二595)

D4 6 3(第二595)

这个项目既便宜又容易制作,但需要一点耐心和毅力(也就是说,如果您愿意加倍努力将其焊接在 PCB 上)。如果你只是想尝试一下,它几乎不需要 2 小时。

请就我如何改进这一点提供反馈,如果帖子中没有明确提及任何内容。

代码

  • 时钟代码
  • 设置时间
  • RealTimeClockDS1307.cpp
  • 自述文件
  • RealTimeClockDS1307.h
  • 另一个文件
  • RTClib 文件
  • library.properties(名称)
  • RTClib
  • RTClib
  • README.md
  • RTClib.cpp
  • RTClib.h
时钟代码 Arduino
代码使用了 RTC 库和 I2C 库。您需要这些库才能执行程序。此程序用于共阳极型显示。
#include #include#include RTC_DS1307 RTC;int temp, inc, hours1, minut, add =11;int小时,分钟,秒;int latchPin =3; //引脚 12 上 595 o3 3int dataPin =4; // 595 或 4int 上的引脚 14 clockPin =2; //595 或 2int 上的引脚 11 shift =256;int 单位,十,百,千;int x;int y;const int alarmHour =17;const int alarmMinute =26;void setup() { Serial.begin(9600 ); pinMode(latchPin, OUTPUT);引脚模式(数据引脚,输出); pinMode(clockPin, 输出); pinMode(13,输出); Wire.begin(); RTC.begin(); if (!RTC.isrunning()) { RTC.adjust(DateTime(__DATE__, __TIME__)); }}void loop() { int temp =0, val =1, temp4;现在日期时间 =RTC.now(); HOUR =now.hour(); MINUT =now.minute(); //Serial.println(MINUT);如果(小时 <10){ 数百 =小时;千 =小时/10; } else if (HOUR>=10 &&HOUR <24) { 数百 =HOUR % 10;千 =小时 / 10; } if (MINUT <=9) { 单位 =MINUT;十 =分钟/10; } else if (MINUT> 9 &&MINUT <=60) { 单位 =MINUT % 10;十 =分钟 / 10; } switch (units) { case 0://0 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 192 );数字写入(闩锁销,高);休息; case 1://1 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 249);数字写入(闩锁销,高);休息; case 2://2 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 164);数字写入(闩锁销,高);休息; case 3://3 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 176);数字写入(闩锁销,高);休息; case 4://4 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 153);数字写入(闩锁销,高);休息; case 5://5 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 146);数字写入(闩锁销,高);休息; case 6://6 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 130);数字写入(闩锁销,高);休息; case 7://7 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 248);数字写入(闩锁销,高);休息; case 8://8 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 128);数字写入(闩锁销,高);休息; case 9://9 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 8 + 144);数字写入(闩锁销,高);休息; } 延迟(1); switch (tens) { case 0://0 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 192 );数字写入(闩锁销,高);休息; case 1://1 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 249);数字写入(闩锁销,高);休息; case 2://2 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 164);数字写入(闩锁销,高);休息; case 3://3 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 176);数字写入(闩锁销,高);休息; case 4://4 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 153);数字写入(闩锁销,高);休息; case 5://5 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 4 + 146);数字写入(闩锁销,高);休息; } 延迟(1);开关(数百){ case 0://0 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 64 );数字写入(闩锁销,高);休息; case 1://1 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 121);数字写入(闩锁销,高);休息; case 2://2 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 36);数字写入(闩锁销,高);休息; case 3://3 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 48);数字写入(闩锁销,高);休息; case 4://4 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 25);数字写入(闩锁销,高);休息; case 5://5 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 18);数字写入(闩锁销,高);休息; case 6://6 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 2);数字写入(闩锁销,高);休息; case 7://7 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 120);数字写入(闩锁销,高);休息; case 8://8 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 0);数字写入(闩锁销,高);休息; case 9://9 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift * 2 + 16);数字写入(闩锁销,高);休息; } 延迟(1);开关(千){ case 0://0 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 192 );数字写入(闩锁销,高); //延迟(500);休息; case 1://1 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 249);数字写入(闩锁销,高); //延迟(500);休息; case 2://2 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 164);数字写入(闩锁销,高); //延迟(500);休息; case 3://3 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 176);数字写入(闩锁销,高); //延迟(500);休息; case 4://4 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 153);数字写入(闩锁销,高); //延迟(500);休息; case 5://5 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 146);数字写入(闩锁销,高); //延迟(500);休息; case 6://6 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 130);数字写入(闩锁销,高); //延迟(500);休息; case 7://7 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 248);数字写入(闩锁销,高); //延迟(500);休息; case 8://8 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 128);数字写入(闩锁销,高);休息; case 9://9 digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, MSBFIRST, shift>> 8 ); shiftOut(dataPin, clockPin, MSBFIRST, shift + 152);数字写入(闩锁销,高);休息; } 延迟(1); //报警部分 if (HOUR ==alarmHour &&MINUT ==alarmMinute) { digitalWrite(13, HIGH); } else { 数字写入(13,低); }}
设置时间Arduino
因为 ds1307 很容易偏离正确的时间。该程序允许您通过串行监视器设置时间。当您发现时间不正确时,只需将 rtc 模块插入 arduino 并上传该程序。然后进入串行监视器,然后设置正确的日期、月份、年份、时间。然后只需上传其他程序,正确的时间将显示在 7 段显示器上。
/* RealTimeClockDS1307 - 控制 DS1307 RTC 模块的库 版权所有 (c) 2011 David H. Brown。保留所有权利 非常感谢 John Waters 和 Maurice Ribble 早期且非常有帮助的工作(即使我没有使用他们的任何代码): - http://combusstory.com/wiki/index.php/RTC1307_ -_Real_Time_Clock - http://www.glacialwanderer.com/hobbyrobotics/?p=12 这个库是免费软件;您可以根据自由软件基金会发布的 GNU 宽松通用公共许可证的条款重新分发和/或修改它;许可证的 2.1 版,或(由您选择)任何更高版本。这个库是分发的,希望它有用,但没有任何保证;甚至没有对适销性或针对特定目的的适用性的暗示保证。有关更多详细信息,请参阅 GNU 宽松通用公共许可证。您应该已经收到一份 GNU 宽松通用公共许可证以及这个库;如果没有,请写信给 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/#include #include //RealTimeClock RTC;// =new RealTimeClock();#define Display_Clock_Every_N_Seconds 1#define Display_ShortHelp_Every_N_Seconds 25//#define TEST_Squarewave//#define TEST_StopStart//#define TEST_1224Switchint count=0;char formatted[] ="00-00-000:00;void setup() {// Wire.begin(); Serial.begin(9600);} void loop() { if(Serial.available()) { processCommand(); } 延迟(1000); RTC.readClock();计数++; if(count % Display_Clock_Every_N_Seconds ==0){ Serial.print(count); Serial.print(":"); RTC.getFormatted(格式化); Serial.print(格式化); Serial.println(); } if(count % Display_ShortHelp_Every_N_Seconds ==0) { Serial.println("Send ? for a list of commands."); }#ifdef TEST_Squarewaveif(count%10 ==0){ switch(count/10 % 6) { case 0:Serial.print("Squarewave disabled (低阻抗):"); RTC.sqwDisable(0); Serial.println((int) RTC.readData(7));休息; case 1:Serial.print("方波禁用(高阻抗):"); RTC.sqwDisable(1); Serial.println((int) RTC.readData(7));休息; case 2:Serial.println("Squarewave 在 1 Hz 时启用"); RTC.sqwEnable(RTC.SQW_1Hz);休息; case 3:Serial.println("Squarewave 在 4.096 kHz 启用"); RTC.sqwEnable(RTC.SQW_4kHz);休息; case 4:Serial.println("Squarewave 在 8.192 kHz 启用"); RTC.sqwEnable(RTC.SQW_8kHz);休息; case 5:Serial.println("Squarewave 在 32.768 kHz 下启用"); RTC.sqwEnable(RTC.SQW_32kHz);休息;默认值:Serial.println("未定义方波测试"); }//switch}#endif#ifdef TEST_StopStartif(count%10 ==0){ if(!RTC.isStopped()) { if(RTC.getSeconds() <45) { Serial.println("停止时钟10秒"); RTC.stop(); }//如果我们有足够的时间 } else { RTC.setSeconds(RTC.getSeconds()+11); RTC.start(); Serial.println("增加11秒并重新启动时钟"); }}//如果是10的倍数#endif#ifdef TEST_1224Switch if(count%10 ==0) { if(count %20 ==0) { Serial.println("切换到12小时制"); RTC.switchTo12h(); RTC.setClock(); } else { Serial.println("切换到24小时制"); RTC.switchTo24h(); RTC.setClock(); } }#endif}void processCommand() { if(!Serial.available()) { return; }字符命令 =Serial.read(); int in,in2; switch(command) { case 'H':case 'h':in=SerialReadPosInt(); RTC.setHours(in); RTC.setClock(); Serial.print("设置时间为"); Serial.println(in);休息; case 'I':case 'i':in=SerialReadPosInt(); RTC.setMinutes(in); RTC.setClock(); Serial.print("设置分钟为"); Serial.println(in);休息; case 'S':case 's':in=SerialReadPosInt(); RTC.setSeconds(in); RTC.setClock(); Serial.print("设置秒为"); Serial.println(in);休息; case 'Y':case 'y':in=SerialReadPosInt(); RTC.setYear(in); RTC.setClock(); Serial.print("设置年份为"); Serial.println(in);休息; case 'M':case 'm':in=SerialReadPosInt(); RTC.setMonth(in); RTC.setClock(); Serial.print("设置月份为"); Serial.println(in);休息; case 'D':case 'd':in=SerialReadPosInt(); RTC.setDate(in); RTC.setClock(); Serial.print("设置日期为"); Serial.println(in);休息; case 'W':Serial.print("星期几是"); Serial.println((int) RTC.getDayOfWeek());休息; case 'w':in=SerialReadPosInt(); RTC.setDayOfWeek(in); RTC.setClock(); Serial.print("设置星期几为"); Serial.println(in);休息; case 't':case 'T':if(RTC.is12hour()) { RTC.switchTo24h(); Serial.println("切换到 24 小时制。"); } else { RTC.switchTo12h(); Serial.println("切换到 12 小时制。"); RTC.setClock();休息;案例“A”:案例“a”:if(RTC.is12hour()) { RTC.setAM(); RTC.setClock(); Serial.println("设置上午。"); } else { Serial.println("(仅在 24 小时模式下设置小时。)"); } 休息;案例'P':案例'p':if(RTC.is12hour()) { RTC.setPM(); RTC.setClock(); Serial.println("设置下午。"); } else { Serial.println("(仅在 24 小时模式下设置小时。)"); } 休息; case 'q':RTC.sqwEnable(RTC.SQW_1Hz); Serial.println("方波输出设置为1Hz");休息; case 'Q':RTC.sqwDisable(0); Serial.println("方波输出禁用(低)");休息;案例'z':RTC.start(); Serial.println("时钟振荡器启动。");休息;案例'Z':RTC.stop(); Serial.println("时钟振荡器停止。");休息; case '>':in=SerialReadPosInt(); in2=SerialReadPosInt(); RTC.writeData(in, in2); Serial.print("写入寄存器"); Serial.print(in); Serial.print("值​​"); Serial.println(in2);休息; case '<':in=SerialReadPosInt(); in2=RTC.readData(in); Serial.print("从寄存器读取"); Serial.print(in); Serial.print("值​​"); Serial.println(in2);休息;默认值:Serial.println("未知命令。试试这些:"); Serial.println(" h## - 设置小时数 d## - 设置日期"); Serial.println(" i## - 设置分钟数 m## - 设置月份"); Serial.println(" s## - 设置秒数 y## - 设置年份"); Serial.println(" w## - 设置任意星期几"); Serial.println(" t - 切换 24 小时模式"); Serial.println(" a - 设置 AM p - 设置 PM"); Serial.println(); Serial.println(" z - 开始时钟 Z - 停止时钟"); Serial.println(" q - SQW/OUT =1Hz Q - 停止 SQW/OUT"); Serial.println(); Serial.println(">##,### - 写入寄存器## 的值###"); Serial.println(" <## - 读取寄存器##中的值"); }//打开命令}//读入数字字符,直到有其他内容//或serial.int SerialReadPosInt() { int i =0;布尔值完成=假; while(Serial.available() &&!done) { char c =Serial.read(); if (c>='0' &&c <='9') { i =i * 10 + (c-'0'); }其他{完成=真; } } return i;}
RealTimeClockDS1307.cppC/C++
这是实时时钟的库文件之一。创建一个名为“RealTimeClockDS1307”的文件夹并将其复制到该文件夹​​中。这就是你要做的。无需编译。
/* RealTimeClockDS1307 - 控制 DS1307 RTC 模块的库 版权所有 (c) 2011 David H. Brown。版权所有 v0.92 为 Arduino 1.00 更新;没有在早期版本上重新测试 非常感谢 John Waters 和 Maurice Ribble 的早期和非常有用的工作(即使我没有使用他们的任何代码): - http://combusstory.com/wiki/index .php/RTC1307_-_Real_Time_Clock - http://www.glacialwanderer.com/hobbyrobotics/?p=12 这个库是免费软件;您可以根据自由软件基金会发布的 GNU 宽松通用公共许可证的条款重新分发和/或修改它;许可证的 2.1 版,或(由您选择)任何更高版本。这个库是分发的,希望它有用,但没有任何保证;甚至没有对适销性或针对特定目的的适用性的暗示保证。有关更多详细信息,请参阅 GNU 宽松通用公共许可证。您应该已经收到一份 GNU 宽松通用公共许可证以及这个库;如果没有,请写信给 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/ /******************** ****************************************************** ******** * 包括 ******************************************** **************************************/#include "RealTimeClockDS1307.h"#include /**************************************************** ******************************** * 定义 **************** ****************************************************** ************/#define DS1307_I2C_ADDRESS 0x68 // 这是I2C地址/************************* ****************************************************** *** * 构造函数 ************************************************ *********************************/RealTimeClockDS1307::RealTimeClockDS1307(){ Wire.begin(); //不得在未调用 //Wire.begin() 之前尝试读取时钟; readClock() 将挂起。 //还好,好像可以调用Wire.begin() //多次都没有不良影响。} /*********************** ****************************************************** ***** * 用户 API ********************************************* ************************************//***** 芯片读/写 *** ***/void RealTimeClockDS1307::readClock(){ // 重置寄存器指针 Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write((uint8_t) 0x00); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 8); _reg0_sec =Wire.read(); _reg1_min =Wire.read(); _reg2_hour =Wire.read(); _reg3_day =Wire.read(); _reg4_date =Wire.read(); _reg5_month =Wire.read(); _reg6_year =Wire.read(); _reg7_sqw =Wire.read();}void RealTimeClockDS1307::setClock(){ // 是偏执,我们将首先停止时钟 // 以确保我们在编写时没有翻转:写数据(0,0x80); //现在,我们将编写所有内容*除了*第二个 Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write((uint8_t) 0x01); Wire.write(_reg1_min); Wire.write(_reg2_hour); Wire.write(_reg3_day); Wire.write(_reg4_date); Wire.write(_reg5_month); Wire.write(_reg6_year); Wire.endTransmission(); //现在,我们将写秒数;我们不必 // 跟踪时钟是否已经在运行,因为 //_reg0_sec 已经知道我们想要它是什么。 //这将在写入新的秒值时重新启动时钟。写数据(0,_reg0_sec); }void RealTimeClockDS1307::stop(){ //“寄存器 0 的第 7 位是时钟暂停 (CH) 位。//当该位设置为 1 时,振荡器被禁用。” _reg0_sec =_reg0_sec | 0x80; writeData(0,_reg0_sec);}void RealTimeClockDS1307::start(){ //“寄存器 0 的第 7 位是时钟暂停 (CH) 位。//当该位设置为 1 时,振荡器被禁用。” _reg0_sec =_reg0_sec &~0x80; writeData(0,_reg0_sec);}void RealTimeClockDS1307::writeData(byte regNo, byte value){ if(regNo> 0x3F) { return; } Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(regNo); Wire.write(value); Wire.endTransmission();}void RealTimeClockDS1307::writeData(byte regNo, void * source, int length){ char * p =(char*) source;如果(regNo> 0x3F || 长度> 0x3F){ 返回; Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(regNo); for(int i=0; i 0x3F) { return 0xff; Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(regNo); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 1); return Wire.read();}void RealTimeClockDS1307::readData(byte regNo, void * dest, int length){ char * p =(char*) dest;如果(regNo> 0x3F || 长度> 0x3F){ 返回; Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(regNo); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 长度); for(int i=0; i 3) { return; } } //第4位启用(0x10); //如果禁用,第 7 位是当前输出状态 _reg7_sqw =_reg7_sqw &0x80 | 0x10 |频率; writeData(0x07, _reg7_sqw);}void RealTimeClockDS1307::sqwDisable(boolean outputLevel){ //bit 7 0x80 output + bit 4 0x10 使两者都为零,//与布尔值的 OR 向上移至 bit 7 _reg7_sqw =_reg7_sqw 0x90 | (输出级别<<7);写数据(0x07,_reg7_sqw); //注意:根据数据表,“OUT(输出控制):当方波输出被禁用时,此位控制 //SQW/OUT 引脚的输出电平。如果 SQWE =0,则//如果 OUT =1,则 SQW/OUT 引脚为 1,如果 OUT =0,则为 0。” //“SQW/OUT 引脚是漏极开路,需要一个外部 // 上拉电阻。” //值得一提的是,在Sparkfun分线板上,//BOB-00099,一个LED通过电阻连接到SQW引脚到//Vcc+5V,OUT=0时亮,OUT=1时暗,/ / 与我的预期相反,直到我记得它是 // 一个开放的排水沟(如果需要,请使用谷歌搜索)。基本上,它们 // 与其说是逻辑电平(例如,+3.3V rel Gnd),不如说是 // 对地(漏极)的高或低 *阻抗*。所以高基本上是//一个打开的开关。低电平接地。}/***** GETTERS ******/boolean RealTimeClockDS1307::is12hour() { //12 小时模式将小时寄存器的第 6 位设置为高电平返回 ((_reg2_hour &0x40) ==0x40);}boolean RealTimeClockDS1307::isPM(){ //如果在12小时模式下,但小时寄存器的5表示PM if(is12hour()) { return ((_reg2_hour &0x20) ==0x20); } //否则,让我们将小时>11 的任何时间视为 PM: return (getHours()> 11);}boolean RealTimeClockDS1307::isStopped(){ // 秒寄存器的第 7 位在高返回时停止时钟((_reg0_sec &0x80) ==0x80);}int RealTimeClockDS1307::getHours(){ if(is12hour()) { //不包括第 5 位,上午/下午指标返回 bcdToDec(_reg2_hour &0x1f); } //bits 4-5 是几十小时 return bcdToDec(_reg2_hour &0x3f);}int RealTimeClockDS1307::getMinutes(){ //可以用 0x7f 屏蔽但不需要返回 bcdToDec(_reg1_min);}int RealTimeClockDS1307::getSeconds(){ //需要屏蔽振荡器开始/停止位7 return bcdToDec(_reg0_sec &0x7f);}int RealTimeClockDS1307::getYear(){ return bcdToDec(_reg6_year);}int RealTimeClockDS1307::getMonth(){ //可以用 0x1f 屏蔽但不需要返回 bcdToDec(_reg5_month);}int RealTimeClockDS1307::getDate(){ //可以用 0x3f 屏蔽但不需要返回 bcdToDec(_reg4_date);}int RealTimeClockDS1307::getDay( ){ return getDate();}int RealTimeClockDS1307::getDayOfWeek(){ //可以用 0x07 屏蔽,但不需要返回 bcdToDec(_reg3_day);}void RealTimeClockDS1307::getFormatted(char * buffer){ int i=0; //目标字符串格式:YY-MM-DD HH:II:SS buffer[i++]=highNybbleToASCII(_reg6_year);缓冲区[i++]=lowNybbleToASCII(_reg6_year);缓冲区[i++]='-';缓冲区[i++]=highNybbleToASCII(_reg5_month &0x1f);缓冲区[i++]=lowNybbleToASCII(_reg5_month);缓冲区[i++]='-';缓冲区[i++]=highNybbleToASCII(_reg4_date &0x3f);缓冲区[i++]=lowNybbleToASCII(_reg4_date);缓冲区[i++]=''; if(is12hour()) { buffer[i++]=highNybbleToASCII(_reg2_hour &0x1f); } else { buffer[i++]=highNybbleToASCII(_reg2_hour &0x3f); } buffer[i++]=lowNybbleToASCII(_reg2_hour);缓冲区[i++]=':';缓冲区[i++]=highNybbleToASCII(_reg1_min &0x7f);缓冲区[i++]=lowNybbleToASCII(_reg1_min);缓冲区[i++]=':';缓冲区[i++]=highNybbleToASCII(_reg0_sec &0x7f);缓冲区[i++]=lowNybbleToASCII(_reg0_sec); if(is12hour()) { if(isPM()) { buffer[i++]='P'; } else { 缓冲区[i++]='A'; } } buffer[i++]=0x00;}void RealTimeClockDS1307::getFormatted2k(char * buffer){ buffer[0]='2';缓冲区[1]='0'; getFormatted(&buffer[2]);}/**** SETTERS *****/void RealTimeClockDS1307::setSeconds(int s){ if (s <60 &&s>=0) { //需要保留振荡器位_reg0_sec =decToBcd(s) | (_reg0_sec &0x80); }}void RealTimeClockDS1307::setMinutes(int m){ if (m <60 &&m>=0) { _reg1_min =decToBcd(m); }}void RealTimeClockDS1307::setHours(int h){ if (is12hour()) { if (h>=1 &&h <=12) { //preserve 12/24 and AM/PM bits _reg2_hour =decToBcd(h) | (_reg2_hour &0x60); } } else { if (h>=0 &&h <=24) { //preserve 12/24 bit _reg2_hour =decToBcd(h) | (_reg2_hour &0x40); } }//else}//setHoursvoid RealTimeClockDS1307::set24h(){ //"Bit 6 of the hours register is defined as the //"12- or 24-hour mode select bit. //"When high, the 12-hour mode is selected" //So, mask the curent value with the complement turn off that bit:_reg2_hour =_reg2_hour &~0x40; }void RealTimeClockDS1307::setAM(){ //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" //so we need to OR with 0x40 to set 12-hour mode and also //turn off the PM bit by masking with the complement _reg2_hour =_reg2_hour &~0x20 | 0x40;}void RealTimeClockDS1307::setPM(){ //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" //so we need to OR with 0x40 and 0x20 to set 12-hour mode and also //turn on the PM bit:_reg2_hour =_reg2_hour | 0x60;}void RealTimeClockDS1307::switchTo12h(){ if(is12hour()) { return; } int h =getHours(); if (h <12) { setAM(); } else { h =h-12; setPM(); } if (h==0) { h=12; } setHours(h);}void RealTimeClockDS1307::switchTo24h(){ if(!is12hour()) { return; } int h =getHours(); if(h==12) {//12 PM is just 12; 12 AM is 0 hours. h =0; } if (isPM()) {//if it was 12 PM, then h=0 above and so we're back to 12:h =h+12; } set24h(); setHours(h);}void RealTimeClockDS1307::setDayOfWeek(int d){ if (d> 0 &&d <8) { _reg3_day =decToBcd(d); }}void RealTimeClockDS1307::setDate(int d){ if (d> 0 &&d <32) { _reg4_date =decToBcd(d); }}void RealTimeClockDS1307::setDay(int d){ setDate(d);}void RealTimeClockDS1307::setMonth(int m){ if (m> 0 &&m <13) { _reg5_month =decToBcd(m); }}void RealTimeClockDS1307::setYear(int y){ if (y>=0 &&y <100) { _reg6_year =decToBcd(y); }}/***************************************** * Private methods *****************************************/byte RealTimeClockDS1307::decToBcd(byte b){ return ( ((b/10) <<4) + (b%10) );}// Convert binary coded decimal to normal decimal numbersbyte RealTimeClockDS1307::bcdToDec(byte b){ return ( ((b>> 4)*10) + (b%16) );}char RealTimeClockDS1307::lowNybbleToASCII(byte b) { b =b &0x0f; if(b <10) { //0 is ASCII 48 return 48+b; } //A is ASCII 55 return 55+b;}char RealTimeClockDS1307::highNybbleToASCII(byte b){ return lowNybbleToASCII(b>> 4);}/***** INSTANCE *******/RealTimeClockDS1307 RTC =RealTimeClockDS1307();
ReadmeClojure
Copy this also into the same folder you created named "RealTimeClockDS1307".
My goal in creating yet another DS1307 library was to provideeasy access to some of the other functions I needed from the chip,specifically its square wave output and its battery-backed RAM.## Documentation@todo Mostly comments in `RealTimeClockDS1307.h`## Examples (in /examples folder)- `RealTimeClockDS1307_Test.pde` allow you to turn the clock on/off,set date/time, set 12/24h, [de]activate the square wave, andread/write memory from the Serial Monitor.- `RealTimeClockDS1307.fz` is a Fritzing breadboard layout showingthe basic hookup of the Sparkfun RTC module to an Arduino. Includedis an optional resistor+LED to show the square wave (note that it'san open drain, so you hook up to it rather differently than, say, pin 13).## Changelog##### Version 0.95* Reverse renaming of getDate() and setDate(), now getDay() is calling getDate() and setDay() is calling setDate()* Readme improvements##### Version 0.94* changed getDate() to getDay() and setDate() to setDay()* updated keywords.txt* updated example##### Version 0.93* added keywords.txt for syntax highlighting##### Version 0.92 RC* Updated for Arduino 1.00; testing with Andreas Giemza (hurik)##### Version 0.91* added multi-byte read/write##### Version 0.9 RC* initial release## Future - web page documentation## CreditsMuch thanks to John Waters and Maurice Ribble for theirearlier and very helpful work (even if I didn't wind upusing any of their code):- [http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock](http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock)- [http://www.glacialwanderer.com/hobbyrobotics/?p=12](http://www.glacialwanderer.com/hobbyrobotics/?p=12)## CopyrightRealTimeClockDS1307 - library to control a DS1307 RTC moduleCopyright (c) 2011 David H. Brown. All rights reserved## License This library is free software;您可以根据自由软件基金会发布的 GNU 宽松通用公共许可证的条款重新分发和/或修改它;许可证的 2.1 版,或(由您选择)任何更高版本。 This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;甚至没有对适销性或针对特定目的的适用性的暗示保证。 See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
RealTimeClockDS1307.hC/C++
This is the main header file of the real time clock. Copy this also into the folder you previously created named "RealTimeClockDS1307". Now you have all the files for the Real Time Clock. Enter the arduino ide and under the 'Sketch' menu click on the 'include library' option and then search your folder under the 'Add .ZIP Library". This will do the trick and you will now be able to set the time in the RTC module.
/* RealTimeClockDS1307 - library to control a DS1307 RTC module Copyright (c) 2011 David H. Brown. All rights reserved v0.92 Updated for Arduino 1.00; not re-tested on earlier versions Much thanks to John Waters and Maurice Ribble for their earlier and very helpful work (even if I didn't wind up using any of their code):- http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock - http://www.glacialwanderer.com/hobbyrobotics/?p=12 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;甚至没有对适销性或针对特定目的的适用性的暗示保证。 See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/#ifndef RealTimeClockDS1307_h#define RealTimeClockDS1307_h #if defined(ARDUINO) &&ARDUINO>=100 #include "Arduino.h" #else #include "WProgram.h" #endif//#include //#include  //need/want 'boolean' and 'byte' types used by Arduino//#undef round is required to avoid a compile-time//"expected unqualified-id before 'double'" error in math.h//see:http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1247924528/3#undef round #include #define ARDUINO_PIN_T uint8_tclass RealTimeClockDS1307{ private:byte _reg0_sec; byte _reg1_min; byte _reg2_hour; byte _reg3_day; byte _reg4_date; byte _reg5_month; byte _reg6_year; byte _reg7_sqw; byte decToBcd(byte); byte bcdToDec(byte); char lowNybbleToASCII(byte); char highNybbleToASCII(byte); public:RealTimeClockDS1307(); void readClock();//read registers (incl sqw) to local store void setClock();//update clock registers from local store void stop();//immediate; does not require setClock(); void start();//immediate; does not require setClock(); void sqwEnable(byte);//enable the square wave with the specified frequency void sqwDisable(boolean);//disable the square wave, setting output either high or low void writeData(byte, byte);//write a single value to a register void writeData(byte, void *, int);//write several values consecutively byte readData(byte);//read a single value from a register void readData(byte, void *, int);//read several values into a buffer int getHours(); int getMinutes(); int getSeconds(); int getYear(); int getMonth(); int getDate(); int getDay(); int getDayOfWeek(); boolean is12hour(); boolean isPM(); boolean isStopped(); //getFormatted writes into a char array provided by you. Format is:// YY-MM-DD HH:II:SS ... plus "A" or "P" if in 12-hour mode //and of course a NULL terminator. So, [18] for 24h or [19] for 12h void getFormatted(char *);//see comment above void getFormatted2k(char *);//as getFormatted, but with "20" prepended //must also call setClock() after any of these //before next readClock(). Note that invalid dates are not //corrected by the clock. All the clock knows is when it should //roll over to the next month rather than the next date in the same month. void setSeconds(int); void setMinutes(int); //setHours rejects values out of range for the current 12/24 mode void setHours(int); void setAM();//does not consider hours; see switchTo24() void setPM();//does not consider hours; see switchTo24() void set24h();//does not consider hours; see switchTo24() void switchTo24h();//returns immediately if already 24h void switchTo12h();//returns immediately if already 12h void setDayOfWeek(int);//incremented at midnight; not set by date (no fixed meaning) void setDate(int);//allows 1-31 for *all* months. void setDay(int); void setMonth(int); void setYear(int); //squarewave frequencies:static const byte SQW_1Hz=0x00; static const byte SQW_4kHz=0x01;//actually 4.096kHz static const byte SQW_8kHz=0x02;//actually 8.192kHz static const byte SQW_32kHz=0x03;//actually 32.768kHz};extern RealTimeClockDS1307 RTC;#endif
another fileC/C++
add this to the 'RealTimeClockDS1307' folder.
########################################## Syntax Coloring Map RealTimeClockDS1307################################################################################# Instances (KEYWORD2)#######################################RTC KEYWORD2########################################## Methods and Functions (KEYWORD2)#########################################readClock KEYWORD2setClock KEYWORD2stop KEYWORD2start KEYWORD2sqwEnable KEYWORD2sqwDisable KEYWORD2writeData KEYWORD2readData KEYWORD2getHours KEYWORD2getMinutes KEYWORD2getSeconds KEYWORD2getYear KEYWORD2getMonth KEYWORD2getDate KEYWORD2getDay KEYWORD2getDayOfWeek KEYWORD2is12hour KEYWORD2isPM KEYWORD2isStopped KEYWORD2getFormatted KEYWORD2getFormatted2k KEYWORD2setSeconds KEYWORD2setMinutes KEYWORD2setHours KEYWORD2setAM KEYWORD2setPM KEYWORD2set24h KEYWORD2switchTo24h KEYWORD2switchTo12h KEYWORD2setDayOfWeek KEYWORD2setDate KEYWORD2setDay KEYWORD2setMonth KEYWORD2setYear KEYWORD2########################################## Constants (LITERAL1)#########################################SQW_1Hz LITERAL1SQW_4kHz LITERAL1SQW_8kHz LITERAL1SQW_32kHz LITERAL1
RTClib filesC#
create a folder named 'RTClib' and add the following files into it
########################################## Syntax Coloring Map RealTimeClockDS1307################################################################################# Instances (KEYWORD2)#######################################RTC KEYWORD2########################################## Methods and Functions (KEYWORD2)#########################################readClock KEYWORD2setClock KEYWORD2stop KEYWORD2start KEYWORD2sqwEnable KEYWORD2sqwDisable KEYWORD2writeData KEYWORD2readData KEYWORD2getHours KEYWORD2getMinutes KEYWORD2getSeconds KEYWORD2getYear KEYWORD2getMonth KEYWORD2getDate KEYWORD2getDay KEYWORD2getDayOfWeek KEYWORD2is12hour KEYWORD2isPM KEYWORD2isStopped KEYWORD2getFormatted KEYWORD2getFormatted2k KEYWORD2setSeconds KEYWORD2setMinutes KEYWORD2setHours KEYWORD2setAM KEYWORD2setPM KEYWORD2set24h KEYWORD2switchTo24h KEYWORD2switchTo12h KEYWORD2setDayOfWeek KEYWORD2setDate KEYWORD2setDay KEYWORD2setMonth KEYWORD2setYear KEYWORD2########################################## Constants (LITERAL1)#########################################SQW_1Hz LITERAL1SQW_4kHz LITERAL1SQW_8kHz LITERAL1SQW_32kHz LITERAL1
library.properties(name)C/C++
add this to the RTClib folder
My goal in creating yet another DS1307 library was to provideeasy access to some of the other functions I needed from the chip,specifically its square wave output and its battery-backed RAM.## Documentation@todo Mostly comments in `RealTimeClockDS1307.h`## Examples (in /examples folder)- `RealTimeClockDS1307_Test.pde` allow you to turn the clock on/off,set date/time, set 12/24h, [de]activate the square wave, andread/write memory from the Serial Monitor.- `RealTimeClockDS1307.fz` is a Fritzing breadboard layout showingthe basic hookup of the Sparkfun RTC module to an Arduino. Includedis an optional resistor+LED to show the square wave (note that it'san open drain, so you hook up to it rather differently than, say, pin 13).## Changelog##### Version 0.95* Reverse renaming of getDate() and setDate(), now getDay() is calling getDate() and setDay() is calling setDate()* Readme improvements##### Version 0.94* changed getDate() to getDay() and setDate() to setDay()* updated keywords.txt* updated example##### Version 0.93* added keywords.txt for syntax highlighting##### Version 0.92 RC* Updated for Arduino 1.00; testing with Andreas Giemza (hurik)##### Version 0.91* added multi-byte read/write##### Version 0.9 RC* initial release## Future - web page documentation## CreditsMuch thanks to John Waters and Maurice Ribble for theirearlier and very helpful work (even if I didn't wind upusing any of their code):- [http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock](http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock)- [http://www.glacialwanderer.com/hobbyrobotics/?p=12](http://www.glacialwanderer.com/hobbyrobotics/?p=12)## CopyrightRealTimeClockDS1307 - library to control a DS1307 RTC moduleCopyright (c) 2011 David H. Brown. All rights reserved## License This library is free software;您可以根据自由软件基金会发布的 GNU 宽松通用公共许可证的条款重新分发和/或修改它;许可证的 2.1 版,或(由您选择)任何更高版本。 This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;甚至没有对适销性或针对特定目的的适用性的暗示保证。 See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
RTClibC/C++
add this to the RTClib folder
/* RealTimeClockDS1307 - library to control a DS1307 RTC module Copyright (c) 2011 David H. Brown. All rights reserved v0.92 Updated for Arduino 1.00; not re-tested on earlier versions Much thanks to John Waters and Maurice Ribble for their earlier and very helpful work (even if I didn't wind up using any of their code):- http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock - http://www.glacialwanderer.com/hobbyrobotics/?p=12 This library is free software;您可以根据自由软件基金会发布的 GNU 宽松通用公共许可证的条款重新分发和/或修改它;许可证的 2.1 版,或(由您选择)任何更高版本。 This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;甚至没有对适销性或针对特定目的的适用性的暗示保证。 See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/ /****************************************************************************** * Includes ******************************************************************************/#include "RealTimeClockDS1307.h"#include /****************************************************************************** * Definitions ******************************************************************************/#define DS1307_I2C_ADDRESS 0x68 // This is the I2C address/****************************************************************************** * Constructors ******************************************************************************/RealTimeClockDS1307::RealTimeClockDS1307(){ Wire.begin(); //must NOT attempt to read the clock before //Wire.begin() has not been called; readClock() will hang. //Fortunately, it seems that you can call Wire.begin() //multiple times with no adverse effect).} /****************************************************************************** * User API ******************************************************************************//***** CHIP READ/WRITE ******/void RealTimeClockDS1307::readClock(){ // Reset the register pointer Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write((uint8_t) 0x00); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 8); _reg0_sec =Wire.read(); _reg1_min =Wire.read(); _reg2_hour =Wire.read(); _reg3_day =Wire.read(); _reg4_date =Wire.read(); _reg5_month =Wire.read(); _reg6_year =Wire.read(); _reg7_sqw =Wire.read();}void RealTimeClockDS1307::setClock(){ //to be paranoid, we're going to first stop the clock //to ensure we don't have rollovers while we're //writing:writeData(0,0x80); //now, we'll write everything *except* the second Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write((uint8_t) 0x01); Wire.write(_reg1_min); Wire.write(_reg2_hour); Wire.write(_reg3_day); Wire.write(_reg4_date); Wire.write(_reg5_month); Wire.write(_reg6_year); Wire.endTransmission(); //now, we'll write the seconds; we didn't have to keep //track of whether the clock was already running, because //_reg0_sec already knows what we want it to be. This //will restart the clock as it writes the new seconds value. writeData(0,_reg0_sec); }void RealTimeClockDS1307::stop(){ //"Bit 7 of register 0 is the clock halt (CH) bit. //When this bit is set to a 1, the oscillator is disabled." _reg0_sec =_reg0_sec | 0x80; writeData(0,_reg0_sec);}void RealTimeClockDS1307::start(){ //"Bit 7 of register 0 is the clock halt (CH) bit. //When this bit is set to a 1, the oscillator is disabled." _reg0_sec =_reg0_sec &~0x80; writeData(0,_reg0_sec);}void RealTimeClockDS1307::writeData(byte regNo, byte value){ if(regNo> 0x3F) { return; } Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(regNo); Wire.write(value); Wire.endTransmission();}void RealTimeClockDS1307::writeData(byte regNo, void * source, int length){ char * p =(char*) source; if(regNo> 0x3F || length> 0x3F) { return; } Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(regNo); for(int i=0; i 0x3F) { return 0xff; } Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(regNo); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 1); return Wire.read();}void RealTimeClockDS1307::readData(byte regNo, void * dest, int length){ char * p =(char*) dest; if(regNo> 0x3F || length> 0x3F) { return; } Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.write(regNo); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, length); for(int i=0; i 3) { return; } //bit 4 is enable (0x10); //bit 7 is current output state if disabled _reg7_sqw =_reg7_sqw &0x80 | 0x10 | frequency; writeData(0x07, _reg7_sqw);}void RealTimeClockDS1307::sqwDisable(boolean outputLevel){ //bit 7 0x80 output + bit 4 0x10 enable both to zero, //the OR with the boolean shifted up to bit 7 _reg7_sqw =_reg7_sqw &~0x90 | (outputLevel <<7); writeData(0x07, _reg7_sqw); //note:per the data sheet, "OUT (Output control):This bit controls //the output level of the SQW/OUT pin when the square wave //output is disabled. If SQWE =0, the logic level on the //SQW/OUT pin is 1 if OUT =1 and is 0 if OUT =0." //"The SQW/OUT pin is open drain and requires an external //pull-up resistor." //It is worth mentioning that on the Sparkfun breakout board, //BOB-00099, a LED connected to the SQW pin through a resistor to //Vcc+5V illuminated when OUT=0 and was dark when OUT=1, the //opposite of what I expected until I remembered that it is //an open drain (google it if you need to). Basically, they don't //so much mean a logic level (e.g., +3.3V rel Gnd) as they mean //high or low *impeadance* to ground (drain). So High is basically //an open switch. Low connects to ground.}/***** GETTERS ******/boolean RealTimeClockDS1307::is12hour() { //12-hour mode has bit 6 of the hour register set high return ((_reg2_hour &0x40) ==0x40);}boolean RealTimeClockDS1307::isPM(){ //if in 12-hour mode, but 5 of the hour register indicates PM if(is12hour()) { return ((_reg2_hour &0x20) ==0x20); } //otherwise, let's consider any time with the hour>11 to be PM:return (getHours()> 11);}boolean RealTimeClockDS1307::isStopped(){ //bit 7 of the seconds register stopps the clock when high return ((_reg0_sec &0x80) ==0x80);}int RealTimeClockDS1307::getHours(){ if(is12hour()) { //do not include bit 5, the am/pm indicator return bcdToDec(_reg2_hour &0x1f); } //bits 4-5 are tens of hours return bcdToDec(_reg2_hour &0x3f);}int RealTimeClockDS1307::getMinutes(){ //could mask with 0x7f but shouldn't need to return bcdToDec(_reg1_min);}int RealTimeClockDS1307::getSeconds(){ //need to mask oscillator start/stop bit 7 return bcdToDec(_reg0_sec &0x7f);}int RealTimeClockDS1307::getYear(){ return bcdToDec(_reg6_year);}int RealTimeClockDS1307::getMonth(){ //could mask with 0x1f but shouldn't need to return bcdToDec(_reg5_month);}int RealTimeClockDS1307::getDate(){ //could mask with 0x3f but shouldn't need to return bcdToDec(_reg4_date);}int RealTimeClockDS1307::getDay(){ return getDate();}int RealTimeClockDS1307::getDayOfWeek(){ //could mask with 0x07 but shouldn't need to return bcdToDec(_reg3_day);}void RealTimeClockDS1307::getFormatted(char * buffer){ int i=0; //target string format:YY-MM-DD HH:II:SS buffer[i++]=highNybbleToASCII(_reg6_year); buffer[i++]=lowNybbleToASCII(_reg6_year); buffer[i++]='-'; buffer[i++]=highNybbleToASCII(_reg5_month &0x1f); buffer[i++]=lowNybbleToASCII(_reg5_month); buffer[i++]='-'; buffer[i++]=highNybbleToASCII(_reg4_date &0x3f); buffer[i++]=lowNybbleToASCII(_reg4_date); buffer[i++]=' '; if(is12hour()) { buffer[i++]=highNybbleToASCII(_reg2_hour &0x1f); } else { buffer[i++]=highNybbleToASCII(_reg2_hour &0x3f); } buffer[i++]=lowNybbleToASCII(_reg2_hour); buffer[i++]=':'; buffer[i++]=highNybbleToASCII(_reg1_min &0x7f); buffer[i++]=lowNybbleToASCII(_reg1_min); buffer[i++]=':'; buffer[i++]=highNybbleToASCII(_reg0_sec &0x7f); buffer[i++]=lowNybbleToASCII(_reg0_sec); if(is12hour()) { if(isPM()) { buffer[i++]='P'; } else { buffer[i++]='A'; } } buffer[i++]=0x00;}void RealTimeClockDS1307::getFormatted2k(char * buffer){ buffer[0]='2'; buffer[1]='0'; getFormatted(&buffer[2]);}/**** SETTERS *****/void RealTimeClockDS1307::setSeconds(int s){ if (s <60 &&s>=0) { //need to preserve oscillator bit _reg0_sec =decToBcd(s) | (_reg0_sec &0x80); }}void RealTimeClockDS1307::setMinutes(int m){ if (m <60 &&m>=0) { _reg1_min =decToBcd(m); }}void RealTimeClockDS1307::setHours(int h){ if (is12hour()) { if (h>=1 &&h <=12) { //preserve 12/24 and AM/PM bits _reg2_hour =decToBcd(h) | (_reg2_hour &0x60); } } else { if (h>=0 &&h <=24) { //preserve 12/24 bit _reg2_hour =decToBcd(h) | (_reg2_hour &0x40); } }//else}//setHoursvoid RealTimeClockDS1307::set24h(){ //"Bit 6 of the hours register is defined as the //"12- or 24-hour mode select bit. //"When high, the 12-hour mode is selected" //So, mask the curent value with the complement turn off that bit:_reg2_hour =_reg2_hour &~0x40; }void RealTimeClockDS1307::setAM(){ //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" //so we need to OR with 0x40 to set 12-hour mode and also //turn off the PM bit by masking with the complement _reg2_hour =_reg2_hour &~0x20 | 0x40;}void RealTimeClockDS1307::setPM(){ //"In the 12-hour mode, bit 5 is the AM/PM bit with logic high being PM" //so we need to OR with 0x40 and 0x20 to set 12-hour mode and also //turn on the PM bit:_reg2_hour =_reg2_hour | 0x60;}void RealTimeClockDS1307::switchTo12h(){ if(is12hour()) { return; } int h =getHours(); if (h <12) { setAM(); } else { h =h-12; setPM(); } if (h==0) { h=12; } setHours(h);}void RealTimeClockDS1307::switchTo24h(){ if(!is12hour()) { return; } int h =getHours(); if(h==12) {//12 PM is just 12; 12 AM is 0 hours. h =0; } if (isPM()) {//if it was 12 PM, then h=0 above and so we're back to 12:h =h+12; } set24h(); setHours(h);}void RealTimeClockDS1307::setDayOfWeek(int d){ if (d> 0 &&d <8) { _reg3_day =decToBcd(d); }}void RealTimeClockDS1307::setDate(int d){ if (d> 0 &&d <32) { _reg4_date =decToBcd(d); }}void RealTimeClockDS1307::setDay(int d){ setDate(d);}void RealTimeClockDS1307::setMonth(int m){ if (m> 0 &&m <13) { _reg5_month =decToBcd(m); }}void RealTimeClockDS1307::setYear(int y){ if (y>=0 &&y <100) { _reg6_year =decToBcd(y); }}/***************************************** * Private methods *****************************************/byte RealTimeClockDS1307::decToBcd(byte b){ return ( ((b/10) <<4) + (b%10) );}// Convert binary coded decimal to normal decimal numbersbyte RealTimeClockDS1307::bcdToDec(byte b){ return ( ((b>> 4)*10) + (b%16) );}char RealTimeClockDS1307::lowNybbleToASCII(byte b) { b =b &0x0f; if(b <10) { //0 is ASCII 48 return 48+b; } //A is ASCII 55 return 55+b;}char RealTimeClockDS1307::highNybbleToASCII(byte b){ return lowNybbleToASCII(b>> 4);}/***** INSTANCE *******/RealTimeClockDS1307 RTC =RealTimeClockDS1307();
RTClibC/C++
add this to the RTClib folder. Now you have all the necessary files for the RTClib. Now do the same as I told you with the 'RealTimeClockDS1307' library file.
/* RealTimeClockDS1307 - library to control a DS1307 RTC module Copyright (c) 2011 David H. Brown. All rights reserved v0.92 Updated for Arduino 1.00; not re-tested on earlier versions Much thanks to John Waters and Maurice Ribble for their earlier and very helpful work (even if I didn't wind up using any of their code):- http://combustory.com/wiki/index.php/RTC1307_-_Real_Time_Clock - http://www.glacialwanderer.com/hobbyrobotics/?p=12 This library is free software;您可以根据自由软件基金会发布的 GNU 宽松通用公共许可证的条款重新分发和/或修改它;许可证的 2.1 版,或(由您选择)任何更高版本。 This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;甚至没有对适销性或针对特定目的的适用性的暗示保证。 See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA*/#ifndef RealTimeClockDS1307_h#define RealTimeClockDS1307_h #if defined(ARDUINO) &&ARDUINO>=100 #include "Arduino.h" #else #include "WProgram.h" #endif//#include //#include  //need/want 'boolean' and 'byte' types used by Arduino//#undef round is required to avoid a compile-time//"expected unqualified-id before 'double'" error in math.h//see:http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1247924528/3#undef round #include #define ARDUINO_PIN_T uint8_tclass RealTimeClockDS1307{ private:byte _reg0_sec; byte _reg1_min; byte _reg2_hour; byte _reg3_day; byte _reg4_date; byte _reg5_month; byte _reg6_year; byte _reg7_sqw; byte decToBcd(byte); byte bcdToDec(byte); char lowNybbleToASCII(byte); char highNybbleToASCII(byte); public:RealTimeClockDS1307(); void readClock();//read registers (incl sqw) to local store void setClock();//update clock registers from local store void stop();//immediate; does not require setClock(); void start();//immediate; does not require setClock(); void sqwEnable(byte);//enable the square wave with the specified frequency void sqwDisable(boolean);//disable the square wave, setting output either high or low void writeData(byte, byte);//write a single value to a register void writeData(byte, void *, int);//write several values consecutively byte readData(byte);//read a single value from a register void readData(byte, void *, int);//read several values into a buffer int getHours(); int getMinutes(); int getSeconds(); int getYear(); int getMonth(); int getDate(); int getDay(); int getDayOfWeek(); boolean is12hour(); boolean isPM(); boolean isStopped(); //getFormatted writes into a char array provided by you. Format is:// YY-MM-DD HH:II:SS ... plus "A" or "P" if in 12-hour mode //and of course a NULL terminator. So, [18] for 24h or [19] for 12h void getFormatted(char *);//see comment above void getFormatted2k(char *);//as getFormatted, but with "20" prepended //must also call setClock() after any of these //before next readClock(). Note that invalid dates are not //corrected by the clock. All the clock knows is when it should //roll over to the next month rather than the next date in the same month. void setSeconds(int); void setMinutes(int); //setHours rejects values out of range for the current 12/24 mode void setHours(int); void setAM();//does not consider hours; see switchTo24() void setPM();//does not consider hours; see switchTo24() void set24h();//does not consider hours; see switchTo24() void switchTo24h();//returns immediately if already 24h void switchTo12h();//returns immediately if already 12h void setDayOfWeek(int);//incremented at midnight; not set by date (no fixed meaning) void setDate(int);//allows 1-31 for *all* months. void setDay(int); void setMonth(int); void setYear(int); //squarewave frequencies:static const byte SQW_1Hz=0x00; static const byte SQW_4kHz=0x01;//actually 4.096kHz static const byte SQW_8kHz=0x02;//actually 8.192kHz static const byte SQW_32kHz=0x03;//actually 32.768kHz};extern RealTimeClockDS1307 RTC;#endif
README.mdC/C++
add this to the RTClib library
This is a fork of JeeLab's fantastic real time clock library for Arduino.For details on using this library with an RTC module like the DS1307, see the guide at:https://learn.adafruit.com/ds1307-real-time-clock-breakout-board-kit/overviewTo download. click the DOWNLOADS button to the right, and rename the uncompressed folder RTClib.Place the RTClib folder in your *arduinosketchfolder*/libraries/ folder. You may need to create the libraries subfolder if its your first library. Restart the IDE.## CompatibilityMCU | Tested Works | Doesn't Work | Not Tested | Notes------------------ | :----------:| :----------:| :---------:| -----Atmega328 @ 16MHz | X | | | Atmega328 @ 12MHz | X | | | Atmega32u4 @ 16MHz | X | | | Use SDA/SCL on pins D3 & D2Atmega32u4 @ 8MHz | X | | | Use SDA/SCL on pins D3 & D2ESP8266 | X | | | SDA/SCL default to pins 4 & 5 but any two pins can be assigned as SDA/SCL using Wire.begin(SDA,SCL)Atmega2560 @ 16MHz | X | | | Use SDA/SCL on Pins 20 & 21ATSAM3X8E | X | | | Use SDA1 and SCL1ATSAM21D | X | | | ATtiny85 @ 16MHz | X | | | ATtiny85 @ 8MHz | X | | | Intel Curie @ 32MHz | | | X | STM32F2 | | | X | * ATmega328 @ 16MHz :Arduino UNO, Adafruit Pro Trinket 5V, Adafruit Metro 328, Adafruit Metro Mini * ATmega328 @ 12MHz :Adafruit Pro Trinket 3V * ATmega32u4 @ 16MHz :Arduino Leonardo, Arduino Micro, Arduino Yun, Teensy 2.0 * ATmega32u4 @ 8MHz :Adafruit Flora, Bluefruit Micro * ESP8266 :Adafruit Huzzah * ATmega2560 @ 16MHz :Arduino Mega * ATSAM3X8E :Arduino Due * ATSAM21D :Arduino Zero, M0 Pro * ATtiny85 @ 16MHz :Adafruit Trinket 5V * ATtiny85 @ 8MHz :Adafruit Gemma, Arduino Gemma, Adafruit Trinket 3V
RTClib.cppC/C++
name it as above and add it to the RTClib library
// Code by JeeLabs http://news.jeelabs.org/code/// Released to the public domain! Enjoy!#include #include "RTClib.h"#ifdef __AVR__ #include #elif defined(ESP8266) #include #elif defined(ARDUINO_ARCH_SAMD)// nothing special needed#elif defined(ARDUINO_SAM_DUE) #define PROGMEM #define pgm_read_byte(addr) (*(const unsigned char *)(addr)) #define Wire Wire1#endif#if (ARDUINO>=100) #include  // capital A so it is error prone on case-sensitive filesystems // Macro to deal with the difference in I2C write functions from old and new Arduino versions. #define _I2C_WRITE write #define _I2C_READ read#else #include  #define _I2C_WRITE send #define _I2C_READ receive#endifstatic uint8_t read_i2c_register(uint8_t addr, uint8_t reg) { Wire.beginTransmission(addr); Wire._I2C_WRITE((byte)reg); Wire.endTransmission(); Wire.requestFrom(addr, (byte)1); return Wire._I2C_READ();}static void write_i2c_register(uint8_t addr, uint8_t reg, uint8_t val) { Wire.beginTransmission(addr); Wire._I2C_WRITE((byte)reg); Wire._I2C_WRITE((byte)val); Wire.endTransmission();}////////////////////////////////////////////////////////////////////////////////// utility code, some of this could be exposed in the DateTime API if neededconst uint8_t daysInMonth [] PROGMEM ={ 31,28,31,30,31,30,31,31,30,31,30,31 };// number of days since 2000/01/01, valid for 2001..2099static uint16_t date2days(uint16_t y, uint8_t m, uint8_t d) { if (y>=2000) y -=2000; uint16_t days =d; for (uint8_t i =1; i  2 &&y % 4 ==0) ++days; return days + 365 * y + (y + 3) / 4 - 1;}static long time2long(uint16_t days, uint8_t h, uint8_t m, uint8_t s) { return ((days * 24L + h) * 60 + m) * 60 + s;}////////////////////////////////////////////////////////////////////////////////// DateTime implementation - ignores time zones and DST changes// NOTE:also ignores leap seconds, see http://en.wikipedia.org/wiki/Leap_secondDateTime::DateTime (uint32_t t) { t -=SECONDS_FROM_1970_TO_2000; // bring to 2000 timestamp from 1970 ss =t % 60; t /=60; mm =t % 60; t /=60; hh =t % 24; uint16_t days =t / 24; uint8_t leap; for (yOff =0;; ++yOff) { leap =yOff % 4 ==0; if (days <365 + leap) break; days -=365 + leap; } for (m =1;; ++m) { uint8_t daysPerMonth =pgm_read_byte(daysInMonth + m - 1); if (leap &&m ==2) ++daysPerMonth; if (days =2000) year -=2000; yOff =year; m =month; d =day; hh =hour; mm =min; ss =sec;}DateTime::DateTime (const DateTime©):yOff(copy.yOff), m(copy.m), d(copy.d), hh(copy.hh), mm(copy.mm), ss(copy.ss){}static uint8_t conv2d(const char* p) { uint8_t v =0; if ('0' <=*p &&*p <='9') v =*p - '0'; return 10 * v + *++p - '0';}// A convenient constructor for using "the compiler's time":// DateTime now (__DATE__, __TIME__);// NOTE:using F() would further reduce the RAM footprint, see below.DateTime::DateTime (const char* date, const char* time) { // sample input:date ="Dec 26 2009", time ="12:34:56" yOff =conv2d(date + 9); // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec switch (date[0]) { case 'J':m =date[1] =='a' ? 1 :m =date[2] =='n' ? 6 :7;休息; case 'F':m =2;休息; case 'A':m =date[2] =='r' ? 4 :8;休息; case 'M':m =date[2] =='r' ? 3 :5;休息; case 'S':m =9;休息; case 'O':m =10;休息; case 'N':m =11;休息; case 'D':m =12;休息; } d =conv2d(date + 4); hh =conv2d(time); mm =conv2d(time + 3); ss =conv2d(time + 6);}// A convenient constructor for using "the compiler's time":// This version will save RAM by using PROGMEM to store it by using the F macro.// DateTime now (F(__DATE__), F(__TIME__));DateTime::DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time) { // sample input:date ="Dec 26 2009", time ="12:34:56" char buff[11]; memcpy_P(buff, date, 11); yOff =conv2d(buff + 9); // Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec switch (buff[0]) { case 'J':m =buff[1] =='a' ? 1 :m =buff[2] =='n' ? 6 :7;休息; case 'F':m =2;休息; case 'A':m =buff[2] =='r' ? 4 :8;休息; case 'M':m =buff[2] =='r' ? 3 :5;休息; case 'S':m =9;休息; case 'O':m =10;休息; case 'N':m =11;休息; case 'D':m =12;休息; } d =conv2d(buff + 4); memcpy_P(buff, time, 8); hh =conv2d(buff); mm =conv2d(buff + 3); ss =conv2d(buff + 6);}uint8_t DateTime::dayOfTheWeek() const { uint16_t day =date2days(yOff, m, d); return (day + 6) % 7; // Jan 1, 2000 is a Saturday, i.e. returns 6}uint32_t DateTime::unixtime(void) const { uint32_t t; uint16_t days =date2days(yOff, m, d); t =time2long(days, hh, mm, ss); t +=SECONDS_FROM_1970_TO_2000; // seconds from 1970 to 2000 return t;}long DateTime::secondstime(void) const { long t; uint16_t days =date2days(yOff, m, d); t =time2long(days, hh, mm, ss); return t;}DateTime DateTime::operator+(const TimeSpan&span) { return DateTime(unixtime()+span.totalseconds());}DateTime DateTime::operator-(const TimeSpan&span) { return DateTime(unixtime()-span.totalseconds());}TimeSpan DateTime::operator-(const DateTime&right) { return TimeSpan(unixtime()-right.unixtime());}////////////////////////////////////////////////////////////////////////////////// TimeSpan implementationTimeSpan::TimeSpan (int32_t seconds):_seconds(seconds){}TimeSpan::TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds):_seconds((int32_t)days*86400L + (int32_t)hours*3600 + (int32_t)minutes*60 + seconds){}TimeSpan::TimeSpan (const TimeSpan©):_seconds(copy._seconds){}TimeSpan TimeSpan::operator+(const TimeSpan&right) { return TimeSpan(_seconds+right._seconds);}TimeSpan TimeSpan::operator-(const TimeSpan&right) { return TimeSpan(_seconds-right._seconds);}////////////////////////////////////////////////////////////////////////////////// RTC_DS1307 im plementationstatic uint8_t bcd2bin (uint8_t val) { return val - 6 * (val>> 4); }static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); }boolean RTC_DS1307::begin(void) { Wire.begin(); return true;}uint8_t RTC_DS1307::isrunning(void) { Wire.beginTransmission(DS1307_ADDRESS); Wire._I2C_WRITE((byte)0); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 1); uint8_t ss =Wire._I2C_READ(); return !(ss>>7);}void RTC_DS1307::adjust(const DateTime&dt) { Wire.beginTransmission(DS1307_ADDRESS); Wire._I2C_WRITE((byte)0); // start at location 0 Wire._I2C_WRITE(bin2bcd(dt.second())); Wire._I2C_WRITE(bin2bcd(dt.minute())); Wire._I2C_WRITE(bin2bcd(dt.hour())); Wire._I2C_WRITE(bin2bcd(0)); Wire._I2C_WRITE(bin2bcd(dt.day())); Wire._I2C_WRITE(bin2bcd(dt.month())); Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); Wire.endTransmission();}DateTime RTC_DS1307::now() { Wire.beginTransmission(DS1307_ADDRESS); Wire._I2C_WRITE((byte)0); Wire.endTransmission(); Wire.requestFrom(DS1307_ADDRESS, 7); uint8_t ss =bcd2bin(Wire._I2C_READ() &0x7F); uint8_t mm =bcd2bin(Wire._I2C_READ()); uint8_t hh =bcd2bin(Wire._I2C_READ()); Wire._I2C_READ(); uint8_t d =bcd2bin(Wire._I2C_READ()); uint8_t m =bcd2bin(Wire._I2C_READ()); uint16_t y =bcd2bin(Wire._I2C_READ()) + 2000; return DateTime (y, m, d, hh, mm, ss);}Ds1307SqwPinMode RTC_DS1307::readSqwPinMode() { int mode; Wire.beginTransmission(DS1307_ADDRESS); Wire._I2C_WRITE(DS1307_CONTROL); Wire.endTransmission(); Wire.requestFrom((uint8_t)DS1307_ADDRESS, (uint8_t)1); mode =Wire._I2C_READ(); mode &=0x93; return static_cast(mode);}void RTC_DS1307::writeSqwPinMode(Ds1307SqwPinMode mode) { Wire.beginTransmission(DS1307_ADDRESS); Wire._I2C_WRITE(DS1307_CONTROL); Wire._I2C_WRITE(mode); Wire.endTransmission();}void RTC_DS1307::readnvram(uint8_t* buf, uint8_t size, uint8_t address) { int addrByte =DS1307_NVRAM + address; Wire.beginTransmission(DS1307_ADDRESS); Wire._I2C_WRITE(addrByte); Wire.endTransmission(); Wire.requestFrom((uint8_t) DS1307_ADDRESS, size); for (uint8_t pos =0; pos >=3; mode &=0x7; return static_cast(mode);}void RTC_PCF8523::writeSqwPinMode(Pcf8523SqwPinMode mode) { Wire.beginTransmission(PCF8523_ADDRESS); Wire._I2C_WRITE(PCF8523_CLKOUTCONTROL); Wire._I2C_WRITE(mode <<3); Wire.endTransmission();}////////////////////////////////////////////////////////////////////////////////// RTC_DS3231 implementationboolean RTC_DS3231::begin(void) { Wire.begin(); return true;}bool RTC_DS3231::lostPower(void) { return (read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG)>> 7);}void RTC_DS3231::adjust(const DateTime&dt) { Wire.beginTransmission(DS3231_ADDRESS); Wire._I2C_WRITE((byte)0); // start at location 0 Wire._I2C_WRITE(bin2bcd(dt.second())); Wire._I2C_WRITE(bin2bcd(dt.minute())); Wire._I2C_WRITE(bin2bcd(dt.hour())); Wire._I2C_WRITE(bin2bcd(0)); Wire._I2C_WRITE(bin2bcd(dt.day())); Wire._I2C_WRITE(bin2bcd(dt.month())); Wire._I2C_WRITE(bin2bcd(dt.year() - 2000)); Wire.endTransmission(); uint8_t statreg =read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG); statreg &=~0x80; // flip OSF bit write_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG, statreg);}DateTime RTC_DS3231::now() { Wire.beginTransmission(DS3231_ADDRESS); Wire._I2C_WRITE((byte)0); Wire.endTransmission(); Wire.requestFrom(DS3231_ADDRESS, 7); uint8_t ss =bcd2bin(Wire._I2C_READ() &0x7F); uint8_t mm =bcd2bin(Wire._I2C_READ()); uint8_t hh =bcd2bin(Wire._I2C_READ()); Wire._I2C_READ(); uint8_t d =bcd2bin(Wire._I2C_READ()); uint8_t m =bcd2bin(Wire._I2C_READ()); uint16_t y =bcd2bin(Wire._I2C_READ()) + 2000; return DateTime (y, m, d, hh, mm, ss);}Ds3231SqwPinMode RTC_DS3231::readSqwPinMode() { int mode; Wire.beginTransmission(DS3231_ADDRESS); Wire._I2C_WRITE(DS3231_CONTROL); Wire.endTransmission(); Wire.requestFrom((uint8_t)DS3231_ADDRESS, (uint8_t)1); mode =Wire._I2C_READ(); mode &=0x93; return static_cast(mode);}void RTC_DS3231::writeSqwPinMode(Ds3231SqwPinMode mode) { uint8_t ctrl; ctrl =read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL); ctrl &=~0x04; // turn off INTCON ctrl &=~0x18; // set freq bits to 0 if (mode ==DS3231_OFF) { ctrl |=0x04; // turn on INTCN } else { ctrl |=mode; } write_i2c_register(DS3231_ADDRESS, DS3231_CONTROL, ctrl); //Serial.println( read_i2c_register(DS3231_ADDRESS, DS3231_CONTROL), HEX);}
RTClib.hC/C++
that's the name. add it to the RTClib library. Now you have all the files for the RTClib library. Do the same steps to add this to the arduino libraries.
// Code by JeeLabs http://news.jeelabs.org/code/// Released to the public domain! Enjoy!#ifndef _RTCLIB_H_#define _RTCLIB_H_#include class TimeSpan;#define PCF8523_ADDRESS 0x68#define PCF8523_CLKOUTCONTROL 0x0F#define PCF8523_CONTROL_3 0x02#define DS1307_ADDRESS 0x68#define DS1307_CONTROL 0x07#define DS1307_NVRAM 0x08#define DS3231_ADDRESS 0x68#define DS3231_CONTROL 0x0E#define DS3231_STATUSREG 0x0F#define SECONDS_PER_DAY 86400L#define SECONDS_FROM_1970_TO_2000 946684800// Simple general-purpose date/time class (no TZ / DST / leap second handling!)class DateTime {public:DateTime (uint32_t t =0); DateTime (uint16_t year, uint8_t month, uint8_t day, uint8_t hour =0, uint8_t min =0, uint8_t sec =0); DateTime (const DateTime©); DateTime (const char* date, const char* time); DateTime (const __FlashStringHelper* date, const __FlashStringHelper* time); uint16_t year() const { return 2000 + yOff; } uint8_t month() const { return m; } uint8_t day() const { return d; } uint8_t hour() const { return hh; } uint8_t minute() const { return mm; } uint8_t second() const { return ss; } uint8_t dayOfTheWeek() const; // 32-bit times as seconds since 1/1/2000 long secondstime() const; // 32-bit times as seconds since 1/1/1970 uint32_t unixtime(void) const; DateTime operator+(const TimeSpan&span); DateTime operator-(const TimeSpan&span); TimeSpan operator-(const DateTime&right);protected:uint8_t yOff, m, d, hh, mm, ss;};// Timespan which can represent changes in time with seconds accuracy.class TimeSpan {public:TimeSpan (int32_t seconds =0); TimeSpan (int16_t days, int8_t hours, int8_t minutes, int8_t seconds); TimeSpan (const TimeSpan©); int16_t days() const { return _seconds / 86400L; } int8_t hours() const { return _seconds / 3600 % 24; } int8_t minutes() const { return _seconds / 60 % 60; } int8_t seconds() const { return _seconds % 60; } int32_t totalseconds() const { return _seconds; } TimeSpan operator+(const TimeSpan&right); TimeSpan operator-(const TimeSpan&right);protected:int32_t _seconds;};// RTC based on the DS1307 chip connected via I2C and the Wire libraryenum Ds1307SqwPinMode { OFF =0x00, ON =0x80, SquareWave1HZ =0x10, SquareWave4kHz =0x11, SquareWave8kHz =0x12, SquareWave32kHz =0x13 };class RTC_DS1307 {public:boolean begin(void); static void adjust(const DateTime&dt); uint8_t isrunning(void); static DateTime now(); static Ds1307SqwPinMode readSqwPinMode(); static void writeSqwPinMode(Ds1307SqwPinMode mode); uint8_t readnvram(uint8_t address); void readnvram(uint8_t* buf, uint8_t size, uint8_t address); void writenvram(uint8_t address, uint8_t data); void writenvram(uint8_t address, uint8_t* buf, uint8_t size);};// RTC based on the DS3231 chip connected via I2C and the Wire libraryenum Ds3231SqwPinMode { DS3231_OFF =0x01, DS3231_SquareWave1Hz =0x00, DS3231_SquareWave1kHz =0x08, DS3231_SquareWave4kHz =0x10, DS3231_SquareWave8kHz =0x18 };class RTC_DS3231 {public:boolean begin(void); static void adjust(const DateTime&dt); bool lostPower(void); static DateTime now(); static Ds3231SqwPinMode readSqwPinMode(); static void writeSqwPinMode(Ds3231SqwPinMode mode);};// RTC based on the PCF8523 chip connected via I2C and the Wire libraryenum Pcf8523SqwPinMode { PCF8523_OFF =7, PCF8523_SquareWave1HZ =6, PCF8523_SquareWave32HZ =5, PCF8523_SquareWave1kHz =4, PCF8523_SquareWave4kHz =3, PCF8523_SquareWave8kHz =2, PCF8523_SquareWave16kHz =1, PCF8523_SquareWave32kHz =0 };class RTC_PCF8523 {public:boolean begin(void); void adjust(const DateTime&dt); boolean initialized(void); static DateTime now(); Pcf8523SqwPinMode readSqwPinMode(); void writeSqwPinMode(Pcf8523SqwPinMode mode);};// RTC using the internal millis() clock, has to be initialized before use// NOTE:this clock won't be correct once the millis() timer rolls over (>49d?)class RTC_Millis {public:static void begin(const DateTime&dt) { adjust(dt); } static void adjust(const DateTime&dt); static DateTime now();protected:static long offset;};#endif // _RTCLIB_H_

示意图

This is the schematic of the project. 7segmentClock.fzz

制造工艺

  1. 熨衣板
  2. 布谷鸟钟
  3. 印刷电路板
  4. 冲浪板
  5. 如何制作 Arduino+Raspberry Pi 机器人平台
  6. RaspiRobot Board V2
  7. Arduino pov 视觉时钟
  8. 简单字时钟(Arduino)
  9. 主时钟
  10. 无限镜时钟
  11. 制作完美印刷电路板的原因不止一个
  12. 了解引擎配置