DS1320原理和C51代码实现解读

DS1320原理和C51代码实现解读

  • DS封装

    这里写图片描述

  • 引脚介绍

    • VCC2 为主电源, VCC1 为备用电源,当 VCC2 > VCC1 + 0.2V时选择 VCC2 , VCC2 < vCC1 时,选择 VCC1
    • SCLK:同步时钟。
    • I/0: 数据传输,n数据输入/输出。
    • RST¯¯¯¯¯¯¯ 为复位引脚,1代表读/写使能,0代表读/写禁止。
    • GND:地
  • 功能特性

    • 能计算2100年前的年、月、日、星期、时、分、秒的信息;每月的天数和闰年天数可自动调整;时钟可设置为24或12小时格式。
    • 与单片机间采用单线同步串行通信。
    • 31字节的8位静态RAM。
    • 功耗低,保持数据和时钟信息时功率小于1mW;可选的涓流充电能力。
    • 读/写时钟或RAM数据有单字节和多字节两种传送方式。
  • 时序图

    • 分为写时序和读时序图,由SCLK时钟控制,SCLK为低电平时,单片机和DS1302之间没有数据传输。

    • 读/写时序,SCKL产生上升沿(由低电平变为高电平)

这里写图片描述

  • 放置数据时序,SCLK产生下降沿(由高电平变为低电平),放置数据。

这里写图片描述

  • 整读/写时序图。每次读/写数据时,都要先发送命令。

这里写图片描述

  • DS1302命令格式

    这里写图片描述

    • D7:必须为1代表能写入DS1302,0代表禁止写入DS1302。
    • D6:RAM/ CK¯¯¯¯¯¯ :1代表读/写RAM,0代表读/写时钟/日历数据
    • D5~D1:命令地址。
    • D0-RD/ W¯¯¯¯ : 1代表对DS1302进行读操作,0代表对DS1302进行写操作
  • DS1302寄存器
    这里写图片描述

    • DS1302有12个寄存器,7个存放时钟/日历相关信息。BCD码形式存放数据。

    • 秒寄存器

      • D7:时钟暂停位,1代表振荡器停止,DS1302为低功耗方式。0代表时钟开始工作。
      • 10SEC(D6~D4):秒的十位
      • SEC(D3~D0):秒的个位
    • 分寄存器

      • 10MIN(D6~D4):分的十位
      • MIN(D3~D0):分的个位
    • 小时寄存器

      • 12/24(D7):12或24小时选择位
      • 0(D6):
      • AP(D5):1代表AM,0代表PM
      • HR:存储时间
    • 天寄存器

      • 10DATE(D5~D4):天的十位
      • DATE(D3~D0):天的个位
    • 月寄存器

      • 10M(D4):月十位
      • MONTH(D3~D0):月个位
    • 星期寄存器

      • DAY(D3~D0)
    • 年寄存器

      • 10YEAR(D7~D4):年的十位
      • YERAR(D3~D0):年的个位
    • 写保护寄存器

      • WP:0允许写入,1进制写入。用来反正写入其他寄存器。
    • 涓流充电寄存器

      • 慢充电寄存器,用于管理对备用电源的充电

      • TCS:当4位TCS=1010时,才允许使用涓流充电寄存器,其他任何状态都将禁止使用涓流充电器。

      • DS:两DS位用于选择连接在VCC2和VCC1间的二极管数目。

      ​ 01-选择1个二极管;10-选择2个二极管;

      ​ 11或00-涓流充电器被禁止。

      • RS:两位RS位用于选择涓流充电器内部在VCC2和VCC1之间的连接电阻。

      • RS=01,选择R1(2kΩ);RS=10时,选择R2(4kΩ);RS=11时,选择R3(8kΩ);RS=00时,不选择任何电阻。

      • 时钟突发寄存器

      • 多字节读/写。写入地址3EH。

  • 代码解读

    • 读取时间流程:初始化时间->写入读取时间的命令->读取时间并输出。

    • 引脚定义:

    sbit DSIO=P3^4; //IO
    sbit RST=P3^5; //复位
    sbit SCLK=P3^6//时钟
    • 代码模块

      • void Ds1302Init()。初始化设置时间
      • void Ds1302Write(uchar addr, uchar dat)。向DS1302写入数据
      • uchar Ds1302Read(uchar addr)。向DS1302读出数据
      • void Ds1302ReadTime()。获得时间的值

    • 初始化设置时间
    uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};  //读寄存器命令
    uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c}; //写寄存器命令
    uchar TIME[7] = {0, 0x42, 0x13, 0x21, 0x11, 0x02, 0x17}; //时间初始化设置
    void Ds1302Init()
    {
        uchar n;
        Ds1302Write(0x8E,0X00);      //写入写保护寄存器,关闭写保护。
        for (n=0; n<7; n++)//把时间写入7个时间寄存器
        {
            Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]); 
        }
        Ds1302Write(0x8E,0x80);      //开启写保护
    }
    • 向DS1302写入8位数据。RST=1和SCLK=0,数据赋值为IO引脚,RST =1 ,SCLK触发上升沿写入数据,写入成功后,RST=0
    void Ds1302Write(uchar addr, uchar dat)
    {
      uchar n;
      RST = 0;
      _nop_();
      SCLK = 0;//置为0
      _nop_();
      RST = 1; //复位为1,允许写入DS1302
      _nop_();
      for (n=0; n<8; n++)//写入命令,低位先写入
      {
        DSIO = addr & 0x01;//
        addr >>= 1;
        SCLK = 1;//上升沿
        _nop_();
        SCLK = 0; //恢复
        _nop_();
      }
      for (n=0; n<8; n++)//写入数据
      {
        DSIO = dat & 0x01;
        dat >>= 1;
        SCLK = 1;//上升沿
        _nop_();
        SCLK = 0; //恢复
        _nop_();    
      } 
    
      RST = 0;//写入完成后,RST=0
      _nop_();
    }
    
    • 向DS1302读取数据,CLK =1,RST = 1.上升沿读取数据,下降沿放置数据。数据恢复到稳定阶段。
    uchar Ds1302Read(uchar addr)
    {
        uchar n,dat,dat1;
        RST = 0;
        _nop_();
    
        SCLK = 0;//
        _nop_();
        RST = 1;//
        _nop_();
    
        for(n=0; n<8; n++)//写八位命令
        {
            DSIO = addr & 0x01;//
            addr >>= 1;
            SCLK = 1;//上升沿
            _nop_();
            SCLK = 0;//恢复
            _nop_();
        }
        _nop_();
        for(n=0; n<8; n++)//读取八位数据,低位先读
        {
            dat1 = DSIO;//读取引脚IO值
            dat = (dat>>1) | (dat1<<7);
            SCLK = 1; //上升沿读取
            _nop_();
            SCLK = 0;//下降沿放置数据
            _nop_();
        }
    
        RST = 0;
        _nop_();    //必须延时,让数据稳定。下面是稳定时间
        SCLK = 1;   
        _nop_();
        DSIO = 0;
        _nop_();
        DSIO = 1;
        _nop_();
        return dat; 
    }
    • 读取时钟的值
      void Ds1302ReadTime()
      {
          uchar n;
          for (n=0; n<7; n++)//读取7个寄存器的时间数据
          {
              TIME[n] = Ds1302Read(READ_RTC_ADDR[n]);
          }
      }

猜你喜欢

转载自blog.csdn.net/jmu201521121021/article/details/78935765
C51