DS1320原理和C51代码实现解读

2019-07-14 00:58发布

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]); } }
    ​ ​