在当今世界,时间就是一切,而对于特定的电子产品,时间至关重要;就像我们人类一样,他们也需要一种方法来记录时间。那么电子产品是如何做到的呢?答案是 DS3231,一种实时时钟,通常称为 RTC,是一种内置于集成电路或 IC 中的计时设备。它用于许多对时间要求严格的应用程序和设备,例如服务器、GPS 和数据记录器。让我们看看是什么让它滴答作响。
DS3231 是一款 I2C 实时时钟 (RTC),具有内置温度补偿晶体振荡器 (TCXO) 和低成本且异常精确的晶体。当模块的电源中断时,设备有电池输入并保持精确的时间。该器件的长期精度因包含晶体振荡器而得到提高。RTC 跟踪秒、分钟、小时、天、日期、月和年。对于少于 31 天的月份,月末日期会自动修改,包括闰年更正。时钟具有 AM/PM 指示,可在 24 小时或 12 小时模式下工作。包括两个可编程的时间警报,以及一个可编程的方波输出。I2C 双向总线用于串行传输地址和数据。
DS3231 模块有 6 个引脚,用于从模块获取数据并为电路板供电。DS3231的引脚排列如下:
当我们使用示波器探测 DS3231 模块的 32k 引脚时,我们会从 IC 的内部振荡器获得 32kHz 信号。
典型 DS3231 RTC 模块板的关键组件是 DS3231 IC 和 AT24C32 EEPROM IC,用于存储时间和日期数据。其他组件包括电源开启 LED、一些电阻器、电容器、电池座和用于连接到微控制器的引脚。
当模块的主电源停止时,DS3231 包含电池输入并保持准确的时间。内置电源检测电路不断检查 VCC 的状态,以识别断电并自动切换到备用电源。因此,即使断电,您的 MCU 仍然能够保持时间跟踪。DS3231 RTC 模块上有一个 CR2032 电池座。用于 20 毫米 3V 锂纽扣电池的电池座位于电路板的底部。任何 CR2032 电池都可以使用。
充电能力:
该模块的设计方式是,当外部供电时,它可以为安装在模块上的电池充电。但是使用不可充电的 CR2032 电池时必须小心,因为模块也会为电池充电。CR2032 是不可充电的 3V 电池,但可充电电池可充电至 4.2V。要阻止模块对 CR2032 不可充电电池充电,应拆焊 U4(220R) 电阻或 D1 (1N4148) 二极管。
问:DS1307 和 DS3231 有什么区别?
DS3231 和 DS1370 之间最显着的区别在于计时精度。为了计时,DS1307 有一个外部 32kHz 晶体振荡器,而 DS3231 有一个内部振荡器。
问:DS3231 的精度如何?
DS3231 和 DS3234 中的温度补偿晶体振荡器 (TCXO) 符合要求,在 0°C 至 +40°C 的温度范围内精度高达 ±2 ppm。
问:DS3231 使用什么电池?
DS3231 使用 CR2032 可充电电池,但如果要使用不可充电电池,则需要对模块进行小幅修改。
在 DS3231 模块中设置时间相当简单。您需要做的就是在以下配置中将其连接到 Arduino。
完成上述连接后,您需要将 Arduino UNO 连接到您的 PC,打开 Arduino IDE,并安装 Arduino DS3231 Time Set Library。打开 Arduino IDE 并从菜单栏中选择 Library Manager。现在查找RTCLib和 DS3231 并获取最新版本,如下图所示。
代码非常简单。它将设置时间,然后将其显示在串行监视器上。
rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
rtc 对象在这一行中根据您计算机上的时间设置时间。它将更改您系统的当前时钟时间。
rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
您可以通过按以下顺序将日期时间值传递给函数来手动设置此行中的时间:年、月、日、小时、分钟和秒。我们将在下面的代码中设置系统的时间。结果,我们注释掉了这一行。
#include
#include
RTC_DS3231 rtc;
char t[32];
void setup()
{
Serial.begin(9600);
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
//rtc.adjust(DateTime(2019, 1, 21, 5, 0, 0));
}
void loop()
{
DateTime now = rtc.now();
sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
Serial.print(F("Date/Time: "));
Serial.println(t);
delay(1000);
}
Arduino数字时钟电路图 :
将 RTC 模块的 SCL 连接到 Arduino A5
将 RTC 模块的 SDA 连接到 Arduino A4
将 VCC 连接到 5v,将 GND 连接到 GND
将 LCD 的 RS 连接到 Arduino 的引脚 7
将 LCD 的 E 连接到 Arduino 的引脚 6
将 LCD 的 D7 连接到 Arduino 的引脚 2
将 LCD 的 D6 连接到 Arduino 的引脚 3
将 LCD 的 D5 连接到 Arduino 的引脚 4
将 LCD 的 D4 连接到 Arduino 的引脚 5
将 VSS、K、RW、D0、D1、D2、D3 连接到 GND
将 VDD 和 A 连接到 5v
将 VO 连接到电位器输出引脚(用于控制文本的对比度)
我们在代码中包含以下头文件,Wire.h 用于使用 I2C 与模块通信,LiquidCrystal.h用于在 LCD 显示器上显示时间,RTClib.h用于设置显示器时间并对其进行格式化。
#include
#include
#include
代码中的这一行指定 LCD 的哪个引脚连接到 Arduino 的哪个引脚。
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (rs, e, d4, d5, d6, d7)
如果项目因连接中断而启动,代码将在串行监视器中打印 RTC Module not Present。
if (! rtc.begin())
{
Serial.println(" RTC Module not Present");
while (1);
}
如果 RTC 掉电,模块中的时间出错,代码会自动设置模块中的时间,并从计算机时钟中获取时间。因此,请确保在设置时间时将 PC 上的时钟设置在正确的时间。
if (rtc.lostPower())
{
Serial.println("RTC power failure, reset the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
这部分代码将 LCD 上的光标设置为 0,并以 Date/Month/Year 格式打印日期。
void displayDate()
{
lcd.setCursor(0,0);
lcd.print("Date:");
lcd.print(now.day());
lcd.print('/');
lcd.print(now.month());
lcd.print('/');
lcd.print(now.year());
}
这部分代码将光标设置为 1,并以 Hour:Minute:Second 格式打印时间。
void displayTime()
{
lcd.setCursor(0,1);
lcd.print("Time:");
lcd.print(now.hour());
lcd.print(':');
lcd.print(now.minute());
lcd.print(':');
lcd.print(now.second());
lcd.print(" ");
}
上传代码后,您将能够在 LCD 屏幕上看到日期和时间。
#include
#include
#include
DateTime now;
RTC_DS3231 rtc;
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // (rs, e, d4, d5, d6, d7)
void displayDate(void);
void displayTime(void);
void setup ()
{
Serial.begin(9600);
lcd.begin(16,2);
if (! rtc.begin())
{
Serial.println(" RTC Module not Present");
while (1);
}
if (rtc.lostPower())
{
Serial.println("RTC power failure, reset the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop ()
{
now = rtc.now();
displayDate();
displayTime();
}
void displayDate()
{
lcd.setCursor(0,0);
lcd.print("Date:");
lcd.print(now.day());
lcd.print('/');
lcd.print(now.month());
lcd.print('/');
lcd.print(now.year());
}
void displayTime()
{
lcd.setCursor(0,1);
lcd.print("Time:");
lcd.print(now.hour());
lcd.print(':');
lcd.print(now.minute());
lcd.print(':');
lcd.print(now.second());
lcd.print(" ");
}
To set the Time
#include
#include
RTC_DS3231 rtc;
char t[32];
void setup()
{
Serial.begin(9600);
Wire.begin();
rtc.begin();
rtc.adjust(DateTime(F(__DATE__),F(__TIME__)));
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
}
void loop()
{
DateTime now = rtc.now();
sprintf(t, "%02d:%02d:%02d %02d/%02d/%02d", now.hour(), now.minute(), now.second(), now.day(), now.month(), now.year());
Serial.print(F("Date/Time: "));
Serial.println(t);
delay(1000);
}