DS1302时钟模块LCD1602显示

  • DS1302时钟模块相关介绍
    • 基本介绍
      • 概述
      • 特点
      • 各引脚功能
      • 相关寄存器
    • 时序图
      • 单字节写时序
      • 单字节读时序
      • 时钟/日历多字节(Burst)方式
  • 代码
    • main.c
    • lcd1602.c
    • ds1302.c
  • 项目展示

DS1302时钟模块相关介绍

基本介绍

概述

DS1302 可慢速充电实时时钟芯片包含实时时钟/日历和 31 字节的非易失性静态 RAM。它经过一个简
单的串行接口与微处理器通信。实时时钟/日历可对秒,分,时,日,周,月,和年进行计数,对于小于
31 天的月,月末的日期自动进行调整,还具有闰年校正的功能。时钟可以采用 24 小时格式或带 AM(上
午)/PM(下午)的 12 小时格式。31 字节的== RAM== 可以用来临时保存一些重要数据。使用同步串行通信,
简化了 DS1302 与微处理器的通信。与时钟/RAM 通信仅需3 根线:(1)RST(复位),(2)I/O(数据线)
和(3)SCLK(串行时钟)。数据可以以每次一个字节的单字节形式或多达 31 字节的多字节形式传输。DS1302
能在非常低的功耗下工作,消耗小于 1µW 的功率便能保存数据和时钟信息。

特点

各引脚功能


各引脚的功能:
Vcc1:主电源;Vcc2:备份电源。 当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2<Vcc1时,由Vcc1向DS1302供电。
SCLK: 串行时钟,输入,控制数据的输入与输出;
I/O: 三线接口时的双向数据线;
CE: 输入信号,在读和写的器件必须为高。该引脚有两个功能:1.开始控制字访问移位寄存器的控制逻辑;2.提供结束单字节或多字节数据传输的方法。

相关寄存器

有关日历、时间的寄存器共有12个,其中有7个寄存器(读时81H——8DH,写时80H——8CH==)存放的数据格式是BCD码形式。如图所示

小时寄存器
位7用于定义DS1302是采用12小时模式还是24小时模式。高:12小时模式。在12小时模式时,位5 为1时,表示PM。在24小时模式时,为5是第二个10小时位。
秒寄存器
的就位7定义为时钟暂停标志(CH)。1:时钟振荡器停止,DS1302进入低功耗状态,当该位置为0时,时钟开始运行。
控制寄存器
的位7是写保护位(WP),其他7位均置0,对时钟和RAM进行写操作时,WP必须为0,也就是关闭写保护,当WP为1时,就是只读模式。
DS1302相关的RAM地址
DS1302中附加31字节静态RAM的地址如下图

DS1302的工作模式寄存器
所谓的突发模式(BURST模式)就是一次性传送多个字节的时钟信号和RAM数据。比如我可以一次性把时间和日期写入,也可以一次性的读出时间和日期。

通过对 31(十进制)位地址寻址(地址/命令位于 1 至 5=逻辑 1),可以把时钟/日历或 RAM 寄存器规定为多字节方式。如前所述,位 6 规定时钟或 RAM 而位 0 规定读或写。在时钟\日历寄存器中的地址 9 至 31或 RAM 寄存器中的地址 31 不能存储数据。在多字节方式中读或写从地址 0 的位 0 开始。当以多字节方式写时钟寄存器时,必须按数据传送的次序写最先 8 个寄存器。意思就是写我们不是只有7个吗?时分秒、年月日、周一共七个 但是吧它得字节数为8 所有要写够8次。
但是,当以多字节方式写 RAM 时,为了传送数据不必写所有 31 个字节。不管是否写了全部 31 个字节,所写的每一个字节都将传送至 RAM。

DS1302充电寄存器
这个我没整过,全部复制手册的。哈哈

这个寄存器控制 DS1302 的慢速充电特性。图 4 的简化电路表示慢速充电器的基本组成。慢速充电选择(TCS)位(位 4-7)控制慢速充电器的选择。为了防止偶然的因素使之工作,只有 1010 模式才能使慢
速充电器工作,所有其它的模式将禁止慢速充电器。DS1302 上电时,慢速充电器被禁止。二极管选择(DS)位(位 2-3)选择是一个二极管还是两个二极管连接在 Vcc2 与 Vcc1 之间。如果 DS 为 01,那么选择一个二极管;如果 DS 为 10,则选择两个二极管。如果 DS 为 00 或 11,那么充电器被禁止,与 TCS 无关。RS 位(位0-1)选择连接在 Vcc2 与 Vcc1 之间的电阻。电阻选择(RS)位选择的电阻如下:

如果 RS 为 00,充电器被禁止,与 TCS 无关。
二极管和电阻的选择用户根据电池和超容量电容充电所需的最大电流决定。最大充电电流可以如下列
所说明的那样进行计算。假定 5V 系统电源加到 Vcc2 而超容量电容接至 Vcc1。再假设慢速充电器工作时在Vcc2 和 Vcc1 之间接有一个二极管和电阻 R1。因而最大电流可计算如下:
Imax =(5.0V-二极管压降)/R1
=(5.0V-0.7V)/2kΩ
= 2.2mA
显而易见,当超容量电容充电时,Vcc2 和 Vcc1 之间的电压减少,因而充电电流将会减小。

时序图

我们首先得给DS1302时钟模块写入时间和日期,然后呢这个时钟会自己走,我们之后只需要读取时间和日期即可。我们直接看时序图 编写代码

单字节写时序

数据输入
跟随在输入写命令字节的 8 个 SCLK 周期之后,在下 8 个 SCLK 周期的上升沿输入数据。如果有额外的SCLK 周期,它们将被忽略。输入从位 0 开始。

上面时序图是前8位是地址,后8位是数据。
我们根据上面的时序图 来编写 单字节写的一个函数
发现上面的

/*DS1302写单字节函数*/
void ds1302_write_byte(unsigned char addrOrData)
{unsigned char i = 0;for(i=0;i<8;i++)   {DAT = addrOrData & 0x01;   //开始传输低位 addrOrData = addrOrData >> 1;//右移一位CLK = 1;                     //拉高时钟表示已经发送CLK = 0;                   //拉低时钟准备继续放新的数据位}
}/*DS1302写函数*/
void ds1302_write(unsigned char addr,unsigned char data)
{RST = 0; //RST拉低SCLK = 0; //时钟SCLK也拉低RST = 1; //准备开始写   ds1302_writeByte(addr);  //写入要写的地址ds1302_writeByte(dat);     //写入地址的数据RST = 0; //关闭 表示结束
}


看上面的图,比如我想写入时 为18点 时的写寄存器是84H 数据就是18点 但是DS1302存储格式为 BCD 码那就是 0x18。
那写入 时 为18点 的代码则是:

ds1302_write(0x84,0x18); //写入时  为 18点

单字节读时序


/*DS1302读单字节函数*/
unsigned char ds1302_read_byte(unsigned char data)
{unsigned char i;for(i=0;i<8;i++){dat = dat >> 1; //右移一位 数据是先从低位开始if(IO == 1)dat = dat | 0x80;  //1000 0000elsedat = dat & 0x7f;   //0111 1111SCLK = 1; //时钟拉高表示这位已经结束SCLK = 0; //时钟拉低开始接收新的数据位}return data;
}/*DS1302读取数据函数*/
unsigned char ds1302_read_data(unsigned char addr)
{unsigned char data; //用于存放接收的数据RST = 0; //RST拉低SCLK = 0; //时钟SCLK也拉低RST = 1; //准备开始写    ds1302_write_byte(addr);    //写入要读取的地址data = ds1302_read_byte(data); //读取地址的数据RST = 0;//关闭 表示结束return data;   //返回读取到的数据
}

我们想读取时 里面时间 看看现在是几点 时 读寄存器是85H

time = ds1302_read_data(0x85);

写保护寄存器
写保护寄存器的位 7 是写保护位。开始 7 位(位 0-6)置为零,在读操作时总是读出零。在对时钟或
功能 字节数 脉冲数
CLOCK 8 72
RAM 31 256
DS1302
RAM 进行写操作之前,位 7 必须为零。当它为高电平时,写保护位禁止对任何其它寄存器进行写操作。

时钟/日历多字节(Burst)方式

所谓的突发模式(BURST模式)就是一次性传送多个字节的时钟信号和RAM数据。比如我可以一次性把时间和日期写入,也可以一次性的读出时间和日期。

代码

部分代码呈现

main.c

#include <reg52.h>
#include "lcd1602.h"
#include "ds1302.h"void main()
{lcd_init();   //初始化LCD1602 ds1302_init();//初始化DS1302while(1){ds1302_burst_read(DS1302_READ_TIME); //读取日期和时间lcd_display_dateAndTime(); //1602显示日期和时间    }
}

lcd1602.c

/*初始化LCD1602函数*/
void lcd_init()
{unsigned char array1[] = "date:    -  -  ";unsigned char array2[] = "time:  :  :  "; write_com(CURSOR_RIGHT); //写入数据后光标自动右移 整屏不移动。 0x40(光标左移 整屏不移动)0x05(左移 整屏右移)0x07(右移 整屏右移)write_com(CLOSE_DIS_CUR); //开显示功能 无光标 不闪烁write_com(DIS_5X7); //数据总线8位 16X2显示 5*7点阵write_com(CLEAR_SCREEN); //清屏 0000 0001lcd_display_str(0,0,array1);  //第一行显示  date:    -  -  lcd_display_str(0,1,array2);  //第二行显示    time:  :  :  }/*LCD1602 显示DS1302日期和时间 函数*/
void lcd_display_dateAndTime()
{   lcd_display_byte(5,0,(time[7]>>4)+48);   //显示年lcd_display_byte(6,0,(time[7]&0x0f)+48);lcd_display_byte(7,0,(time[6]>>4)+48);     //显示年lcd_display_byte(8,0,(time[6]&0x0f)+48);lcd_display_byte(10,0,(time[4]>>4)+48);    //显示月lcd_display_byte(11,0,(time[4]&0x0f)+48);lcd_display_byte(13,0,(time[3]>>4)+48);   //显示日lcd_display_byte(14,0,(time[3]&0x0f)+48);lcd_display_byte(5,1,(time[2]>>4)+48);    //显示时lcd_display_byte(6,1,(time[2]&0x0f)+48);lcd_display_byte(8,1,(time[1]>>4)+48); //显示分lcd_display_byte(9,1,(time[1]&0x0f)+48);lcd_display_byte(11,1,(time[0]>>4)+48);    //显示秒lcd_display_byte(12,1,(time[0]&0x0f)+48);lcd_display_byte(14,1,(time[5]&0x0f)+48);   //显示周   }

ds1302.c

#include "ds1302.h"unsigned char time[8] = {0x00,0x45,0x19,0x18,0x10,0x01,0x21,0x20};//秒分时 日月周 年/*DS1302单字节读数据函数*/
unsigned char ds1302_readByte(unsigned char dat)
{unsigned char i = 0;for(i=0;i<8;i++)  {dat = dat >> 1;    //左移一次 低位开始 共有效左移7次if(DAT == 1)      dat = dat | 0x80;   //高位置1elsedat = dat & 0x7F;    //高位置0 CLK = 1; //时钟拉高表示这位已经结束CLK = 0; //时钟拉低开始接收新的数据位}  return dat;}/*DS1302单字节写地址或者数据函数*/
void ds1302_writeByte(unsigned char addrOrData)
{unsigned char i = 0;for(i=0;i<8;i++)   {DAT = addrOrData & 0x01;   //开始传输低位 addrOrData = addrOrData >> 1;//右移一位CLK = 1;                     //拉高时钟表示已经发送CLK = 0;                   //拉低时钟准备继续放新的数据位}}/*DS1302时钟模块写命令函数*/
void ds1302_writeCom(unsigned char addr,unsigned char dat)
{RST = 0; //拉低RSTCLK = 0; //拉低时钟RST = 1; //使能打开ds1302_writeByte(addr);    //写入要写的地址ds1302_writeByte(dat);     //写入地址的数据RST = 0; //关闭 表示结束
}/*DS1302时钟模块读数据函数*/
unsigned char ds1302_readData(unsigned char addr)
{unsigned char dat = 0;RST = 0; //拉低RSTCLK = 0; //拉低时钟RST = 1; //打开使能ds1302_writeByte(addr);        //写入要读的地址dat = ds1302_readByte(dat);   //读取地址的数据RST = 0; //关闭 表示结束return dat; //返回读取到的数据
}/*DS1302时钟模块读取日期和时间函数*/
void ds1302_read_DateAndTime()
{time[0] = ds1302_readData(DS1302_READ_YEAR);  //读取年time[1] = ds1302_readData(DS1302_READ_MONTH); //读取月time[2] = ds1302_readData(DS1302_READ_DAY);   //读取日time[3] = ds1302_readData(DS1302_READ_HOUR);  //读取时time[4] = ds1302_readData(DS1302_READ_MINUTE);//读取分time[5] = ds1302_readData(DS1302_READ_SECOND);//读取秒time[6] = ds1302_readData(DS1302_READ_WEEK);  //读取周
}/*DS1302时钟模块初始化函数*/
void ds1302_init()
{RST = 0; //关闭RSTCLK = 0; //拉低时钟ds1302_writeCom(DS1302_WRITE_PROTECT,0x00); //关闭写保护 这样才能进行写操作ds1302_burst_write(DS1302_WRITE_TIME);   //初始化全部时间//ds1302_initTime(); //初始时间:2021年10月18日 19点45分00秒 周一    ds1302_writeCom(DS1302_WRITE_PROTECT,0x80); //开启写保护 只读模式}

项目展示


如果觉得这篇文章对你有用。欢迎大家点赞、评论哈哈
需要整个工程代码,欢迎大家打赏,评论区留上你的邮箱 or vx or qq。o( ̄︶ ̄)o

继续加油!!!

基于51单片机+DS1302时钟模块+LCD1602显示相关推荐

  1. 基于51单片机驱动MPU6050模块(LCD1602显示)

    @TOC 一.简介 MPU-6050集成了3轴MEMS陀螺仪,3轴MEMS加速度计,以及一个可扩展的数字运动处理器DMP,可用IIC接口连接一个第三方的数字传感器.MPU-6050对陀螺仪和加速度计分 ...

  2. 基于51单片机ds1302时钟、ds18b20、lcd12864的恒温器

    目录 项目:基于51单片机ds1302时钟.ds18b20的恒温器 功能说明: 运行流程: 效果展示: 供电方式: 用途: 提高: 附: ​                              ...

  3. 基于51单片机驱动ADXL346 (LCD1602显示)

    基于51单片机驱动ADXL346 (LCD1602显示) 一.ADXL346传感器介绍 1.实物图 2.产品说明 3.电气参数 4.通信协议 二.驱动代码 1.引脚定义 2.初始化函数 3.主函数 三 ...

  4. 基于51单片机的电子钟万年历LCD1602显示

    本设计是51单片机的电子钟万年历LCD1602显示(proteus仿真+程序+报告+器件清单) 仿真图proteus 7.8 程序编译器:keil 4/keil 5 编程语言:C语言 编号C0002 ...

  5. 基于51单片机+红外遥控解码+LCD1602显示

    红外遥控解码(NEC) 基本介绍 什么是红外线? 红外线系统的组成 发射管和接收管 红外遥控发射(载波频率) 重要介绍 NEC协议 数据格式(必看) 位定义(必看) 编写程序思路(2种) 方式一 方式 ...

  6. 基于51单片机的时钟系统

     这一次带来的项目是课程设计级别的基于51单片机的时钟系统,本次的项目共有两种,一种是基础功能时钟,上电后自动从00-00-00开始计时,另一种加上了调时功能,上电后自动从00-00-00开始,当需要 ...

  7. 【Proteus仿真】51单片机汇编实现DS18B20+LCD1602显示

    [Proteus仿真]51单片机汇编实现DS18B20+LCD1602显示 Proteus仿真 汇编代码(.asm) ;**************************************** ...

  8. 【Proteus仿真】51单片机制作简易计算器+ LCD1602显示

    [Proteus仿真]51单片机制作简易计算器+ LCD1602显示 Proteus仿真效果演示 程序代码 #include<reg51.h> //头文件 #define uint uns ...

  9. 【Proteus仿真】51单片机+SHT11温湿度传感器+LCD1602显示

    [Proteus仿真]51单片机+SHT11温湿度传感器+LCD1602显示 Proteus仿真 主程序代码 /*-------------------------------SHT11湿度测量 -- ...

  10. 基于51单片机电子时钟

    keil工程与protues仿真电路 1 基于51单片机用LCD1602实现时-分的显示 2. 按键控制时-分的调整 3. 能实现整时报时的功能(蜂鸣器响) 4. 闹钟模式 5.按键切换模式(模式一: ...

最新文章

  1. Android_开源框架_Volley实例
  2. 调整数组顺序使奇数位于偶数的前面
  3. 编译安装MySQL5.6失败的相关问题解决方案
  4. VNX证书过期解决方案(2018-11-02)
  5. springMVC - 之拦截器
  6. 基于python的nlp预备知识
  7. java2ee和java2se_Java知识:(2)JavaSE和JavaEE
  8. Pygal简单使用——模拟掷骰子
  9. Python爬虫学习第一天--uillib库和request库
  10. react里面的this_React 为啥要绑定this
  11. 正则表达式学习笔记009--大括号与选择符的认识与应用
  12. eclipse如何修改字体大小
  13. Redis常见配置介绍
  14. 在java中改变圆半径_java小例子:打印一个近似圆,要求根据给定半径圆的大小随之发生改变...
  15. https://www.cnblogs.com/skywang12345/category/455711.html
  16. 大数据BI平台建设需注意什么问题
  17. pytho运算符练习
  18. 包政讲营销录音(1)
  19. Allegro-CRTL键的使用
  20. LVGL lv_cont 容器(8)

热门文章

  1. 2022 老A卡密验证系统
  2. Android 高德地图 Native method not found: com.autonavi.amap.mapcore.MapCore.nativeNewInstance:(Ljava/lan
  3. 【win】全屏、窗口化、动态修改分辨率和获取屏幕支持的所有分辨率
  4. java表格数据导出到Excel案例
  5. 【游戏引擎Easy2D】场景和文本,不同的输出方式
  6. 关于vs2008改变工程路径
  7. Win10系统蓝屏错误DPC怎么解决【系统天地】
  8. 基于FPGA VHDL 的 ASK调制与解调设计(附源码)
  9. 十大免费java开源商城系统
  10. 阵列式键盘实训C语言,新人求教 阵列式键盘