抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

DS1302

芯片功能

DS1302是美国DALLAS推出的一款高性能、低功耗的日历时钟芯片。

DS1302是一种串行接口的实时时钟,芯片内部具有可编程的日历时钟和31个字节的静态RAM,日历时钟可以自动进行闰年补偿,计时准确,接口简单,使用方便

工作电压范围2.5~5.5V,芯片自身还具有对备用电池进行涓流充电功能,可有效延长备用电池的使用寿命。

DS1302用于数据记录,能实现数据与该数据出现的时间同时记录,广泛应用于测量系统中。

引脚

image-20210824170629438

  • VCC1:主电源

  • VCC2:备用电源

    当VCC2大于VCC1+0.2V时,由VCC2向DS1302供电否则由VCC1向DS1302供电

  • SCLK:串行时钟输入端,控制数据输入与输出

  • I/O :双向输入线

  • CE:使能端,CE为高时允许读写DS1302数据,为低时禁止读写

应用电路

开发板实际电路如下:

image-20210824170855223

说明:

DS1302和单片机的IO连接只需3条线:

  • CE数据传输使能端、SCLK串行时钟输入端、I/O串行数据端

    (开发板上把这3个引脚分别接到了j5排针上同时通过4.7K电阻上拉到VCC,我们实际使用DS1302芯片时需要用杜邦线把j5和相应的单片机IO链接上)

此外

  • X1、X2晶振引脚外接32.768KHZ圆形晶振,给时钟芯片提供工作频率

  • VCC2接的开发上的系统电源,VCC1接的预留电池座

  • DS1302第4脚接的系统GND

DS1302的寄存器

image-20210824174037791

如图所示,时钟日历包含在 7 个读/写寄存器内,读/写寄存器中的数据是 BCD 码。(4位BCD码最大表示9,不是15, 例如用BCD码表示10为 0001 0000

  • 秒寄存器(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进行写操作。

使用对应指令即可读取或写入数据到相应寄存器,比如读取秒,用指令81h,读取分,用 83h, …

突发模式:

突发模式可以指定任 何的时钟/日历或者 RAM 寄存器为突发模式,和以前一样,第 6 位指定时钟或 RAM 而 0 位指定读或写。

突发模式的实质是指一次传送多个字节的时钟信号和 RAM 数据。如下图所示:

image-20210824174700324

也就是说,如果发送BFh指令,DS1302会一次性把年月周日、时分秒发送过来,不需要像前面一个个指令来获取时间

DS1302时序

DS1302读写数据时序,数据的传输是从最低位开始(BIT0)。

数据是以位(BIT)为单位依次写入或读出,读写数据操作中SCLK上升沿时执行写入数据,下降沿时执行读出数据。

**读数据:**CE端从低到高的一个上升沿开始允许开始读数据,拉低CE端则禁止读写数据;开始的8个SCLK周期,写命令字节,数据的后8个SCLK 周期读出数据。

image-20210824175336808

**写数据:**CE端从低到高的一个上升沿开始允许开始写数据,拉低CE端则禁止读写数据;开始的8个SCLK周期,写命令字节,数据的后8个SCLK 周期写入数据。

image-20210824175358215

例子

数码管显示DS1302时钟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#include <reg52.h>
#include <intrins.h>
#define MAIN_Fosc 11059200UL //宏定义主时钟HZ
/*====================================
自定义类型名
====================================*/
typedef unsigned char INT8U;
typedef unsigned char uchar;

typedef unsigned int INT16U;
typedef unsigned int uint;

/*====================================
硬件接口位声明
====================================*/
sbit TSCLK = P1^0;//时钟线 接到P10上用杜邦线
sbit TIO = P1^1;//数据线,接到P11上
sbit TRST = P1^2;//使能端,接到P12上
sbit DU = P2^6; //数码管段选
sbit WE = P2^7; //数码管位选
/*====================================
共阴极数码管段选码
====================================*/
uchar code table[]={
//0 1 2 3 4 5 6 7 8
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9 A B C D E F - . 关显示
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
};

/*====================================
数码管位选码
====================================*/
//第1位 2位 3位 4位 5位 6位 7位 8位
uchar code T_COM[] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};//数码管位码

/*====================================
函数:void Delay_Ms(INT16U ms)
参数:ms,毫秒延时形参
描述:12T 51单片机自适应主时钟毫秒级延时函数
====================================*/
void Delay_Ms(INT16U ms)
{
INT16U i;
do{
i = MAIN_Fosc / 96000;
while(--i); //96T per loop
}while(--ms);
}

void Display(uchar Hour, Min, Sec)
{
//------------------------------
DU = 0;
P0 = table[Hour/10];
DU = 1;
DU = 0;

WE = 0;
P0 = T_COM[0];
WE = 1;
WE = 0;
Delay_Ms(3);
//-------------------------------
DU = 0;
P0 = table[Hour%10]|0x80;
DU = 1;
DU = 0;

WE = 0;
P0 = T_COM[1];
WE = 1;
WE = 0;
Delay_Ms(3);
//------------------------------
DU = 0;
P0 = table[Min/10];
DU = 1;
DU = 0;

WE = 0;
P0 = T_COM[2];
WE = 1;
WE = 0;
Delay_Ms(3);
//-------------------------------
DU = 0;
P0 = table[Min%10]|0x80;
DU = 1;
DU = 0;

WE = 0;
P0 = T_COM[3];
WE = 1;
WE = 0;
Delay_Ms(3);
//------------------------------
DU = 0;
P0 = table[Sec/10];
DU = 1;
DU = 0;

WE = 0;
P0 = T_COM[4];
WE = 1;
WE = 0;
Delay_Ms(3);
//-------------------------------
DU = 0;
P0 = table[Sec%10];
DU = 1;
DU = 0;

WE = 0;
P0 = T_COM[5];
WE = 1;
WE = 0;
Delay_Ms(3);

}

//写DS1302数据
void Write_DS1302_DAT(uchar cmd, uchar dat)
{
uchar i;
TRST = 0; //拉低使能端
TSCLK = 0;//拉低数据总线
TRST = 1; //拉高使能端,产生上升沿开始写数据
for(i = 0; i < 8; i++)//每次写1位,写8次
{
TSCLK = 0; //拉低时钟总线
TIO = cmd & 0x01; //写1位数据,从最低位开始写
TSCLK = 1; //拉高时钟总线,产生上升沿数据被DS1302读走
cmd >>=1; //右移一位
}
for(i = 0; i < 8; i++)//每次写1位,写8次
{
TSCLK = 0; //拉低时钟总线
TIO = dat & 0x01; //写1位数据,从最低位开始写
TSCLK = 1; //拉高时钟总线,产生上升沿数据被DS1302读走
dat >>= 1; //右移一位
}
}
//读DS1302数据
uchar Read_DS1302_DAT(uchar cmd)
{
uchar i, dat;
TRST = 0; //拉低使能端
TSCLK = 0; //拉低数据总线
TRST = 1; //拉高使能端,产生上升沿开始写数据
for(i = 0; i < 8; i++)//每次写1位,写8次
{
TSCLK = 0; //拉低时钟总线
TIO = cmd & 0x01;//写1位数据,从最低位开始写
TSCLK = 1; //拉高时钟总线,产生上升沿数据被DS1302读走
cmd >>=1; //右移一位
}
for(i = 0; i < 8; i++)//每次读1位,读8次
{
TSCLK = 0; //拉低时钟总线,产生下降沿,DS1302把数据放到TIO上
dat >>= 1; //右移一位
if(TIO) dat |= 0x80;//读取数据,从最低位开始
TSCLK = 1; //拉高时钟总线,以备下一次产生下降沿
}
return dat; //返回读出数据
}

//数据转BCD码
uchar Dat_Chg_BCD(uchar dat)
{
uchar dat1, dat2;
dat1 = dat / 10;
dat2 = dat % 10;
dat2 = dat2 + dat1 * 16;
return dat2;
}

//BCD码转换为数据
uchar BCD_Chg_Dat(uchar dat)
{
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_DAT(0x8e, 0);//清除写保护
Write_DS1302_DAT(0x80, Dat_Chg_BCD(30));//30秒(并且进行BCD码转换)
Write_DS1302_DAT(0x82, Dat_Chg_BCD(15));//15分
Write_DS1302_DAT(0x84, Dat_Chg_BCD(19));//19时
Write_DS1302_DAT(0x8e, 0x80);//开写保护
while(1)
{
Write_DS1302_DAT(0x8e, 0); //清除写保护
Sec = BCD_Chg_Dat(Read_DS1302_DAT(0x81));//读秒寄存器(并且进行BCD码转换)
Min = BCD_Chg_Dat(Read_DS1302_DAT(0x83));//读分寄存器
Hour = BCD_Chg_Dat(Read_DS1302_DAT(0x85));//读时寄存器
Write_DS1302_DAT(0x8e, 0x80);//开写保护
for(i = 0; i < 50; i++) //循环显示时钟
Display(Hour, Min, Sec);

}
}

评论