[技术讨论]DS1302-单片机驱动及应用实例
peng4534 发表于 2007-12-1 11:30:12
1 DS1302 简介:
DS1302 是美国 DALLAS 公司推出的一种高性能、低功耗的实时时钟
芯片,附加 31 字节静态 RAM,采用 SPI 三线接口与 CPU 进行同步通信,
并可采用突发方式一次传送多个字节的时钟信号和 RAM 数据。实时时钟
可提供秒、分、时、日、星期、月和年,一个月小与 31 天时可以自动
调整,且具有闰年补偿功能。工作电压宽达 2.5~5.5V。采用双电源供
电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电
源进行涓细电流充电的能力。DS1302 的外部引脚分配如图 1 所示及内部
结构如图 2 所示。DS1302 用于数据记录,特别是对某些具有特殊意义的
数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛
应用于测量系统中。
图 1 DS1302 的外部引脚分配
图 2 DS1302 的内部结构
各引脚的功能为:
Vcc1:主电源;Vcc2:备份电源。当 Vcc2>Vcc1+0.2V 时,由 Vcc2
向 DS1302 供电,当 Vcc2< Vcc1 时,由 Vcc1 向 DS1302 供电。
SCLK:串行时钟,输入;
I/O:三线接口时的双向数据线;
CE:输入信号,在读、写数据期间,必须为高。该引脚有两个功
能:第一,CE 开始控制字访问移位寄存器的控制逻辑;其次,CE 提供
结束单字节或多字节数据传输的方法。
DS1302 有下列几组寄存器:
① DS1302 有关日历、时间的寄存器共有 12 个,其中有 7 个寄存器
(读时 81h~8Dh,写时 80h~8Ch),存放的数据格式为 BCD 码形式,
如图 3 所示。
图 3
DS1302 有关日历、时间的寄存器
小时寄存器(85h、84h)的位 7 用于定义 DS1302 是运行于 12 小
时模式还是 24 小时模式。当为高时,选择 12 小时模式。在 12 小时模
式时,位 5 是 ,当为 1 时,表示 PM。在 24 小时模式时,位 5 是第二个
10 小时位。
秒寄存器(81h、80h)的位 7 定义为时钟暂停标志(CH)。当
该位置为 1 时,时钟振荡器停止,DS1302 处于低功耗状态;当该位置为
0 时,时钟开始运行。
控制寄存器(8Fh、8Eh)的位 7 是写保护位(WP),其它 7 位均置
为 0。在任何的对时钟和 RAM 的写操作之前,WP 位必须为 0。当 WP 位为
1 时,写保护位防止对任一寄存器的写操作。
② DS1302 有关 RAM 的地址
DS1302 中附加 31 字节静态 RAM 的地址如图 4 所示。
图 4
③ DS1302 的工作模式寄存器
所谓突发模式是指一次传送多个字节的时钟信号和 RAM 数据。突发
模式寄存器如图 5 所示。
④此外,DS1302 还有充电寄存器等。
图 5
2 读写时序说明
DS1302 是 SPI 总线驱动方式。它不仅要向寄存器写入控制字,还
需要读取相应寄存器的数据。
要想与 DS1302 通信,首先要先了解 DS1302 的控制字。DS1302 的
控制字如图 6。
图 6
控制字(即地址及命令字节)
控制字的最高有效位(位 7)必须是逻辑 1,如果它为 0,则不能把
数据写入到 DS1302 中。
位 6:如果为 0,则表示存取日历时钟数据,为 1 表示存取 RAM 数
据;
位 5 至位 1(A4~A0):指示操作单元的地址;
位 0(最低有效位):如为 0,表示要进行写操作,为 1 表示进行读
操作。
控制字总是从最低位开始输出。在控制字指令输入后的下一个 SCLK
时钟的上升沿时,数据被写入 DS1302,数据输入从最低位(0 位)开
始。同样,在紧跟 8 位的控制字指令后的下一个 SCLK 脉冲的下降沿,
读出 DS1302 的数据,读出的数据也是从最低位到最高位。数据读写时
序如图 7 。
图 7 数据读写时序
具体操作见驱动程序。
3 电路原理图:
电路原理图如图 8,DS1302 与单片机的连接也仅需要 3 条线:CE 引脚、
SCLK 串行时钟引脚、I/O 串行数据引脚,Vcc2 为备用电源,外接
32.768kHz 晶振,为芯片提供计时脉冲。
图 8
4 驱动程序
//寄存器宏定义
#define WRITE_SECOND
#define WRITE_MINUTE
#define WRITE_HOUR
#define READ_SECOND
#define READ_MINUTE
#define READ_HOUR
#define WRITE_PROTECT
//位寻址寄存器定义
sbit ACC_7 = ACC^7;
//管脚定义
sbit SCLK = P3^5;
sbit DIO= P3^6;
sbit CE = P3^7;
0x80
0x82
0x84
0x81
0x83
0x85
0x8E
// DS1302 时钟信号
// DS1302 数据信号
// DS1302 片选
7 脚
6 脚
5 脚
//地址、数据发送子程序
void Write1302 ( unsigned char addr,dat )
{
unsigned char i,temp;
CE=0;
SCLK=0;
CE = 1;
//发送地址
for ( i=8; i>0; i-- ) //循环 8 次移位
{
//CE 引脚为低,数据传送中止
//清零时钟总线
//CE 引脚为高,逻辑控制有效
SCLK = 0;
temp = addr;
DIO = (bit)(temp&0x01);
addr >>= 1;
SCLK = 1;
//右移一位
}
//每次传输低字节
//发送数据
for ( i=8; i>0; i-- )
{
SCLK = 0;
temp = dat;
DIO = (bit)(temp&0x01);
dat >>= 1;
SCLK = 1;
}
CE = 0;
}
//数据读取子程序
unsigned char Read1302 ( unsigned char addr )
{
}
//初始化 DS1302
void Initial(void)
{
Write1302 (WRITE_PROTECT,0X00);
Write1302 (WRITE_SECOND,0x56);
//禁止写保护
//秒位初始化
unsigned char i,temp,dat1,dat2;
CE=0;
SCLK=0;
CE = 1;
//发送地址
for ( i=8; i>0; i-- )
{
SCLK = 0;
temp = addr;
DIO = (bit)(temp&0x01);
addr >>= 1;
SCLK = 1;
}
//读取数据
for ( i=8; i>0; i-- )
{
ACC_7=DIO;
SCLK = 0;
ACC>>=1;
SCLK = 1;
}
CE=0;
dat1=ACC;
dat2=dat1/16;
dat1=dat1%16;
dat1=dat1+dat2*10;
return (dat1);
//循环 8 次移位
//每次传输低字节
//右移一位
//数据进制转换
//十六进制转十进制
Write1302 (WRITE_MINUTE,0x34);
Write1302 (WRITE_HOUR,0x12);
Write1302 (WRITE_PROTECT,0x80);
//分钟初始化
//小时初始化
//允许写保护
}