51单片机DS1302实时时钟驱动程序

编程实验

72人已加入

描述

  ds1302引脚及功能

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

  图1示出DS1302的引脚排列,其中Vcc1为后备电源,VCC2为主电源。在主电源关闭的情况下,也能保持时钟的连续运行。DS1302由Vcc1或Vcc2两者中的较大者供电。当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。当Vcc2小于Vcc1时,DS1302由Vcc1供电。X1和X2是振荡源,外接32.768kHz晶振。RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。RST输入有两种功能RFBLN2012090A1T:首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器SMBJ70A-TR;其次,RST提供终止单字节或多字节数据的传送手段。当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。上电运行时,在Vcc≥2.5V之前,RST必须保持低电平。只有在SCLK为低电平时,才能将RST置为高电平。I/O为串行数据输入输出端(双向),后面有详细说明。SCLK始终是输入端。

DS1302

  DS1302的控制字节

  DS1302的控制字如图2所示。控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据GRM1886T1H1R0CD01C;位5至位1指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。

DS1302

  DS1302电路图

DS1302

  SCL,SDA,RST_D连接单片机,VCC电压不清楚,只是有个接口。VCC是连接的ATMEGA64.

DS1302

  VCC=3.3V

  DS1302与CPU的连接需要三条线,即SCLK(7)、I/O(6)、RST(5)。图3示出DS1302与89C2051的连接图,其中,时钟的显示用LCD。

DS1302

  51单片机DS1302实时时钟驱动程序

  #include《reg51.h》

  #include《intrins.h》

  #define uchar unsigned char

  #define uint unsigned int

  sbit IO=P3^4; //数据输入输出线

  sbit RST=P3^5; //复位信号线

  sbit SCLK=P3^6; //时钟信号线

  uchar code write_addr[]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c}; //写的地址

  uchar code read_addr[]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d}; //读的地址 //---存储顺序是秒分时日月周年,存储格式是用BCD码---//

  uchar time[7]={0,0,0x12,0x12,0x12,0x20,0x15}; //初始化的时间为2015年12月12日12:00

  1、初始化

  void ds1302_init()

  {

  uchar k;

  write(0x8e,0x00); //禁止写保护,即允许数据写入

  for(k=0;k《7;k++) //写入7个字节的时钟信号:分秒时日月周年

  {

  write(write_addr[k],time[k]);

  }

  write(0x8e,0x80); //打开写保护

  }

  2、写字节

  void write(uchar addr,uchar dat)

  {

  uchar i,j;

  SCLK=0;

  _nop_();

  RST=0;

  _nop_();

  RST=1; //拉高,准备写地址写数据

  _nop_();

  _nop_();

  for(i=0;i《8;i++) //传送8位地址,往哪里写

  {

  SCLK=0; //再置为低,以便实现上升沿

  _nop_();

  IO=addr&0x01; //先传送最低位

  addr》》=1; //向右移位,把8位数据依次写入

  SCLK=1; //数据在上升沿时,写入数据

  _nop_();

  }

  for(j=0;j《8;j++) //写入8位数据

  {

  SCLK=0; //置为低,以便实现上升沿

  _nop_(); IO=dat&0x01; //先传送最低位

  dat》》=1; //向右移位,把8位数据依次写入

  SCLK=1; //数据在上升沿时,写入数据

  _nop_();

  }

  RST=0; //释放

  _nop_();

  }

  3、读字节

  uchar read(uchar addr)

  {

  uchar i,dat=0;

  SCLK=0;

  _nop_();

  RST=0;

  _nop_();

  RST=1; //拉高,准备写地址读数据

  _nop_();

  _nop_();

  for(i=0;i《8;i++) //传送8位地址,从哪里读

  {

  SCLK=0; //置为低,以便实现上升沿

  _nop_();

  IO=addr&0x01; //先传送最低位

  addr》》=1; //向右移位,把8位数据依次写入

  SCLK=1; //数据在上升沿时,写入数据

  _nop_();

  }

  _nop_();

  for(i=0;i《8;i++) //读出8位数据

  {

  SCLK=1; //置为低,以便实现下降沿

  _nop_();

  dat》》=1; //向右移位,把8位数据依次读出

  if(IO==1)

  dat=dat|0x80;

  SCLK=0; //读数据时,下降沿有效

  _nop_();

  }

  RST=0; //复位

  _nop_();

  SCLK = 1;

  _nop_();

  IO = 0;

  _nop_();

  IO = 1;

  _nop_();

  return dat; //返回读到的数据 }

  4、读时间

  void read_time()

  {

  uchar n;

  for(n=0;n《7;n++)

  time[n]=read(read_addr[n]); //读取分秒时日月周年

  }

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分