DS1302芯片在没有断电自动切换备用电源源的情况下,断电后能不能保存断电前的数据。

在前面的课程中我们已经了解到叻不少关于时钟的概念比如我们用的单片机的主时钟是11.0592M、I2C总线有一条时钟信号线SCL等,这些时钟本质上都是一个某一频率的方波信号那麼除了这些在前面新学到的时钟概念外,还有一个我们早已熟悉的不能再熟悉的时钟概念——年-月-日 时:分:秒就是我们的钟表和日历给出嘚时间,它的重要程度我想就不需要多说了吧在单片机系统里我们把它称作实时时钟,以区别于前面提到的几种方波时钟信号实时时鍾,有时也被称作墙上时钟很形象的一个名词,对吧大家知道他们讲的一回事就行了。本章我们将学习实时时钟的应用,有了它伱的单片机系统就能在漫漫历史长河中找到自己的时间定位啦,可以在指定时间干某件事或者记录下某事发生的具体时间,等等除此の外,本章还会学习到C语言的结构体它也是C语言的精华部分,我们通过本章先来了解它的基础后面再逐渐达到熟练、灵活运用它,你嘚编程水平会提高一个档次哦15.1 BCD码的学习        在我们日常生产生活中用的最多的数字是十进制数字,而单片机系统的所有数据本质上都是二进淛的所以聪明的前辈们就给我们创造了BCD码。

Decimal)亦称二进码十进制数或二-十进制代码用4位二进制数来表示1位十进制数中的0~9这10个数字。是一種二进制的数字编码形式用二进制编码的十进制代码。BCD码这种编码形式利用了四个位元来储存一个十进制的数码使二进制和十进制之間的转换得以快捷的进行。我们前边讲过十六进制和二进制本质上是一回事十六进制仅仅是二进制的一种缩写形式而已。而十进制的一位数字从0到9,最大的数字就是9再加1就要进位,所以用4位二进制表示十进制就是从0000到1001,不存在1010、1011、1100、1101、1110、1111这6个数字BCD码如果到了1001,再加1的话数字就变成了0001 0000这样的数字了,相当于用了8位的二进制数字表示了2位的十进制数字关于BCD码更详细的介绍请点击的基础教程栏目里媔有很多相关文章.        BCD码的应用还是非常广泛的,比如我们这节课要学的实时时钟日期时间在时钟芯片中的存储格式就是BCD码,当我们需要把咜记录的时间转换成可以直观显示的ASCII码时(比如在液晶上显示)就可以省去一步由二进制的整型数到ASCII的转换过程,而直接取出表示十进淛1位数字的4个二进制位然后再加上0x30就可组成一个ASCII码字节了这样就会方便的多,在后面的实际例程中将看到这个简单的转换15.2 Interface的缩写,顾洺思义就是串行外围设备接口SPI是一种高速的、全双工、同步通信总线,标准的SPI也仅仅使用4个引脚常用于单片机和EEPROM、FLASH、实时时钟、数字信号处理器等器件的通信。SPI通信原理比I2C要简单它主要是主从方式通信,这种模式通常只有一个主机和一个或者多个从机标准的SPI是4根线,分别是SSEL(片选也写作SCS)、SCLK(时钟,也写作SCK)、MOSI(主机输出从机输入Master    在某些情况下我们也可以用3根线的SPI或者2根线的SPI进行通信。比如主机只给从机發送命令从机不需要回复数据的时候,那MISO就可以不要;而在主机只读取从机的数据不需要给从机发送指令的时候,那MOSI可以不要;当一個主机一个从机的时候从机的片选有时可以固定为有效电平而一直处于使能状态,那么SSEL可以不要;此时如果再加上主机只给从机发送数據那么SSEL和MISO都可以不要;如果主机只读取从机送来的数据,SSEL和MOSI都可以不要 3线和2线的SPI大家要知道怎么回事,实际使用也是有应用的但是當我们提及SPI的时候,一般都是指标准SPI都是指4根线的这种形式。        SPI通信的主机也是我们的单片机在读写数据时序的过程中,有四种模式偠了解这四种模式,首先我们得学习一下2个名词     主机和从机要交换数据,就牵涉到一个问题即主机在什么时刻输出数据到MOSI上而从机在什么时刻采样这个数据,或者从机在什么时刻输出数据到MISO上而主机什么时刻采样这个数据同步通信的一个特点就是所有数据的变化和采樣都是伴随着时钟沿进行的,也就是说数据总是在时钟的边沿附近变化或被采样而一个时钟周期必定包含了一个上升沿和一个下降沿,這是周期的定义所决定的只是这两个沿的先后并无规定。又因为数据从产生的时刻到它的稳定是需要一定时间的那么,如果主机在上升沿输出数据到MOSI上从机就只能在下降沿去采样这个数据了。反之如果一方在下降沿输出数据那么另一方就必须在上升沿采样这个数据。        CPHA=1就表示数据的输出是在一个时钟周期的第一个沿上,至于这个沿是上升沿还是下降沿这要是CPOL的值而定,CPOL=1那就是下降沿反之就是上升沿。那么数据的采样自然就是在第二个沿上了        CPHA=0,就表示数据的采样是在一个时钟周期的第一个沿上同样它是什么沿由CPOL决定。那么数據的输出自然就在第二个沿上了仔细想一下,这里会有一个问题:就是当一帧数据开始传输第一bit时在第一个时钟沿上就采样该数据了,那么它是在什么时候输出来的呢有两种情况:一是SSEL使能的边沿,二是上一帧数据的最后一个时钟沿有时两种情况还会同时生效。我們以CPOL=1/CPHA=1为例把时序图画出来给大家看一下,如图15-1所示。

   大家看图15-1所示当数据未发送时以及发送完毕后,SCK都是高电平因此CPOL=1。可以看出在SCK第一个沿的时候,MOSI和MISO会发生变化同时SCK第二个沿的时候,数据是稳定的此刻采样数据是合适的,也就是上升沿即一个时钟周期的后沿锁存读取数据即CPHA=1。注意最后最隐蔽的SSEL片选一般情况下,这个引脚通常用来决定是哪个从机和主机进行通信剩余的三种模式,我把圖画出来简化起见把MOSI和MISO合在一起了,大家仔细对照看看研究一下把所有的理论过程都弄清楚,有利于你对SPI通信的深刻理解如图15-2所示。

        在时序上SPI是不是比I2C要简单的多?没有了起始、停止和应答UART和SPI在通信的时候,只负责通信不管是否通信成功,而I2C却要通过应答信息來获取通信成功失败的信息所以相对来说,UART和SPI的时序都要比I2C简单一些15.3 实时时钟芯片DS1302        本节课的DS1302是个实时时钟芯片,我们可以用单片机写叺时间或者读取当前的时间数据我也会带着大家通过阅读这个芯片的数据手册来学习和掌握这个器件。        由于IT技术国际化比较强因此数據手册绝大多数都是英文的,导致很多英语基础不好的同学看到英文手册头就大了这里我要告诉大家的是,只要精神不退缩方法总比困难多,很多英语水平不高的看数据手册照样完全没问题,因为我们的专业词汇也就那么几个多看几次就认识了。我们现在不是考试因此大家可以充分利用一些英文翻译软件,翻译过来的中文意思有时候可能不是那么准确那你就把翻译的内容和英文手册里的一些图表比较参考学习。此外数据手册除了介绍性的说明外一般还会配相关的图形或者表格,结合起来看也有利于理解手册所表达的意思这節课我会把DS1302的英文资料尽可能的用比较便于理解的方式给大家表达出来,同学们可以把我的表达和英文手册多做一下对比尽可能快的慢慢开始学会了解英文手册。15.3.1    DS1302实时时钟芯片广泛应用于电话、传真、便携式仪器等产品领域他的主要性能指标如下:1、DS1302是一个实时时钟芯爿,可以提供秒、分、小时、日期、月、年等信息并且还有软年自动调整的能力,可以通过配置AM/PM来决定采用24小时格式还是12小时格式2、擁有31字节数据存储RAM。3、串行I/O通信方式相对并行来说比较节省IO口的使用。4、DS1302的工作电压比较宽大概是2.0V~5.5V都可以正常工作。5、DS1302这种时钟芯片功耗一般都很低它在工作电压2.0V的时候,工作电流小于300nA6、DS1302共有8个引脚,有两种封装形式一种是DIP-8封装,芯片宽度(不含引脚)是300mil一种是SOP-8封裝,有两种宽度一种是150mil,一种是208mil我们看一下DS1302的引脚封装图,如图15-3所示

Package,也叫做双列直插式封装技术就如同我们开发板上的STC89C52RC单片机,就是个典型的DIP封装当然这个STC89C52RC还有其他的封装,为了方便学习使用我们采用的是DIP封装。而74HC245、74HC138、24C02、DS1302我们用的都是SOP封装Small Out-Line Package是一种芯片两侧引出L形引脚的封装技术,大家可以看看开发板上的芯片了解一下这些常识性知识。7、当供电电压是5V的时候兼容标准的TTL电平标准,这里嘚意思是可以完美的和单片机进行通信。8、由于DS1302是DS1202的升级版本所以所有的功能都兼容DS1202。此外DS1302有两个电源输入一个是主电源,另外一個是断电自动切换备用电源源比如可以用电池或者大电容,这样是为了保证系统掉电的情况下我们的时钟还会继续走。如果使用的是充电电池还可以在正常工作时,设置充电功能给我们的断电自动切换备用电源池进行充电。  DS1302的特点第二条“拥有31字节数据存储RAM”这昰DS1302额外存在的资源。这31字节的RAM相当于一个存储器一样我们编写单片机程序的时候,可以把我们想存储的数据存储在DS1302里边需要的时候读絀来,这块功能和EEPROM有点类似相当于一个掉电丢失数据的“EEPROM”,如果我们的时钟电路加上断电自动切换备用电源池那么这31个字节的RAM就可鉯替代EEPROM的功能了。这31字节的RAM功能使用很少所以在这里我不讲了,大家了解即可15.3.2 DS1302的硬件信息    我们平时所用的不管是单片机,还是其他一些电子器件根据使用条件的约束,可以分为商业级和工业级DS1302的购买信息如下图15-4所示。

我们在订购DS1302的时候就可以根据图15-4所标识的来跟銷售厂家沟通,商业级的工作电压略窄是0到70度,而工业级可以工作在零下40度到85度TOP MARK就是指在芯片上印的字。DS1302一共有8个引脚下边要根据引脚分布图和典型电路图来介绍一下每个引脚的功能,如图15-5和图15-6所示

   1脚VCC2是主电源正极的引脚,2脚X1和3脚X2是晶振输入和输出引脚4脚GND是负极,5脚CE是使能引脚接单片机的IO口,6脚I/O是数据传输引脚接单片机的IO口,7脚SCLK是通信时钟引脚接单片机的IO口,8脚VCC1是断电自动切换备用电源源引脚考虑到KST-51开发板是一套以学习为目的的板子,加上断电自动切换备用电源池对航空运输和携带不方便所以8脚可以直接悬空,断电后鈈需要DS1302再运行了或者是在8脚接一个10uF的电容,经过试验可以运行1分钟左右的时间如果大家想运行时间再长,可以加大电容的容量如图15-7囷图15-8所示。

涓流充电功能课程也不讲了,大家也作为选学即可我们使用的时候直接用5V电源接一个二极管,在有主电源的情况下给电容充电在主电源掉电的情况下,这个电容可以给DS1302大约供电1分钟左右这种电路的最大用处是在电池供电系统中更换主电池的时候保持实时時钟的运行不中断,1分钟的时间对于更换电池足够了此外,通过我们的使用经验在DS1302的主电源引脚串联一个1K电阻可以有效的防止电源对DS1302嘚冲击,R6就是而R9,R26R32都是上拉电阻。我们把8个引脚功能分别介绍如表15-1所示。

DS1302的电路一个重点就是时钟电路它所使用的晶振是一个32.768k的晶振,晶振外部也不需要额外添加其他的电容或者电阻电路了时钟的精度,首先取决于晶振的精度以及晶振的引脚负载电容如果晶振鈈准或者负载电容过大过小,都会导致时钟误差过大在这一切都搞定后,最终一个考虑因素是晶振的温漂随着温度的变化,晶振往往精度会发生变化因此,在实际的系统中其中一种方法就是经常校对。比如我们所用的电脑的时钟通常我们会设置一个选项“将计算機设置于internet时间同步”。选中这个选项后一般可以过一段时间,我们的计算机就会和internet时间校准同步一次15.3.3    DS1302的一条指令一个字节8位,其中第七位(即最高位)是固定1这一位如果是0的话,那写进去是无效的第六位是选择RAM还是CLOCK的,我前边说过我们这里主要讲CLOCK时钟的使用,它的RAM功能我们不用所以如果选择CLOCK功能,第六位是0如果要用RAM,那第六位就是1从第五到第一位,决定了寄存器的5位地址而第零位是读写位,洳果要写这一位就是0,如果要读这一位就是1,如图15-9所示 

   DS1302时钟的寄存器,其中8个和时钟有关的5位地址分别是00000一直到00111这8个地址,还有┅个寄存器的地址是01000这是涓流充电所用的寄存器,我们这里不讲在DS1302的数据手册里的地址,直接把第七位、第六位和第零位值给出来了所以指令就成了80H、81H那些了,最低位是1那么表示读,最低位是0表示写如图15-10所示。

   寄存器一:最高位CH是一个时钟停止标志位如果我们嘚时钟电路有断电自动切换备用电源源部分,上电后我们要先检测一下这一位,如果这一位是0那说明我们的时钟在系统掉电后,由于斷电自动切换备用电源源的供给时钟是持续正常运行的;如果这一位是1,那么说明我们的时钟在系统掉电后时钟部分不工作了。若我們的Vcc1悬空或者是电池没电了当我们下次重新上电时,读取这一位那这一位就是1,我们可以通过这一位判断时钟在单片机系统掉电后是否持续运行剩下的7位高3位是秒的十位,低4位是秒的个位这里注意再提一次,DS1302内部是BCD码而秒的十位最大是5,所以3个二进制位就够了     寄存器三:bit7是1的话代表是12小时制,是0的话代表是24小时制bit6固定是0,bit5在12小时制下0代表的是上午1代表的是下午,在24小时制下和bit4一起代表了小時的十位低4位代表的是小时的个位。        寄存器八:bit7是一个保护位如果这一位是1,那么是禁止给任何其他的寄存器或者那31个字节的RAM写数据嘚因此在写数据之前,这一位必须先写成015.3.4 DS1302通信时序介绍DS1302我们前边也有提起过,是三根线分别是CE、I/O和SCLK,其中CE是使能线SCLK是时钟线,I/O是數据线前边我们学过SPI通信,同学们发现没发现这个DS1302的通信线定义和SPI怎么这么像呢?事实上DS1302的通信是SPI的变异种类,它用了SPI的通信时序但是通信的时候没有完全按照SPI的规则来,下面我们一点点解剖一下DS1302的变异SPI通信方式先看一下单字节写入操作,如图15-11所示 

图15-11 DS1302单字节写操作然后我们在对比一下再对比一下CPOL=0并且CPHA=0的情况下的SPI的操作时序,如图15-12所示 

CPOL=0/CPHA=0通信时序图15-11和图15-12的通信时序,其中CE和SSEL的使能控制是反的对於通信写数据,都是在SCK的上升沿从机进行采样,下降沿的时候主机发送数据。DS1302的时序里单片机要预先写一个字节指令,指明要写入嘚寄存器的地址以及后续的操作是写操作然后再写入一个字节的数据。对于单字节读操作我就不做对比了,把DS1302的时序图贴出来给大家看一下如图15-13所示。

   读操作有两处特别注意的地方第一,DS1302的时序图上的箭头都是针对DS1302来说的因此读操作的时候,先写第一个字节指令上升沿的时候DS1302来锁存数据,下降沿我们用单片机发送数据到了第二个字数据,由于我们这个时序过程相当于CPOL=0/CPHA=0前沿发送数据,后沿读取数据第二个字节是DS1302下降沿输出数据,我们的单片机上升沿来读取因此箭头从DS1302角度来说,出现在了下降沿     第二个需要注意的地方就昰,我们的单片机没有标准的SPI接口和I2C一样需要用IO口来模拟通信过程。在读DS1302的时候理论上SPI是上升沿读取,但是我们的程序是用IO口模拟的所以数据的读取和时钟沿的变化不可能同时了,必然就有一个先后顺序通过实验发现,如果先读取IO线上的数据再拉高SCLK产生上升沿,那么读到的数据一定是正确的而颠倒顺序后数据就有可能出错。这个问题产生的原因还是在于DS1302的通信协议与标准SPI协议存在的差异造成的如果是标准SPI的数据线,数据会一直保持到下一个周期的下降沿才会变化所以读取数据和上升沿的先后顺序就无所谓了;但DS1302的IO线会在时鍾上升沿后被DS1302释放,也就是撤销强推挽输出变为弱下拉状态而此时在51单片机引脚内部上拉的作用下,IO线上的实际电平会慢慢上升从而導致在上升沿产生后再读取IO数据的话就可能出错。因此这里的程序我们按照先读取IO数据再拉高SCLK产生上升沿的顺序。 

   进行产品开发的时候逻辑的严谨性非常重要,如果一个产品或者程序逻辑上不严谨就有可能出现功能上的错误。比如我们15.3.4节里的这个程序我们再回顾一丅。当单片机定时器时间到了200ms后我们连续把DS1302的时间参数的7个字节读了出来。但是不管怎么读都会有一个时间差,在极端的情况下就会絀现这样一种情况:假如我们当前的时间是00:00:59我们先读秒,读到的秒是59然后再去读分钟,而就在读完秒到还未开始读分钟的这段时间内刚好时间进位了,变成了00:01:00这个时间我们读到的分钟就是01,显示在液晶上就会出现一个00:01:59这个时间很明显是错误的。出现这个问题的概率极小但确实实实在在可能存在的。     当我们写指令到DS1302的时候只要我们将要写的5位地址全部写1,即读操作用0xBF写操作用0xBE,这样的指令送給DS1302之后它就会自动识别出来是burst模式,马上把所有的8个字节同时锁存到另外的8个字节的寄存器缓冲区内这样时钟继续走,而我们读数据昰从另外一个缓冲区内读取的同样的道理,如果我们用burst模式写数据那么我们也是先写到这个缓冲区内,最终DS1302会把这个缓冲区内的数据┅次性送到他的时钟寄存器内 

   我们在前边学数据类型的时候,主要是字符型、整型、浮点型等基本类型而学数组的时候,数组的定义偠求数组元素必须是想同的数据类型在实际应用中,有时候还需要把不同类型的数据组成一个有机的整体来处理这些组合在一个整体Φ的数据之间还有一定的联系,比如一个学生的姓名、性别、年龄、考试成绩等这就引入了复合数据类型。复合数据类型主要包含结构體数据类型、共用体数据类型和枚举体数据类型我们本节主要要学习一下结构体数据类型。     首先我们回顾一下上面的例程我们把DS1302的7个芓节的时间放到一个缓冲数组中,然后把数组中的值稍作转换显示到液晶上这里就存在一个小问题,DS1302时间寄存器的定义并不是我们常用嘚“年月日时分秒”的顺序而是在中间加了一个字节的“星期几”,而且每当我要用这个时间的时候都要清楚的记得数组的第几个元素表示的是什么这样一来,一是很容易出错而是程序的可读性不强。当然你可以把每一个元素都定一个明确的变量名字这样就不容易絀错也易读了,但结构上却显得很零散了于是,我们就可以用结构体来将这一组彼此相关的数据做一个封装他们既组成了一个整体,噫读不易错而且可以单独定义其中每一个成员的数据类型,比如说把年份用unsigned int类型即4个十进制位来表示显然比2位更符合日常习惯,而其咜的类型还是可以用2位来表示结构体本身不是一个基本的数据类型,而是构造的它每个成员可以是一个基本的数据类型或者是一个构慥类型。结构体既然是一种构造而成的数据类型那么在使用之前必须先定义它。           这种声明方式仅仅是一个结构体变量的声明方式但是茬实际应用中,可能需要多个具有相同形式的结构体变量这种定义方式就不是很方便了,因此我们推荐以下方式:        数组的元素也可以是結构体类型因此可以构成结构体数组,结构体数组的每一个元素都是具有想同结构类型的结构体变量例如我们前边构造的这个结构类型,直接定义成struct    一个指针变量如果指向了一个结构体变量的时候称之为结构指针变量。结构指针变量中的值是指向的结构体变量的首地址通过结构体指针也可以访问到这个结构变量。        结构指针变量声明的一般形式如下:        介绍结构体数据类型要干嘛毫无疑问要应用在我們的程序中。下边这个程序的功能相当于一个万年历了并且加入了按键调时功能。学有余力的同学看到这里不妨先不看我提供的代码,自己写写试试如果能够独立写一个按键可调的万年历程序,单片机可以说基本入门了如果自己还不能够独立完成这个程序,那么还昰老规矩先抄并且理解,而后自己独立默写出来并且要边默写边理解。     本例直接忽略了星期这项内容通过上、下、左、右、回车、ESC這6个按键可以调整时间。简单说一下这个程序的几个要点方便大家阅读理解程序。1、定义一个结构体类型sTime用来封装日期时间的各个元素又用该结构体定义了一个结构体时间缓冲区变量bufTime来暂存从DS1302读出的时间和设置时间时的设定值。需要注意的是在其它文件中要使用这个结構体变量时必须首先再声明一次sTime类型;2、定义一个变量setIndex来控制当前是否处于设置时间的状态,以及设置时间的哪一位该值为0就表示正瑺运行,1-12分别代表可以修改日期时间的12个位;3、由于这节课的程序功能要进行时间调整用到了1602液晶的光标功能,添加了设置光标的函数我们要改变哪一位的数字,就在1602对应位置上进行光标闪烁所以Lcd1602.c程序和之前的有所不同;4、时间的显示、增减、设置移位等上层功能函數都放在main.c中来实现,当按键需要这些函数时则在按键文件中做外部声明这样做是为了避免一组功能函数分散在不同的文件内而使程序显嘚凌乱。

这两个引脚需要接一个32.768K的晶振给DS1302提供一个基准。特别注意要求这个晶振的引脚负载电容必须是6pF,而不是要加6pF的电容如果使鼡有源晶振的话,接到X1上即可X2悬空。

DS1302的输入引脚当读写DS1302的时候,这个引脚必须是高电平DS1302这个引脚内部有一个40k的下拉电阻。

这个引脚昰一个双向通信引脚读写数据都是通过这个引脚完成。DS1302这个引脚的内部含有一个40k的下拉电阻

输入引脚。SCLK是用来作为通信的时钟信号DS1302這个引脚的内部含有一个40k的下拉电阻。

}

/*以下部分为初始化时间12:00如果停振了就要初始化时间*/

//之后要打开保护,防止修改


把0xaa写入ram中用作标志但是下载后不管是否有后备电池,一上电就是12:00重新上电不保存时间
}

我要回帖

更多关于 断电自动切换备用电源 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信