Arduino 实时时钟 (RTC) 模块指南(DS1307 和 DS3231)

释放双眼,带上耳机,听听看~!

这篇文章介绍的是关于如何在 Arduino 中使用 DS1307 实时时钟 (RTC) 模块。对于 DS3231 RTC 等其它类似模块,您也可以按照本指南进行操作。

实时时钟模块介绍

实时时钟模块为下图(前后视图):

Arduino 实时时钟 (RTC) 模块指南(DS1307 和 DS3231)

首次使用该模块时,需要焊接一些排针。

如上图所示,该模块安装了备用电池。这允许模块保留时间,即使它没有被 Arduino 供电。这样,每次打开和关闭模块时,时间都不会重置。

该模块使用 I2C 通信。这意味着它仅使用 2 个引脚与 Arduino 通信。

去哪买?

实时时钟是一种经济实惠的模块。某宝一大把,不用多说自己找。

引脚接线

连接 RTC 模块非常简单:

引脚 连接到 Arduino Uno
SCL A5
SDA A4
VCC 5V
GND GND

如果您使用的是其它 Arduino 板而不是 uno,请查看它们的 SCL 和 SDA 引脚是什么:

  • Nano: SDA (A4); SCL(A5)
  • MEGA: SDA (20); SCL(21)
  • Leonardo: SDA (20); SCL(21)

示例:在串行监视器上显示日期和时间

此示例在串行监视器上显示日期和时间。

所需零件

对于此示例,您需要以下部分:

  • Arduino UNO
  • DS1307 RTC模块
  • 连接线

示意图

如下图所示,将您的实时时钟模块连接到您的 Arduino。

Arduino 实时时钟 (RTC) 模块指南(DS1307 和 DS3231)

代码

使用 RTC 需要两个重要步骤:

  • 设置当前时间,以便RTC知道现在几点了
  • 保留时间,以便 RTC 始终给出正确的时间,即使它已关闭

在实时时钟中设置当前时间

要设置当前时间,您需要更改提供的代码:

该函数的参数以红色突出显示:秒、分、小时、星期几、日期、月份和年份(按此顺序)。星期日是一周的第 1 天,星期六是第 7 天。不要忘记取消注释那行代码。

设置当前时间后,您可以上传提供的代码并进行所需的修改。

提供的代码由 tronixstuff 的 John Boxall 编写:

// Written by John Boxall from http://tronixstuff.com

#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val){
  return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val){
  return( (val/16*10) + (val%16) );
}
void setup(){
  Wire.begin();
  Serial.begin(9600);
  // set the initial time here:
  // DS3231 seconds, minutes, hours, day, date, month, year
  setDS3231time(30,42,16,5,13,10,16);
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year){
  // sets time and date data to DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set next input to start at the seconds register
  Wire.write(decToBcd(second)); // set seconds
  Wire.write(decToBcd(minute)); // set minutes
  Wire.write(decToBcd(hour)); // set hours
  Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
  Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
  Wire.write(decToBcd(month)); // set month
  Wire.write(decToBcd(year)); // set year (0 to 99)
  Wire.endTransmission();
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year){
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}
void displayTime(){
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
  &year);
  // send it to the serial monitor
  Serial.print(hour, DEC);
  // convert the byte variable to a decimal number when displayed
  Serial.print(":");
  if (minute<10){
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second<10){
    Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print(" Day of week: ");
  switch(dayOfWeek){
  case 1:
    Serial.println("Sunday");
    break;
  case 2:
    Serial.println("Monday");
    break;
  case 3:
    Serial.println("Tuesday");
    break;
  case 4:
    Serial.println("Wednesday");
    break;
  case 5:
    Serial.println("Thursday");
    break;
  case 6:
    Serial.println("Friday");
    break;
  case 7:
    Serial.println("Saturday");
    break;
  }
}
void loop(){
  displayTime(); // display the real-time clock data on the Serial Monitor,
  delay(1000); // every second
}

 

在实时时钟中保留时间

如果您不想在每次关闭 RTC 时重置时间,您应该执行以下操作:

这是在 RTC 中设置时间的一个非常重要的步骤。如果您不这样做,每次您的 RTC 重置时,它都会显示您之前设置的时间,而不是当前时间。

示范

以 9600 的波特率打开串行监视器,您将看到结果。

这是显示当前日期和时间的串行监视器。

Arduino 实时时钟 (RTC) 模块指南(DS1307 和 DS3231)

总结

RTC 模块非常有用,您可以将其用作时钟、定时器等。

给TA打赏
共{{data.count}}人
人已打赏
Arduino-进阶

128×64LCD诺基亚显示屏 与 Arduino 连接教程

2021-6-3 21:37:46

ArduinoArduino-进阶动态

DIY Arduino全息矩阵时钟

2023-7-2 18:43:44

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索
'); })();