arduino是个功能很弱的单片机,自身没有获得当前时间的功能。仅有的mills()记录系统运行时长函数在49天左右后也会溢出而重置,无法用于时钟,故只能外加一个时钟芯片。
网上搜到的常用芯片一般是ds1307,比小指甲盖还小,成本只有几毛钱,很划算。因为后续我还有存储信息的需求,所以最终选择了集成DS3231 AT24C32 高精度时钟模块 IIC模块 存储模块功能的芯片,大概2/3大拇指那么大,某宝上一堆。
ds3231时钟模块参数如下:
DS3231是低成本、高精度I2C实时时钟(RTC),具有集成的温补晶振(TCXO)和晶体。包含扭扣电池,断开主电源时仍可保持精确的计时。
RTC保存秒、分、时、星期、日期、月和年信息。少于31天的月份,将自动调整月末的日期,包括闰年的修正。时钟的工作格式可以是24小时或带/AM/PM指示的12小时格式。提供两个可设置的日历闹钟和一个可设置的方波输出。地址与数据通过I2C双向总线串行传输。
精密的、经过温度补偿的电压基准和比较器电路用来监视VCC状态,检测电源故障,提供复位输出,并在必要时自动切换到备份电源。另外,/RST监视引脚可以作为产生μP复位的手动输入。
除计时精度高之外,DS3231还具有一些其它功能,这些功能扩展了系统主机的附加功能和选择范围。该器件内部集成了一个非常精确的数字温度传感器,可通过I2C*接口对其进行访问(如同时间一样)。这个温度传感器的精度为±3°C。片上控制电路可实现自动电源检测,并管理主电源和备用电源(即低压电池) 之间的电源切换。如果主电源掉电,该器件仍可继续提供精确的计时和温度,性能不受影响。当主电源重新加电或电压值返回到容许范围内时,片上复位功能可用来重新启动系统微处理器。
模块参数:
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.带电池CR2032,保证系统断电后,时钟任然正常走动
14.包装方式:单个防静电包装
一、接线说明(以Arduino uno r3为例):
SCL→A5
SDA→A4
VCC→5V
GND→GND
二、安装uRTCLib库(找来找去,还是这个库好用,似乎是针对这快集成芯片封装的)
三、使用uRTCLib库测试初始化和读取ds3231的时间
#include <uRTCLib.h>
#include "Arduino.h"
#include "Wire.h"
#include "uRTCLib.h"
uRTCLib rtc;
unsigned int pos;
void setup() {
delay (2000);
Serial.begin(9600);
Serial.println("Serial OK");
// Max position: 32767
for (pos = 0; pos < 1000; pos++) {
rtc.eeprom_write(pos, (unsigned char) pos % 256);
}
//芯片初次使用时初始化一次当前时间,成功后注掉这行
//rtc.set(0, 36, 15, 6, 24, 12, 16); //初始化时间rtc.set(second, minute, hour, dayOfWeek, dayOfMonth, month, year)
pos = 0;
#if def _VARIANT_ARDUINO_STM32_
#Serial.println("Board: Maple");
#else
#Serial.println("Board: Other");
#endif
}
void loop() {
rtc.refresh();
Serial.print("RTC DateTime: ");
Serial.print(rtc.year());
Serial.print('/');
Serial.print(rtc.month());
Serial.print('/');
Serial.print(rtc.day());
Serial.print(' ');
Serial.print(rtc.hour());
Serial.print(':');
Serial.print(rtc.minute());
Serial.print(':');
Serial.print(rtc.second());
Serial.print(" DOW: ");
Serial.print(rtc.dayOfWeek());
Serial.print(" ---- ");
Serial.print(pos);
Serial.print(": ");
Serial.print(rtc.eeprom_read(pos));
Serial.println();
pos++;
pos %= 1000;
delay(1000);
}
运行效果:
把时间打印到led的效果:
yan 2016.12.24 15:59
参考:
https://detail.tmall.com/item.htm?id=41231526179
https://github.com/Naguissa/uRTCLib
厉害!