轻松吃透实时时钟芯片DS1302软硬件设计,看完秒懂
今天我们来讨论一款老掉牙的实时时钟芯片DS1302。什么是实时时钟(RealTime Clock, RTC)呢?为什么我们需要它呢?假设你使用单片机实现万年历应用,一般的做法是这样的:设置中断后判断1秒是否到来,如果到来就将秒数加1,然后再考虑一些进位处理,例如,每60秒则分钟加1,每60分则小时加1, 24小时或12小时制也要区分对待,每12个月则年加1,还要考虑闰月闰年。虽然考虑的事情好像有些多,但是在资讯非常发达的今天,从网络上搜索出现成的代码也绝不是难事。
当然,利用代码来实现这些算法并不是惟一途径,你也可以使用实时时钟芯片来减轻编程负担,只要我们把芯片内的年月日时分秒等参数设置为当前时间,启动后内部会自动开始计数,理论上芯片记录的时间将与我们的时间实时同步,进位的问题也由芯片自行处理,我们只需要在必要的时候从芯片中读取一些时间值即可,实在不要太简单。
DS1302就是一款使用广泛的RTC芯片,我们来看看与时间相关的寄存器有哪些,如下图所示(DS1302内部另外还有31个字节的RAM,本文不涉及):
首先我们关注一下地址,可能不少人会想:这些地址怎么这么怪呢?你这个厂家设计芯片时就不能靠谱点吗?地址从0x00开始连续增加会死呀?竟然还分为不同的读写地址,我看这个芯片设计者是闲得“淡”疼,简单的问题复杂化!
然而实际上,这9个寄存器地址的确是0x0~0x8,并且读写的也确实是同一个地址的数据,只不过数据手册在标记这些地址时,把发送串行数据中的其它一些位也考虑进来了。我们来看看如何往DS1302中写入一个字节的数据,相应的时序如下图所示:
可以看到,单个字节数据写入到DS1302需要两个字节,前一个字节用来确定写数据的目的地址。后一个字节就是需要写入的数据。请注意:两个字节都是以低位先行的方式发送,正常情况下确定地址的前一个字节如下图所示
读写数据时最高位(第7位)必须为1,最低位用来表示读(RD=1)还是写(WR=0)数据。我们刚刚提过,DS1302内部额外还有31个字节的RAM,可作为通用的RAM使用,第6位表示往RAM(RAM=1)还是RTC(CK=0)中写入(或读取)数据,前面表格中标注的写或读地址就是把这8位都考虑进来了。
如果你往RTC中写入数据,第7位总是1,第6位与第0位总是0,所以写的地址总是偶数,读的地址总是奇数。是不是闲得“淡”疼呢?还真不是,因为从本质上来讲,读写信号以及访问区域(RAM/CK)选择位也可以算是地址线。例如,以前讨论的HD44780有一个RS引脚表示写入的是数据还是指令,但是你也可以认为它是一条地址线,它决定你将代码写入数据寄存器还是指令寄存器。
好吧!地址的事情已经谈妥了,咱们来一一介绍DS1302内部与时间有关的寄存器:
(1)【地址0x80】秒钟寄存器(Seconds):DS1302中RTC寄存器都是以BCD码来保存的,也就是说,个位与十位分别占用一些位。在8位秒钟寄存器中,BIT3~0用来保存秒钟的个位,BIT6~4用保存秒钟的十位,因为秒数是不可能大于5的,所以用3位已然足够,而最高位BIT7表示时钟挂起位(ClockHalt, CH),当CH=1时,时钟暂时处于挂起状态(暂停计数),当CH=0时,计数才会开始运行。这个寄存器的设计还是很巧妙的,也就是说,只要我们往秒寄存器写入实际的秒钟数时,CH位都会被清零。换句话说,一般情况下,我们都会先初始化年月日时分等其它寄存器,而秒钟寄存器留待最后设置,同时也开启了芯片计数。
(2)【地址0x82】分钟寄存器(Minutes):与秒钟寄存器一样,BIT3~0用来保存分钟的个数,BIT6~4用保存分钟的十位,最高位是无效的。
(3)【地址0x84】小时寄存器(Hour):该寄存器的低4位保存小时的个位,而小时的十位则取决于时间是24还是12小时制。BIT7=1时为12小时制,那么小时的十位不可能大于1(1~12),它只需要一位(BIT4)表示即可,只是还多了一个BIT5用来表示下午(PM=1)还是上午(AM=0);而BIT7=0时为24小时制,十位数最大值可能为2(0~23),所以用BIT5~BIT4表示小时的十位。
(4)【地址0x86】日期寄存器(Date):日期表示一个月份有多少天,其范围为1~31,十位最大值为3,所以用BIT5~4表示十位,BIT3~0表示个位。
(5)【地址0x88】月份寄存器(Month):月份范围是1~12,所以用BIT4表示十位,BIT3~0表示个位。
(6)【地址0x8A】星期寄存器(Day):星期的范围是1~7,所以用BIT2~BIT0表示即可。可能有些人在想:为什么星期数用Day而不用Week之类的呢?我还以为是天数呢!因为英文的星期1~7都是以Day结尾,例如,Monday,Sunday, Friday等等。英文询问今天星期几即“What day is today?”
(7)【地址0x8C】年份寄存器(Year):DS1302的年份范围是00~99,所以分别用高4位与低4位分别表示十位与个位。
(8)【地址0x8E】写保护寄存器(Write Protect, WP): 该寄存器只有最高位有效,为1表示开启写保护,为0表示解除写保护。在往RTC(或RAM)中写入数据前,必须将该位清0。
(9)【地址0x90】充电寄存器:与时间计数无关,咱们最后讨论。
我们使用VisualCom软件平台来仿真一下,相应的仿真效果如下图所示:
调出的DS1302器件有一个能够方便我们观察RTC内部状态的屏幕,其实就是一块能够显示4行20个字符的液晶显示模组(LCM2004),从屏幕上看到信息就是从DS1302中读取出来并写入到LCM2004中的。当然,一些特殊的寄存器状态还是得观察“内存”窗口,相应的预置数据如下图所示:
VisualCom软件平台中的预置数据格式均按照正常位序定义,共16位有效,高8位设置访问地址,低8位则是写入的数据,如下图所示:
首先我们解除了写保护。因为无论你写什么、往哪里写,写保护都需要解除(将WP位清零),所以需要写入的数据为“0b10001110_0000000(0x8E00)”,如下图所示
写保护解锁后,咱们就可以为所欲为了,在依次写入年份、星期、月份、日期、小时、分钟后,我们才设置了秒钟,也就同时启动了芯片的计数,简单吧!
最后我们谈谈充电寄存器,它是用来做什么的呢?有电脑使用经验的读者都知道,当我们将电脑彻底关机(电)后再开机,时间仍然还在继续跑的,对不对?因为电脑的处理器也有RTC功能,当电脑处于开机时,RTC由外部电源供电,而在断电状态下,RTC则由主板上的电池(最常见的是钮扣电池CR2032)供电。换句话说,RTC单元的供电总是不会断开的,所以计数功能也从来没有停止过,类似的供电电路如下图所示:
图中RTC_VDD是RTC单元的供电电源,电路系统上电后VCC是有电的,同时也给RTC单元供电,断电后则由电池供电,两个二极管可以防止VCC与电池之间出现漏电状态。
DS1302有两个电源供电引脚,VCC2为主电源供电(相当于上图的VCC),VCC1为辅助电源供电。当VCC2没有电源供电时,挂在VCC1引脚的电池将给RTC供电,如图所示:
如果电池是可充电型的,当VCC2主电源有供电时,我们就可以使用充电寄存器来控制充电参数,我们来看看VCC2与VCC1之间的内部电路,如下图所示:
可以看到,VCC2与VCC1之间有三级开关,TCS3~TCS0控制主电源是否往辅助电源供电,DS1~DS0控制串联的二极管个数,ROUT1~ROUT0控制串联的电阻值,数据手册有下表所示的功能表:
如果你使用可充电电池,并且决定使用充电功能,应该通过选择合适的二极管数量与阻值来限制最大充电电流。假设供电电源为5V,并且使用1个二极管与2K欧姆电阻串联方式,则最大充电电流为IMAX=(5V-0.7V)/2K≈2.2mA。
轻松吃透实时时钟芯片DS1302软硬件设计,看完秒懂的更多相关文章
- STC8H开发(十四): I2C驱动RX8025T高精度实时时钟芯片
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- 基于STM32F1的时钟芯片DS1302驱动
目录 DS1302.h源代码 DS1302.c源代码 DS1302.h源代码 /** ********************************************************* ...
- STC8H开发(十三): I2C驱动DS3231高精度实时时钟芯片
目录 STC8H开发(一): 在Keil5中配置和使用FwLib_STC8封装库(图文详解) STC8H开发(二): 在Linux VSCode中配置和使用FwLib_STC8封装库(图文详解) ST ...
- 基于at91rm9200的i2c分析(DS1307实时时钟芯片)
board-ek.c 构造i2c_board_info结构体 static struct i2c_board_info __initdata ek_i2c_devices[] = { { ...
- 4.9版本的linux内核中实时时钟芯片pcf85263的驱动源码在哪里
答:drivers/rtc/rtc-pcf85263.c,内核配置选项为 CONFIG_RTC_DRV_PCF85263 Location: -> Device Drivers -> Re ...
- 4.9版本的linux内核中实时时钟芯片pt7c4338的驱动源码在哪里
答:drivers/rtc/rtc-ds1307.c,内核配置项为CONFIG_RTC_DRV_DS1307 Location: -> Device Drivers -> Real Tim ...
- 单片机课程设计——《基于AT89S52单片机和DS1302时钟芯片的电子时钟(可蓝牙校准)》
引言 本设计以AT89S52单片机为控制核心,时钟芯片DS1302提供时钟源,配合LCD1602液晶显示模块,组成基本硬件系统,同时利用HC-05嵌入式蓝牙串口通讯模块,可在手机端进行日期.时间的校准 ...
- 玩转 RTC时钟库 DS1302
1.前言 最近博主在弄8266编程的时候,偶然发现两个全新时钟模块压仓货: DS1302 DS3231 为了避免资源浪费以及重复编写代码,博主还是抱着尝试的心态去寻找能够同时兼容 DS ...
- 关于时钟模块DS1302的使用心得
最近在做万年历,用到实时时钟DS1302模块,花了两天时间看资料和写驱动,想记录一下我的学习经过,顺便做一下总结. 首先就是在图书馆查各种资料,于是查到的大多是这些,主要时硬件方面的资料: 其实能查到 ...
随机推荐
- copy函数与ostream_iterator、reverse_iterator
#include <iostream> #include <iterator> #include <vector> int main() { using names ...
- path自定义转换器
register-converter用于注册转换器
- Tomcat&Http协议-授课
1 企业开发简介 1.1 JavaEE规范 JavaEE规范是J2EE规范的新名称,早期被称为J2EE规范,其全称是Java 2 Platform Enterprise Edition,它是由SUN公 ...
- [c++] 开发问题
语言中的很多细节都是为了应对实际开发中会遇到的问题 当编写程序时,我们使用的定义多数不是自己写的,如sqrt(),是很多年前别人写的,我们只是使用它们 在C++中,对于"别处"定义 ...
- 网络协议 SNMP- Windows10无简单SNMP协议服务器配置
原因:Windwos10 1809后更新版本,无启动SNMP协议服务器可选配置项. 解决: 1.打开设置中的[开发人员模式],设置->更新与安全->开发者选项->开发人员模式 2.添 ...
- U盘PE重装系统导致D、E、F盘消失
U盘PE重装系统导致D.E.F盘消失 听语音 原创 | 浏览:1251 | 更新:2014-08-18 18:46 | 标签:u盘 重装 解决使用U盘PE重装系统导致的错误问题 工具/原料 制作好 ...
- Python socket 编程实验
实验内容 1.编写一个基于UDP协议的客户机与服务器程序,实现相互通讯. 2.编写一个基于TCP协议的客户机与服务器程序,实现相互通讯. 3.捕获以上两种通讯的数据包,使用Wireshark进行分析, ...
- 047.Python前端html
一 HTTP协议 1.1 HTTP请求 URL: 协议/IP:端口/路径?GET参数 基于请求响应 请求协议格式 GET URL路径?a=1&b=2 HTTP # 请求首行 user-age ...
- shell基础之bus实战(if 练习)
题目: 一条公交路线共30站,乘客上车需支付1元,之后每超过5站支付0.5元:最好可以实现"余额不足的提醒"和"逃票,漏刷卡的显示". 注意:需下载bc计算器 ...
- 2.9高级变量类型操作(列表 * 元组 * 字典 * 字符串)_内置函数_切片_运算符_for循环
高级变量类型 目标 列表 元组 字典 字符串 公共方法 变量高级 知识点回顾 Python 中数据类型可以分为 数字型 和 非数字型 数字型 整型 (int) 浮点型(float) 布尔型(bool) ...