欢迎光临
我们一直在努力

时钟模块DS1307 示例教程 适用于Arduino平台

1. 产品图片

2. 产品购买地址点我购买

3. 产品概述
DS1307是一款低功耗,具有56字节非失性RAM的全BCD码时钟日历实时时钟芯片,地址和数据通过两线双向的串行总线的传输,芯片可以提供秒,分,小时等信息,每一个月的天数能自动调整。并且有闰年补偿功能。AM/PM 标志位决定时钟工作于24小时或12小时模式,芯片有一个内置的电源感应电路,具有掉电检测和电池切换功能。

3. 产品参数
1. DS1307 I2C实时时钟芯片(RTC)
2. 24C32 32K I2C EEPROM存储器
3. 采用LIR2032可充电锂电池,并带充电电路
4. 解决DS1307带备用电池不能读写的问题。
5. 充满电后,能提供DS1307计时1年。
6. 设计小巧,27mm28mm8.4mm
7. 引出DS1307的时钟引脚,为单片机提供时钟信号。
8. 可以级联其他I2C设备。

4. 接线方式

5. 示例程序一

//中贝斯特UltiRobot时钟模块DS1307模块示例教程
//程序效果:编译并上传到Arduino,打开串口监控器,当在串口发送框内输入字符“D”时,会获取当前的时间。
//时间不对的话,可以在程序中设置好当前时间,随后上传代码,在串口发送框内输入字符“S”时,则会设置RTC为代码中指定的时间。
//输入“S”后再输入“D”,显示为您当前的时间了。重复上电,在串口发送框内“D”仍然可以获取当前时间,时钟模块会自动存储时间并运作。
//淘宝店地址:zhongbest.taobao.com
//专业Arduino资料网站:www.arduino365.com
#include <Wire.h>
#include <RTClib.h>
void printDateTime(DateTime dateTime);

//创建实例
RTC_DS1307 RTC;

void setup (void){
   Serial.begin(9600);
   //初始化总线
   Wire.begin();
   //初始化实时时钟
   RTC.begin(); 
}

void loop() {
   if (Serial.available() > 0) {
    int instruct = Serial.read();
    switch (instruct) {
     case 'D': {
       //获取当前日期和时间
       DateTime now = RTC.now();
       //通过串口传送当前的日期和时间      
       printDateTime(now);
       delay(100);
       break;
     } 
     case 'S':
       RTC.set(RTC_YEAR, 17);  //设置成17年
       RTC.set(RTC_MONTH, 4);  //设置成4月
       RTC.set(RTC_DAY, 18);  //设置成18日
       RTC.set(RTC_HOUR, 9);  //设置成9时
       RTC.set(RTC_MINUTE, 39);  //设置成39分
       RTC.set(RTC_SECOND, 01);  //设置成01秒
       break;
     }
   }
}

void printDateTime(DateTime dateTime) {
     //传送年份
     Serial.print(dateTime.year(), DEC);
     Serial.print('/');
     //传送月份
     Serial.print(dateTime.month(), DEC);
     Serial.print('/');
     //传送月份中的第几天
     Serial.print(dateTime.day(), DEC);
     Serial.print(' ');
     //传送小时
     Serial.print(dateTime.hour(), DEC);
     Serial.print(':');
     //传送分钟
     Serial.print(dateTime.minute(), DEC);
     Serial.print(':');
     //传送秒
     Serial.print(dateTime.second(), DEC);
     Serial.println();
}

6. 相关函数
include <Wire.h>
Arduino 与实时时钟通讯是通过I2C总线,为了使用这个总线,必须告知编译器加入这个库。 #include 是一种预编译指令,它告知编译器,在编译代码时加入Wire.h 这个文件,而这个文件则包含了我们使用I2C总线的所有函数,就是所谓的库。而紧接着的 #include <RTClib.h> 也是一样的意思。

Wire.begin();
begin() 则是Wire实例的一个方法,作用是初始化芯片的I2C总线,这个初始化只要一次就行,即使你有多个I2C设备也是如此,所以我们把它放在setup()里面。紧接着的RTC.begin() 也是一样的意思。

RTC_DS1307 RTC;
这是本章比较难理解的地方,RTC_DS1307 是实时时钟库的一个类,而后面的RTC,则是创建一个RTC_DS1307类的实例,这个实例包括一些相关的函数和变量。例如adjust() 是RTC_DS1307的一个方法,你可以通过实例来调用它,即RTC.adjust()

DateTime now =RTC.now();
now() 是RTC_DS1307 的另一个方法,它返回一个DateTime实例,保存着当前的日期时间信息,运行这条语句之后我们可以通过now.month() 获知当前的月份, 通过now.minute() 获取当前的分钟数,如此类推year、day、hour、second。

printDateTime(now);
printDateTime() 是一个把当前时间通过串口传送回电脑的函数,它接收一个Datatime 类型的参数。

RTC.set(RTC_MONTH, 6);
这条语句的作用是设置实时时钟的月份为6月,set()是一个专门设置实时时钟的函数,它接收两个参数,一个是设置的类别,这里的RTC_MONTH 表示月份,相应的还有 RTC_YEAR、RTC_DAY、RTC_MINUTE、RTC_SECOND。第二个参数这是设置的值、这里的6表示6月。

Serial.print(dateTime.year(), DEC);
这条语句的意思是把月份的数值通过串口传送回电脑。 print 是Serial(串口)实例的一个方法,它接收两个参数,第一个是传送的值,第二个是传送的格式,DEC表示10进制,还有OCT 表示8进制,HEX 被表示16进制。

7. 示例程序二

//中贝斯特UltiRobot时钟模块DS1307模块示例教程
//程序效果:打开串口监控器,当输入字符“F”时,串口窗口不会有任何反应,但Arduino会把年、月、日信息储存到EEPROM;
//输入字符“G”,则会把存储的年、月、日信息读取出来。复位Arduino后再次输入字符“G”,仍能把一样的信息读取出来,说明数据没有丢失。
//输入字符“P”,再输入字符“G”,可以看到日期被强制设定为4号
//淘宝店地址:zhongbest.taobao.com
//专业Arduino资料网站:www.arduino365.com
#include <Wire.h>
#include <AT24Cxx.h>
#include <RTClib.h>
AT24Cxx AT24C32(0x50);
RTC_DS1307 RTC;

void setup (void){
  //初始化串口
  Serial.begin(9600);
  //初始化I2C
  Wire.begin();
  //初始化RTC
  RTC.begin();
}

void loop() {
  //判断是否有新串口数据
  if (Serial.available() > 0) {
    //读取数据
    int instruct = Serial.read();

    switch (instruct) {
    case 'P': 
      {
        //先eeprom 指定地址写入数据
        AT24C32.WriteMem(0, 0x04);
        break;
      } 
    case 'G': 
      {
        char buffer[3];
        //读取三个字节数据
        AT24C32.ReadMem(0, buffer, 3);
        Serial.print(2000 + buffer[2], DEC);
        Serial.print('/');
        Serial.print(buffer[1], DEC);
        Serial.print('/');
        Serial.print(buffer[0], DEC);
        Serial.println();
        break;
      } 
    case 'F': 
      {
        //获取当前时间信息
        DateTime now = RTC.now();
        char buffer[3];
        buffer[0] = now.day();
        buffer[1] = now.month();
        buffer[2] = now.year() - 2000;
        //写入时间信息到eeprom
        AT24C32.WriteMem(0, buffer, 3);
        break;
      }
    }
  }
}

8. 相关函数
include <Wire.h>#include <AT24Cxx.h>
当设备要使用I2C总线时,必须包含Wire.h 这个文件。而AT24Cxx.h 则是AT24Cxx 系列通用的头文件。

AT24Cxx AT24C32(0x50);
创建一个AT24Cxx 实例,而0x50则是AT24C32的地址,上面介绍AT24C32 时提到这款芯片可以在I2C总线上挂接8个器件,那么我们如何区分开来这八个器件呢? AT24C32又是如何知道哪些数据是发给自己而不是别的总线上的器件呢?原来,AT24C32上还配备了三个地址选定管脚,A2、A1、A0。而高四位的地址已经固定为1010,A2、A1、A0三个地址脚的连接方式分别决定了后3位的数值。I2C模块上的AT24C32的A2、A1、A0 都接到了地,所以得出的7位地址为101 0000,写成16进制的话为0x50。

char buffer[3];
buffer[0] = now.day();
buffer[1] = now.month();
buffer[2] = now.year() – 2000;
AT24C32.WriteMem(0, buffer, 3);

这几行的代码的意思是把年、月、日信息写到EEPROM上,我们首先看WriteMem 这个方法,它是专门用来写(保存)数据到EEPROM的,它接收三个参数,第一个是地址,EEPROM内部是通过地址来区分数据存储位置的,例如 AT24C32,它具有4096字×8位字长的存储能力,则地址范围则是0 – 4096。这里第一个参数设的是“0”,他可以更改为0 – 4096中的任意一个数。第二个参数为需要写到存储器的数据块的开头地址,注意不是数据本身,而是数据的地址,比较容易理解的实现方式是声明一个数组,然后把数组名作为这个参数(数组名则为该数据块的起始地址)。最后一个参数是要写入的字节数,它不能大于数据块的大小(即数组的大小)。

AT24C32.WriteMem(0, 0x04);
这行代码的意思是把一字节的数据(0x04)写到EEPROM的地址为0的空间上,这里大家会发现这个方法的名字跟前面的一模一样,这是面向对象编程中一个叫重载的特性,这项特性允许创建函数名称相同但功能的输入输出类型不同的子程序,当你只要存储一个字节的数据时比较方便。

char buffer[3];AT24C32.ReadMem(0, buffer, 3);
这两行代码的意思是从EEPROM上读取三个字节的数据,并保存到缓冲数组上。ReadMem这个方法是专门把数据从EEPROM上读取出来。它接收三个参数,第一个是地址,第二个是缓冲块的开头地址(数组名),最后一个参数是要读取的字节数,它不能大于缓冲数据块的大小(即数组的大小)。

9. 相关下载
百度网盘:点我下载

未经允许不得转载:Arduino-Maker » 时钟模块DS1307 示例教程 适用于Arduino平台

支付宝扫码打赏 微信打赏

原创文章,若帮到您,欢迎打赏

分享到:更多 ()

评论 抢沙发

评论前必须登录!

 

线上商城

中贝斯特创客空间蘑菇云创客教育