Arduino Uno 使用DS3231高精度时钟模块实现获取时间和设置时间
目录
实验效果
这次凌顺实验室( lingshunlab.com )分享的DS3231时钟模块将实现以下这两个功能:
1,通过串口监视器可以看到当前的时间。
2,通过串口监视器,输入时间,按发送可以设置时间。
元件说明
模块参数: 1.尺寸:38mm(长)22mm(宽)14mm(高) 2.重量:8g 3.工作电压:3.3--5.5V 4.时钟芯片:高精度时钟芯片DS3231 5.时钟精度:0-40℃范围内,精度2ppm,年误差约1分钟 6.带2个日历闹钟 7.可编程方波输出 8.实时时钟产生秒、分、时、星期、日期、月和年计时,并提供有效期到2100年的闰年补偿 9.芯片内部自带温度传感器,精度为±3℃ 10.存储芯片:AT24C32(存储容量32K) 11.IIC总线接口,最高传输速度400KHz(工作电压为5V时) 12.可级联其它IIC设备,24C32地址可通过短路A0/A1/A2修改,默认地址为0x57 13.带可充电电池LIR2032,保证系统断电后,时钟任然正常走动
引脚说明
32K :32 kHz频率输出
SQW :低电平有效中断或方波输出
SCL :串行时钟输入。
SDA :串行数据输入、输出。
VCC :电源,接3.3V - 5V
GND :接地
BOM表
名称 | 数量 |
---|---|
Arduino Uno | x1 |
DS3231时钟模块 | x1 |
跳线(杜邦线) | 若干 |
接线说明
Arduino Uno 引脚 | <-> | DS3231 引脚 |
---|---|---|
5V | <-> | VCC |
GND | <-> | GND |
A5 | <-> | SCL |
A4 | <-> | SDA |
安装库
本示例用到的库是Adafruit 写的RTClib,请先安装该库。
项目 - 加载库 - 管理库 - 在搜索框输入 “RTClib”
找到 Adafruit 的 RTClib
程序提点
首先,需要先加载刚才安装的库
#include "RTClib.h"
之后,就可以创建一个名为rtc的DS3231实例,就可以调用RTC_DS3231的函数
RTC_DS3231 rtc;
用来设置时间的函数是rtc.adjust
,例如:
rtc.adjust(DateTime(to_year, to_month, to_day, to_hours, to_minute, to_second));
用 rtc.now()
来获取DS3231的时间,返回的是一个DateTime类型的数据,该类型包含了年月日时分秒的数据,例如:
DateTime now = rtc.now();
// 通过串口输出显示DS3231的当前时间
Serial.print(now.year(), DEC); // 以 10进制显示 年
Serial.print('/');
Serial.print(now.month(), DEC);// 以 10进制显示 月
Serial.print('/');
Serial.print(now.day(), DEC);// 以 10进制显示 日
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);// 以 10进制显示 时
Serial.print(':');
Serial.print(now.minute(), DEC);// 以 10进制显示 分
Serial.print(':');
Serial.print(now.second(), DEC);// 以 10进制显示 秒
Serial.println();
程序实现
// by lingshunlab.com
// 加载DS3231的库
#include "RTClib.h"
// 创建rtc实例
RTC_DS3231 rtc;
String input_string; // 声明变量 input_string ,用于存储串口输入的数据
// 声明二维数组变量 daysOfTheWeek,用于通过数组的索引 (index) 匹配对应的星期名称
char daysOfTheWeek[7][12] = {"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"};
// 获取串口数据函数
void GetSerialStuff(String& input_string) {
String temp_string = ""; // 声明变量 temp_string,用于临时存储串口输入的数据
while(Serial.available()) { // 当串口有数据时,循环执行
temp_string += (char)Serial.read(); // 把读取的串口数据,逐个组合到inStr变量里
delay(2);
}
input_string = temp_string; // 把引用指针的变量赋值为 tempStr
}
void setup() {
Serial.begin(9600);
// 初始化rtc,
if (! rtc.begin()) { // 若果初始化失败,则
Serial.println("Couldn't find RTC");
Serial.flush();
abort(); // 程序停止运行
}
}
void loop() {
GetSerialStuff(input_string); // 获取串口的数据
if(input_string != "") { // 如果 串口不为空,则
int to_year = input_string.substring(0, 4).toInt(); // 从字符串中截取 年 的数据并转换成int数据类型
int to_month = input_string.substring(5, 7).toInt(); // 从字符串中截取 月 的数据并转换成int数据类型
int to_day = input_string.substring(8, 10).toInt(); // 从字符串中截取 日 的数据并转换成int数据类型
int to_hours = input_string.substring(11, 13).toInt(); // 从字符串中截取 时 的数据并转换成int数据类型
int to_minute = input_string.substring(14, 16).toInt(); // 从字符串中截取 分 的数据并转换成int数据类型
int to_second = input_string.substring(17, 19).toInt(); // 从字符串中截取 秒 的数据并转换成int数据类型
// 重新设定DS3231模块的时间
rtc.adjust(DateTime(to_year, to_month, to_day, to_hours, to_minute, to_second));
delay(100);
}
// 获取DS3231的时间
DateTime now = rtc.now();
// 通过串口输出显示DS3231的当前时间
Serial.print(now.year(), DEC); // 以 10进制显示 年
Serial.print('/');
Serial.print(now.month(), DEC);// 以 10进制显示 月
Serial.print('/');
Serial.print(now.day(), DEC);// 以 10进制显示 日
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);// 以 10进制显示 时
Serial.print(':');
Serial.print(now.minute(), DEC);// 以 10进制显示 分
Serial.print(':');
Serial.print(now.second(), DEC);// 以 10进制显示 秒
Serial.println();
// 通过串口输出显示DS3231的温度传感器数据
Serial.print("Temperature: ");
Serial.print(rtc.getTemperature());
Serial.println(" C");
delay(1000);
}