一、DS1302介绍
1.功能介绍
DS1302包括时钟/日历寄存器和31字节(8位)的数据暂存寄存器,数据通信仅通过一条串行输入输出口,实时时钟/日历提供包括秒、分、时、日期、月份和年份信息。闰年可自行调整,可选择12小时制和24小时制,可设置AM、PM。
DS1302工作电压范围是2V~5.5V。DS1302只通过三根线进行数据的控制和传递:CE、I/O(Data line)、SCLK(Serial clock),如下图所示。读写时钟寄存器或内部RAM(31*8位的额外数据暂存寄存器)可以采用单字节模式和突发模式。
2.工作过程
工作原理图如下所示,包括移位寄存器、控制逻辑、晶振、时钟和RAM。在进行任何数据传输时,CE必须置为高电平(CE被置为高电平,内部时钟还是在晶振作用下走时,此时允许外部读写数据),在每个SCLK上升沿时数据被输入,下降沿时数据被输出,一次只能读写一位,是读还是写取决于串行输入控制指令,通过8个脉冲便可以读取一个字节从而实现串行输入与输出。
刚开始时,通过8个时钟周期载入控制字节到移位寄存器,如果控制指令是单字节模式,连续的8个时钟脉冲可以进行8位数据的写和8位数据的读 *** 作,SCLK时钟的上升沿时,数据被写入DS1302,SCLK时钟为下降沿时读出DS1302的数据,8个脉冲便可以读写一个字节。在突发模式,通过连续脉冲一次性读写完7个字节的时钟/日历寄存器,也可以一次性读写8~328位RAM数据(可按实际情况读写一定数量的,不必全部读写)。
3.控制指令
每个字节的传输是有控制字节指定的,控制字节最高位bit7必须是1,如果是‘0’,写入将被禁止。如果这位是0,可以禁止写入。bit6为‘0’表示对时钟/日历寄存器控制读写 *** 作,为‘1’表示对RAM区数据的控制读写 *** 作,bit1~bit5指定相关寄存器待进行输入输出 *** 作,最低位bit0指定是输入还是输出,为‘0’则为写(输入),为‘1’则为读(输出)。
4.数据传输
所有数据传输在CE置1时进行,CE输入信号有两个功能:一是CE接通控制逻辑,允许地址/命令序列送入移位寄存器;二是CE提供终止单字节或多字节数据的传送手段。当CE为高电平时,所有的数据传送被初始化,允许对DS1302进行 *** 作。在传送过程中如果CE置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电运行时,在Vcc≥2.5V之前,CE必须保持低电平。只有在SCLK为低电平时,才能将CE置为高电平。I/O为串行数据输入输出端(双向),SCLK始终是输入端。如图是读数据和写数据时序图。
(1)数据输入
经过8个时钟周期的控制字节的输入,一个字节的输入将在8个时钟周期的上升沿完成,数据传输从字节最低位开始。
(2)数据输出
经过8个时钟周期的控制读指令的输入,一个字节的数据将在下个8个时钟周期的下降沿被输出,注意第一位输出是在最后一位控制指令所在脉冲的下降沿被输出,要求CE保持高电平。
同理8个时钟周期的控制读指令如果指定的是突发模式,将会在脉冲的上升沿读入数据,下降沿读出数据,突发模式一次可以进行多字节数据的一次性读写,只要控制好脉冲就行了。
(3)日历时钟寄存器(数据格式:BCD码)
1° 秒寄存器(80H和81H)的bit7(CH)是时钟暂停标志位
CH为0时,时钟振荡停止;
CH为1时,时钟开始运行。
2° 控制寄存器(8EH和8FH)的bit7(WP)为写保护位。
WP为0时,可对任何的时钟或RAM寄存器进行写 *** 作;
WP为1时,禁止对任一寄存器进行写 *** 作。
二、程序编写
#include "reg52.h" #include "ds1302.h" #include "SMG_show.h" uchar write_ds1302_adrr[7] = {0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; uchar read_ds1302_adrr[7] = {0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //22年1月27日,周四,23点59分24秒(BCD编码) uchar timer[7] = {0x24,0x59,0x23,0x27,0x01,0x04,0x22}; void ds1302_config() //初始化(使能)日历时钟 { uchar i; Write_Ds1302_Byte(0x8e,0x00); //关闭保护,开始写数据(写有保护,读没有保护) for(i = 0;i < 7;i++) { Write_Ds1302_Byte( write_ds1302_adrr[i],timer[i] ); } Write_Ds1302_Byte(0x8e,0x80); //恢复保护 } void read_ds1302_timer() //获取当前时间 { uchar i; for(i =0;i < 7;i++) { timer[i] = Read_Ds1302_Byte(read_ds1302_adrr[i]); //读出来的数据放到数组中 } } void ds1302_show() { SMG_show_bit(0,table_nodot[timer[2]/16]); //小时的十位 delay_ms(2); SMG_show_bit(1,table_nodot[timer[2]%16]); //小时的个位 delay_ms(2); SMG_show_bit(2,0xbf); //显示“-” 1011 1111 delay_ms(2); SMG_show_bit(3,table_nodot[timer[1]/16]); //分的十位 delay_ms(2); SMG_show_bit(4,table_nodot[timer[1]%16]); //分的个位 delay_ms(2); SMG_show_bit(5,0xbf); //显示“-” 1011 1111 delay_ms(2); SMG_show_bit(6,table_nodot[timer[0]/16]); //秒的十位 delay_ms(2); SMG_show_bit(7,table_nodot[timer[0]%16]); //秒的个位 delay_ms(2); } void main() { system_init(); ds1302_config(); while(1) { read_ds1302_timer(); ds1302_show(); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)