DS1302介绍
一款高性能、低功耗的日历时钟
DS1302是一种串行接口的实时时钟,内部有可编程的日历时钟和31个字节的静态RAM,可以自动进行闰年补偿
工作电压范围宽(2.5V~5.5V),还有对备用电池进行涓流充电功能,可有效延长备用电池的使用寿命
DS1302用于数据记录,能实现数据与该数据出现的时间同时记录,因此应用的广
DS1302引脚介绍
VCC1 | 主电源 |
---|---|
VCC2 | 备用电源,当VCC2大于VCC1 + 0.2V时,由VCC2向DS1302供电否则由VCC1向DS1302供电 |
SCLK | 串行时钟输入端,控制数据输入和输出 |
I/O | 双向输入线 |
RST | 使能端,RST为高时允许读写DS1302数据,为低时禁止读写 |
X1、X2 | 外接32.768KHZ圆形晶振,给时钟芯片提供工作频率 |
DS1302寄存器
控制寄存器
读写寄存器的数据是BCD码(8421型BCD码)
秒寄存器(81H、80H)
bit7定义为时钟暂停标志(CH)
当该位置为1时,时钟振荡器停止,DS1302处于低功耗状态
当该位置为0时,时钟开始运行
小时寄存器(85H、84H)
bit7用于定义DS1302是运行于12小时模式还是24小时模式,
当为1时,现在12小时模式,此时bit5为AM/PM位
在24小时模式时,此位为小时数据位
控制寄存器(8FH、8EH)
bit7是写保护位(WP),其他7位均为0,
在任何对时钟或RAM读写操作之前,WP位必须为0。当WP位为1时,不能对任何时钟日历寄存器或RAM进行写操作。
DS1302中附加31字节静态RAM的地址
DS1302突发模式配置寄存器
突发模式指一次传送多个字节的时钟信号或RAM数据
DS1302通信时序
数据的传输是从最低位开始(BIT0)。数据是以位(BIT)为单位依次写入或读出,读字节数据操作中SCLK上升沿时执行写入数据,下降沿时读出数据
读一字节时序
RST端(图中的CE)从低到高的一个上升沿开始允许读数据,拉低RST端则禁止读写数据;
开始的8个SCLK周期,写命令字节,数据的后8个SCLK周期读出数据。
写一字节时序
RST端(图中的CE)从低到高的一个上升沿开始允许写数据,拉低RST端则禁止读写数据;
开始的8个SCLK周期,写命令字节,数据的后8个SCLK周期写入数据
#include<reg52.h>
sbit TSCLK = P1^0;//串行时钟输入端
sbit TIO = P1^1;//双向输入线(数据线)
sbit TRST = P1^2;//使能端
#define uchar signed char
void write_DS1302(uchar cmd,uchar dat)//写一个字节
{
uchar i ;
TRST = 0;//拉低使能端
TSCLK = 0;//拉低数据总线
TRST = 1;//使能端产生上升沿
for(i = 0; i < 8; i ++)//写命令
{
TSCLK = 0;
TIO = cmd & 0x01;//最低位先传
TSCLK = 1;//数据总线产生上升沿,数据被DS1302读走
cmd >>= 1;//右移1位
}
for(i = 0; i < 8;i ++)//写数据
{
TSCLK = 0;
TIO = dat & 0x01;//最低位先传
TSCLK = 1;//数据总线产生上升沿,数据被DS1302读走
dat >>= 1;//右移1位
}
TRST = 0;//拉低使能端,关闭读写功能
}
uchar read_DS1302(uchar cmd)//读取数据
{
uchar i,dat;
TRST = 0;//拉低使能端
TSCLK = 0;//拉低数据总线
TRST = 1;//使能端产生上升沿
for(i = 0; i < 8; i ++)//传命令
{
TSCLK = 0;
TIO = cmd & 0x01;//最低位先传
TSCLK = 1;//数据总线产生上升沿,数据被DS1302读走
cmd >>= 1;//右移1位
}
for(i = 0;i < 8; i ++)//读数据
{
TSCLK = 0;//拉低数据总线
dat >>= 1;
if(TIO)
{
dat |= 0x80;
}
TSCLK = 1;//数据总线产生上升沿,数据被DS1302读走
}
TRST = 0;//拉低使能端,关闭读写功能
return dat;
}
uchar dat_to_BCD(uchar dat)//数据转BCD码
{
uchar dat1,dat2;
dat1 = dat / 10;
dat2 = dat % 10;
dat2 = dat2 + dat1 * 16;
return dat2;
}
uchar BDD_to_dat(uchar dat)//BCD码转数据
{
uchar dat1,dat2;
dat1 = dat /16;
dat2 = dat % 16;
dat2 = dat2 + dat1 * 10;
return dat2;
}
void main()
{
uchar i;
uchar sec,min,hour;
write_DS1302(0x8e,0);//清除写保护
write_DS1302(0x80,dat_to_BCD(30));//30秒
write_DS1302(0x82,dat_to_BCD(15));//15分
write_DS1302(0x84,dat_to_BCD(19));//19时
write_DS1302(0x8e,0x80);//开写保护
while(1)
{
write_DS1302(0x8e,0);//清除写保护
sec = BDD_to_dat(read_DS1302(0x81));//读秒寄存器(进行BCD码转换)
min = BDD_to_dat(read_DS1302(0x83));//读分寄存器
hour = BDD_to_dat(read_DS1302(0x85));//读时寄存器
write_DS1302(0x8e,0x80); //开写保护
for(i = 0; i < 50; i ++)//循环显示时钟
{
display(sec,min,hour);//相应的显示函数(本文没有定义)
}
}
}