前言
目前有许多流行的串行时钟电路,例如 DS1302,DS3231,DS1307,PCF8485 等。它们由于其简单的接口,低成本和易用性而被广泛使用。在本实验中,我们将使用 DS1302 实时时钟模块,DS1302 是一种高性能、低功耗、带 RAM 的实时时钟电路,它可以对 年、月、日、周、时、分、秒进行计时,具有闰年补偿功能。
电气参数
宽范围工作电压 | 2.0 -5.5V |
---|---|
工作电流 | 2.0V 时,小于 300nA |
字符组方式 | 单字节传送和多字节传送 |
工作温度 | -40℃~+85℃ |
经典应用电路
DS1302采用三线接口与 CPU 进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或 RAM 数据。DS1302 内部有一个 31×8 的用于临时性存放数据的 RAM 寄存器。DS1302 是 DS1202 的升级产品,与 DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。
接线
Arduino | LCD1602 | DS1302 |
---|---|---|
5V | VCC | VCC |
A4 | SDA | - |
A5 | SCL | - |
5 | - | RST |
6 | - | DAT |
7 | - | CLK |
GND | GND | GND |
程序
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <stdio.h>
#include <DS1302.h>
LiquidCrystal_I2C lcd(0x27,16,2); // 将LCD地址设置为0x27,用于16个字符和2行显示
namespace {
const int kCePin = 5;
const int kIoPin = 6;
const int kSclkPin = 7;
// Create a DS1302 object.
DS1302 rtc(kCePin, kIoPin, kSclkPin);
String dayAsString(const Time::Day day) {
switch (day) {
case Time::kSunday: return "Sunday";
case Time::kMonday: return "Monday";
case Time::kTuesday: return "Tuesday";
case Time::kWednesday: return "Wednesday";
case Time::kThursday: return "Thursday";
case Time::kFriday: return "Friday";
case Time::kSaturday: return "Saturday";
}
return "(unknown day)";
}
void printTime() {
// 获取当前时间和日期
Time t = rtc.time();
const String day = dayAsString(t.day);
// Format the time and date and insert into the temporary buffer. //格式化时间和日期并插入临时缓冲区。
char buf[50]; //定义一个字符型数组用来存放日期数据(用于串口打印)
char DateBuf[12]; //定义一个字符型数组用来存放日期数据(由于1602每行只能打印16个字符,所以日期和时间分两个数组存)
char TimeBuf[10];//定义一个字符型数组用来存放时间数据(由于1602每行只能打印16个字符,所以日期和时间分两个数组存)
snprintf(buf, sizeof(buf), "%s %04d-%02d-%02d %02d:%02d:%02d",day.c_str(),t.yr, t.mon, t.date,t.hr, t.min, t.sec);
//把日期和时间数据存放到数组中
snprintf(DateBuf,sizeof(DateBuf),"%04d-%02d-%02d",t.yr, t.mon, t.date); //把日期数据存放到数组中
snprintf(TimeBuf,sizeof(TimeBuf),"%02d:%02d:%02d",t.hr, t.min, t.sec); //把时间数据存放到数组中
Serial.println(buf); //串口打印输出日期与时间
lcd.setCursor(2,0); //设置1602的光标到第0行第2个字符处
lcd.print(DateBuf); //在LCD光标所在处打印DateBuf数组里的数据
lcd.setCursor(3,1); //设置1602的光标到第1行第3个字符处
lcd.print(TimeBuf); //在LCD光标所在处打印TimeBuf数组里的数据
}
}
void setup() {
lcd.init(); //初始化LCD
lcd.backlight(); //打开LCD背光
Serial.begin(9600); //初始化串口
rtc.writeProtect(false);
rtc.halt(false);
// Make a new time object to set the date and time.
// Wednesday, March 2, 2023 at 16:49:46.
Time t(2023, 3, 2, 16, 49, 46, Time::kWednesday);
// Set the time and date on the chip.
rtc.time(t);
}
// 每秒钟循环并打印一次时间。
void loop() {
printTime();
delay(1000);
}