DS1302时钟芯片使用介绍

DS1302实时时钟芯片简介

      DS1302是由美国DALLAS公司推出的具有涓细电流充电能力的低功耗实时时钟芯片。它可以对年、月、日、周、时、分、秒进行计时,并且具有闰年补偿等多种功能。采用串行数据传输,采用32.768kHz晶振。

DS1302实时时钟芯片特点

      1、DS1302 与单片机之间能简单地采用同步串行的方式进行通信,仅需用到三条线:1、RES 复位,2、I/O 数据线,3、SCLK。

      2、DS1302工作时的功耗很低,保持数据和时钟信息时功率小于1mW。

      3、实时时钟具有能计算2100 年之前的秒分时日日期星期月年的能力还有闰年调整的能力。

      4、宽范围工作电压2.0~5.5V。

      5、可选工业级温度范围-40℃+85℃。

      6、双电源管用于主电源和备份电源供应。

      7、备份电源管脚可由电池或大容量电容输入。

DS1302实时时钟芯片管脚描述

 

寄存器地址/定义

      上表第一行的CH表示时钟暂停控制位,置1时表示时钟暂停(时钟振荡器暂停),DS1302进入漏电流小于100nA的低功耗备用模式。置0时表示时钟开始。

      WP表示write protect(写保护),置1表示写操作无效。在任何对时钟或RAM的写操作以前,WP必须为0;当为1时,写保护位禁止任何寄存器的写操作。因此,在试图写器件之前应该清除WP位。

      TCS用于控制涓流充电,一般不进行设置。

      寄存器的其它内容在下文中进行介绍。

命令字

      下图显示了命令字节,命令字节启动每一次数据传输。

      第7位必须是1。如果为0,将禁用对DS1302的写入。

      第6位如果是1,则读取或写入RAM数据;如果是0,则读取或写入CK时钟。

      第1到5位是地址,即要操作的地址,秒的地址是从0开始

      第0位为1时是read,对地址进行读取;为0时是write,对地址进行写入

      例如:

      10000001(0x81)表示对时钟操作、秒地址操作、读。

      10000000(0x80)表示对时钟操作、秒地址操作、写。

      10001001(0x89)表示对时钟操作、月地址操作、读。

10001000(0x88)表示对时钟操作、月地址操作、写。
这与上文寄存器中的读地址和写地址是对应的。

 

时序图与数据读写

      DS1302实时时钟芯片寄存器的读写需要用到三个引脚:CE(使能端)、SCLK(时钟)和I/O(数据)。在时钟上升沿,I/O口的数据将会被写入,在时钟下降沿,时钟芯片的数据将会被读出。

      单字节写步骤(Write)

      单字节读步骤(Read)

 

BCD

      注意:DS1302寄存器中的数据不是以二进制进行存储的,而是以BCD码进行存储的。所以将数据从DS1302中读取出来后还需要转为十进制来显示。

一个DS1302实时时钟芯片的例程:

/***************ds1302时钟数码管显示*****************     

*单片机型号:STC89C52RC

*开发环境:KEIL

*名称:ds1302时钟数码管显示                  

**********************************************************/

#include <reg52.h>

#define uchar unsigned char

#define AM(X) X

#define PM(X) (X+12)                       // 转成24小时制

#define DS1302_SECOND 0x80

#define DS1302_MINUTE 0x82

#define DS1302_HOUR 0x84

#define DS1302_WEEK       0x8A

#define DS1302_DAY 0x86

#define DS1302_MONTH 0x88

#define DS1302_YEAR 0x8C

#define DS1302_RAM(X) (0xC0+(X)*2)         //用于计算 DS1302_RAM 地址的宏

typedef struct __SYSTEMTIME__

{

 uchar Second;

 uchar Minute;

 uchar Hour;

 uchar Week;

 uchar Day;

 uchar Month;

 uchar  Year;

 uchar DateString[9];

 uchar TimeString[9];

}SYSTEMTIME;                         //定义的时间类型  

uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,

0x5e,0x79,0x71,0xbf};

sbit DS1302_CLK=P2^1;                   //实时时钟时钟线引脚

sbit DS1302_IO=P2^0;                     //实时时钟数据线引脚

sbit DS1302_RST=P2^4;                   //实时时钟复位线引脚 

sbit ACC0=ACC^0;

sbit ACC7=ACC^7;

sbit LE2=P2^7;

sbit LE1=P2^6;

void delay1()

{

 int x,y;

 for(x=1;x>0;x--)

 for(y=110;y>0;y--);

}

void DS1302InputByte(unsigned char d)       //实时时钟写入一字节

{

 uchar i;

 ACC=d;

 for(i=8;i>0;i--)

 {

  DS1302_IO=ACC0;                       //相当于汇编中的 RRC

  DS1302_CLK=1;

  DS1302_CLK=0;

  ACC=ACC>>1;

 }

}

uchar DS1302OutputByte(void)             //实时时钟读取一字节

{

 uchar i;

 for(i=8;i>0;i--)

 {

  ACC=ACC >>1;                               //相当于汇编中的 RRC

  ACC7=DS1302_IO;

  DS1302_CLK=1;

  DS1302_CLK=0;

 }

 return(ACC);

}

void Write1302(uchar ucAddr, uchar ucDa) 

//ucAddr: DS1302地址, ucData: 要写的数据

{

 DS1302_RST=0;

 DS1302_CLK=0;

 DS1302_RST=1;

 DS1302InputByte(ucAddr);                 //地址,命令

 DS1302InputByte(ucDa);                    //写1Byte数据  

 DS1302_RST=0;

}

uchar Read1302(unsigned char ucAddr)       //读取DS1302某地址的数据

{

 uchar ucData;

 DS1302_RST=0;

 DS1302_CLK=0;

 DS1302_RST=1;

 DS1302InputByte(ucAddr|0x01);          //地址,命令

 ucData = DS1302OutputByte();           //读1Byte数据

 DS1302_RST = 0;

 return(ucData);

}

void DS1302_SetProtect(bit flag)          //是否写保护

{

 if(flag){Write1302(0x8E,0x10);}

 else{Write1302(0x8E,0x00);}

}

void DS1302_SetTime(uchar Address, uchar Value)              // 设置时间函数

{

 DS1302_SetProtect(0);

 Write1302(Address,((Value/10)<<4|(Value%10)));

}

void DS1302_GetTime(SYSTEMTIME *Time)

{

 uchar ReadValue;

 ReadValue=Read1302(DS1302_SECOND);

 Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);   //换成十进制

 ReadValue=Read1302(DS1302_MINUTE);

 Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

 ReadValue=Read1302(DS1302_HOUR);

 Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

 ReadValue=Read1302(DS1302_DAY);

 Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);      

 ReadValue=Read1302(DS1302_WEEK);

 Time->Week=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

 ReadValue=Read1302(DS1302_MONTH);

 Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);

 ReadValue=Read1302(DS1302_YEAR);

 Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);      

}

void DateToStr(SYSTEMTIME *Time)

{

 Time->DateString[0]=Time->Year/10 ;             //分离出个位和十位

 Time->DateString[1]=Time->Year%10 ;

 Time->DateString[2]='-';

 Time->DateString[3]=Time->Month/10;

 Time->DateString[4]=Time->Month%10 ;

 Time->DateString[5]='-';

 Time->DateString[6]=Time->Day/10 ;

 Time->DateString[7]=Time->Day%10 ;

 Time->DateString[8]='\0';

}

void TimeToStr(SYSTEMTIME *Time)

{

 Time->TimeString[0]=Time->Hour/10 ;

 Time->TimeString[1]=Time->Hour%10 ;

 Time->TimeString[2]=':';

 Time->TimeString[3]=Time->Minute/10 ;

 Time->TimeString[4]=Time->Minute%10 ;

 Time->TimeString[5]=':';

 Time->TimeString[6]=Time->Second/10;

 Time->TimeString[7]=Time->Second%10 ;

 Time->DateString[8]='\0';

}

void Initial_DS1302(void)

{

 uchar Second=Read1302(DS1302_SECOND);

 if(Second&0x80)          

 DS1302_SetTime(DS1302_SECOND,0);

}

void display(uchar sw,uchar wan,uchar qian,uchar bai,uchar shi,uchar ge)

{

 LE2=1;

 P0=0xfe;

 LE2=0;

 P0=0;

 LE1=1;

 P0=sw;

 LE1=0;

 delay1();

 LE2=1;

 P0=0xfd;

 LE2=0;

 P0=0;

 LE1=1;

 P0=wan;

 LE1=0;

 delay1();

 LE2=1;

 P0=0xfb;

 LE2=0;

 P0=0;

 LE1=1;

 P0=qian;

 LE1=0;

 delay1();

 LE2 = 1;

 P0  = 0xf7;

 LE2 = 0;

 P0  = 0;

 LE1 = 1;

 P0  = bai;

 LE1 = 0;

 delay1();

 LE2=1;

 P0=0xef;

 LE2=0;

 P0=0;

 LE1=1;

 P0=shi;

 LE1=0;

 delay1();

 LE2=1;

 P0=0xdf;

 LE2=0;

 P0=0;

 LE1=1;

 P0=ge;

 LE1=0;

 delay1();

}

void main()

{

 uchar t0,t1,t2,t3,t4,t5;

 SYSTEMTIME CurrentTime;

 Initial_DS1302();

 DS1302_SetTime(DS1302_HOUR,9);             //设置的时间是09:24:18    

 DS1302_SetTime(DS1302_MINUTE,24);

 DS1302_SetTime(DS1302_SECOND,18);  

 while(1)

 {

  DS1302_GetTime(&CurrentTime);

  DateToStr(&CurrentTime);

  TimeToStr(&CurrentTime);

  t0=CurrentTime.TimeString[0];

  t1=CurrentTime.TimeString[1];

  t2=CurrentTime.TimeString[3];

  t3=CurrentTime.TimeString[4];

  t4=CurrentTime.TimeString[6];

  t5=CurrentTime.TimeString[7];

  display(table[t0],table[t1],table[t2],table[t3],table[t4],table[t5]);

 }

}

 

 

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式硬件与代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值