Arduino Uno 使用DS3231高精度时钟模块实现获取时间和设置时间

arduino-ds3231-read-time-and-set-time-cover

实验效果

这次凌顺实验室( lingshunlab.com )分享的DS3231时钟模块将实现以下这两个功能:

1,通过串口监视器可以看到当前的时间。

2,通过串口监视器,输入时间,按发送可以设置时间。

arduino-ds3213-1

元件说明

20170728000020515

模块参数: 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

20170727234133376

安装库

本示例用到的库是Adafruit 写的RTClib,请先安装该库。

项目 - 加载库 - 管理库 - 在搜索框输入 “RTClib”

找到 Adafruit 的 RTClib

WX20211211-1209152x

程序提点

首先,需要先加载刚才安装的库

#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);
}