基于DS1302与数码管设计的可调数字钟.docx
- 文档编号:11874239
- 上传时间:2023-04-08
- 格式:DOCX
- 页数:19
- 大小:299.68KB
基于DS1302与数码管设计的可调数字钟.docx
《基于DS1302与数码管设计的可调数字钟.docx》由会员分享,可在线阅读,更多相关《基于DS1302与数码管设计的可调数字钟.docx(19页珍藏版)》请在冰豆网上搜索。
基于DS1302与数码管设计的可调数字钟
学习情境2-可调式数字钟
之 基于DS1302与数码管设计的可调数字钟
●点名,复习
1、定时器的工作方式有哪些?
如何对定时器进行初始化。
2、数码管动态显示技术的原理?
●新课讲授
2.2基于DS1302与数码管设计的可调数字钟
前面我们用定时器产生1秒的时间,从而也设计出了可以调节数字钟,但用这种方法设计出来的电子钟不够准确。
这节课我们用美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路DS1302,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能。
同时,我们还是用数码管作为显示时间的硬件。
2.2.1DS1302芯片技术资料
DS1302是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。
DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后背电源双电源引脚,同时提供了对后背电源进行涓细电流充电的能力。
DS1302的外部引脚分配如图1所示及内部结构如图2所示。
DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。
图1DS1302引脚
图2 DS1302内部结构
1、引脚功能及结构
DS1302的引脚排列,其中Vcc1为后备电源,VCC2为主电源。
在主电源关闭的情况下,也能保持时钟的连续运行。
DS1302由Vcc1或Vcc2两者中的较大者供电。
当Vcc2大于Vcc1+0.2V时,Vcc2给DS1302供电。
当Vcc2小于Vcc1时,DS1302由Vcc1供电。
X1和X2是振荡源,外接32.768kHz晶振。
RST是复位/片选线,通过把RST输入驱动置高电平来启动所有的数据传送。
RST输入有两种功能:
首先,RST接通控制逻辑,允许地址/命令序列送入移位寄存器;其次,RST提供终止单字节或多字节数据的传送手段。
当RST为高电平时,所有的数据传送被初始化,允许对DS1302进行操作。
如果在传送过程中RST置为低电平,则会终止此次数据传送,I/O引脚变为高阻态。
上电运行时,在Vcc≥2.5V之前,RST必须保持低电平。
只有在SCLK为低电平时,才能将RST置为高电平。
I/O为串行数据输入输出端(双向),SCLK始终是输入端。
2、DS1302的寄存器和控制命令
对DS1302的操作就是对其内部寄存器的操作,DS1302内部共有12个寄存器,其中有7个寄存器与日历、时钟相关,存放的数据位为BCD码形式。
小时寄存器(85h、84h)的位7用于定义DS1302是运行于12小时模式还是24小时模式。
当为高时,选择12小时模式。
在12小时模式时,位5是,当为1时,表示PM,当为0时,表示AM。
在24小时模式时,位5是第二个10小时位。
秒寄存器(81h、80h)的位7定义为时钟暂停标志(CH)。
当该位置为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位置为0时,时钟开始运行。
控制寄存器(8Fh、8Eh)的位7是写保护位(WP),其它7位均置为0。
在任何的对时钟和RAM的写操作之前,WP位必须为0。
当WP位为1时,写保护位防止对任一寄存器的写操作。
日历、时间寄存器及控制字如表1所示:
表1日历、时钟寄存器与控制字对照表
寄存器名称
7
6
5
4
3
2
1
0
1
RAM/CK
A4
A3
A2
A1
A0
RD/W
秒寄存器
1
0
0
0
0
0
0
0/1
分寄存器
1
0
0
0
0
0
1
0/1
小时寄存器
1
0
0
0
0
1
0
0/1
日寄存器
1
0
0
0
0
1
1
0/1
月寄存器
1
0
0
0
1
0
0
0/1
星期寄存器
1
0
0
0
1
0
1
0/1
年寄存器
1
0
0
0
1
1
0
0/1
写保护寄存器
1
0
0
0
1
1
1
0/1
慢充电寄存器
1
0
0
1
0
0
0
0/1
时钟突发寄存器
1
0
1
0
1
1
1
0/1
最后一位RD/W为“0”时表示进行写操作,为“1”时表示读操作。
此外,DS1302还有年份寄存器、控制寄存器、充电寄存器、时钟突发寄存器及与RAM相关的寄存器等。
时钟突发寄存器可一次性顺序读写除充电寄存器以外的寄存器。
DS1302内部的RAM分为两类,一类是单个RAM单元,共31个,每个单元为一个8位的字节,其命令控制
字为COH~FDH,其中奇数为读操作,偶数为写操作;再一类为突发方式下的RAM,此方式下可一次性读写所有的RAM的31个字节,命令控制字为FEH(写)、FFH(读)。
表2 DS1302内部主要寄存器分布表
寄存器名称
命令字
取值范围
寄存器定义
写
读
7
6
5
4
3
2
1
0
秒寄存器
80H
81H
00-59
CH
10SEC
SEC
分寄存器
82H
83H
00-59
0
10MIN
MIN
小时寄存器
84H
85H
01-12或00-23
12/24
0
10
HR
HR
A/P
日寄存器
86H
87H
01-28,29,30,31
0
10DATE
DATE
月寄存器
88H
89H
01-12
0
0
0
10M
MONTH
星期寄存器
8AH
8BH
01-07
0
0
0
0
DAY
年寄存器
8CH
8DH
00-99
10year
year
写保护寄存器
8EH
8FH
WP
0
0
0
0
0
0
0
慢充电寄存器
90H
91H
TCS
TCS
TCS
TCS
DS
DS
DS
DS
我们现在已经知道了控制寄存器和RAM的逻辑地址,接着就需要知道如何通过外部接口来访问这些资源。
单片机是通过简单的同步串行通讯与DS1302通讯的,每次通讯都必须由单片机发起,无论是读还是写操作,单片机都必须先向DS1302写入一个命令帧,这个帧的格式如图3所示,最高位BIT7固定为1,BIT6决定操作是针对RAM还是时钟寄存器,接着的5个BIT是RAM或时钟寄存器在DS1302的内部地址,最后一个BIT表示这次操作是读操作抑或是写操作。
DS1302是SPI总线驱动方式。
它不仅要向寄存器写入控制字,还需要读取相应寄存器的数据。
要想与DS1302通信,首先要先了解DS1302的控制字。
DS1302的控制字如图3所示。
控制字节的最高有效位(位7)必须是逻辑1,如果它为0,则不能把数据写入DS1302中,位6如果为0,则表示存取日历时钟数据,为1表示存取RAM数据;位5至位1(A4~A0)指示操作单元的地址;最低有效位(位0)如为0表示要进行写操作,为1表示进行读操作,控制字节总是从最低位开始输出。
图3命令字节格式
在控制指令字输入后的下一个SCLK时钟的上升沿时,数据被写入DS1302,数据输入从低位即位0开始。
同样,在紧跟8位的控制指令字后的下一个SCLK脉冲的下降沿读出DS1302的数据,读出数据时从低位0位到高位7。
数据读写时序如图4。
图4-1 单字节读时序
图4-2 单字节写时序
物理上,DS1302的通讯接口由3个口线组成,即RST,SCLK,I/O。
其中RST从低电平变成高电平启动一次数据传输过程,SCLK是时钟线,I/O是数据线。
具体的读写时序参考图4,但是请注意,无论是哪种通讯类型的串行接口,都是对时钟信号敏感的,而且一般数据写入有效是在上升沿,读出有效是在下降沿(DS1302正是如此的,但是在芯片手册里没有明确说明),如果不是特别确定,则把程序设计成这样:
平时SCLK保持低电平,在时钟变动前设置数据,在时钟变动后读取数据,即数据操作总是在SCLK保持为低电平的时候,相邻的操作之间间隔有一个上升沿和一个下降沿。
3调试中问题说明
(1)DS1302与微处理器进行数据交换时,首先由微处理器向电路发送命令字节,命令字节最高MSB(D7)必须为逻辑1,如果D7=0,则禁止写DS1302,即写保护;D6=0,指定时钟数据,D6=1,指定RAM数据;D5~D1指定输入或输出的特定寄存器;最低位LSB(D0)为逻辑0,指定写操作(输入),D0=1,指定读操作(输出)。
(2)在DS1302的时钟日历或RAM进行数据传送时,DS1302必须首先发送命令字节。
若进行单字节传送,8位命令字节传送结束之后,在下2个SCLK周期的上升沿输入数据字节,或在下8个SCLK周期的下降沿输出数据字节。
(3) 要特别说明的是备用电源B1,可以用电池或者超级电容器(0.1F以上)。
虽然DS1302在主电源掉电后的耗电很小,但是,如果要长时间保证时钟正常,最好选用小型充电电池。
可以用老式电脑主板上的3.6V充电电池。
如果断电时间较短(几小时或几天)时,就可以用漏电较小的普通电解电容器代替。
100μF就可以保证1小时的正常走时。
DS1302在第一次加电后,必须进行初始化操作。
初始化后就可以按正常方法调整时间。
2.2.2硬件电路设计
硬件设计时使用了DS1302,电路结构简单,具体如下图所示:
2.2.3软件设计
软件设计中主要是针对DS1302芯片进行程序的设计,由以上DS1302的技术资料分析可知,作为程序设计人员,对DS1302的主要操作是:
(1)向DS1302中写一个字节,从DS1302的寄存器中读一个字节。
(2)向DS1302中写入一个数据(通常这个数据就是DS1302中某个寄存器的8位地址),从DS1302的某个寄存器中读取数据,比如读取时间寄存器中的时间。
(3)读取时间寄存器中的时间,主要是时、分、秒和年、月、日、星期等这七个寄存器的值。
1、写字节函数
voidWrite_Byte_TO_DS1302(ucharX) //向DS1302写入一个字节
{ uchari;
for(i=0;i<8;i++)
{
SDA=X&1;
CLK=1;
CLK=0;
X>>=1;
}
}
2、读字节函数
ucharRead_Byte_FROM_DS1302()
{
uchari,byte,t;
for(i=0;i<8;i++)
{
byte>>=1;
t=SDA;
byte|=t<<7;
CLK=1;
CLK=0;
}
//BCD码转换
returnbyte/16*10+byte%16;
}
3、写数据函数
ucharRead_Data_FROM_DS1302(ucharaddr)
{
uchardat;
RST=0;
CLK=0;
RST=1;
Write_Byte_TO_DS1302(addr); //向DS1302写入一个地址
dat=Read_Byte_FROM_DS1302();//在上面写入的地址中读取数据
CLK=1;
RST=0;
returndat;
}
4、读数据函数
voidWrite_Data_TO_DS1302(ucharaddr,uchardat)
{
CLK=0;
RST=1;
Write_Byte_TO_DS1302(addr);
Write_Byte_TO_DS1302(dat);
CLK=1;
RST=0;
}
5、得到时间
voidGET_Time()
{
Current_Time[0]=Read_Data_FROM_DS1302(0x81); //读取当前时间秒
Current_Time[1]=Read_Data_FROM_DS1302(0x83); //读取当前时间分钟
Current_Time[2]=Read_Data_FROM_DS1302(0x85); //读取当前时间时钟
Current_Time[3]=Read_Data_FROM_DS1302(0x87); //读取当前时间日
Current_Time[4]=Read_Data_FROM_DS1302(0x89); //读取当前时间月
Current_Time[5]=Read_Data_FROM_DS1302(0x8B); //读取当前时间秒星期
Current_Time[6]=Read_Data_FROM_DS1302(0x8D); //读取当前时间秒年
}
6、时间调整
//---------------------------------------------------------------------
//键盘中断服务程序(INT0)
//---------------------------------------------------------------------
voidEX_INT0()interrupt0
{
if(K1==0) //小时调整
{
Adjust_Flag=1; //正在调整
Current_Time[2]=(Current_Time[2]+1)%24;
}
elseif(K2==0) //分钟调整
{
Adjust_Flag=1; //正在调整
Current_Time[1]=(Current_Time[1]+1)%60;
}
elseif(K3==0)
{
SET_Time(); //将调整后的时间写入DS1302
Adjust_Flag=0; //结束调整,时间继续正常显示
}
}
7、设置时间函数,
//设置时间函数,当需要调整时间时,需要把调整好的时间写入时间缓冲数组中
//---------------------------------------------------------------------
voidSET_Time()
{
Write_Data_TO_DS1302(0x8e,0x00); //写控制字,取消写保护
Write_Data_TO_DS1302(0x82,(Current_Time[1]/10<<4)|(Current_Time[1]%10));//写入分钟
Write_Data_TO_DS1302(0x84,(Current_Time[2]/10<<4)|(Current_Time[2]%10));//写入时钟
Write_Data_TO_DS1302(0x8e,0x80); //加保护
}
●完整程序代码
//------------------------------
//名称:
基于DS1302和数码管设计的可调式电子钟
//-------------------------------------------------------------
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitSDA=P1^0; //DS1302数据线
sbitCLK=P1^1; //DS1302时钟线
sbitRST=P1^2; //DS1302复位线
sbitK1=P3^5; // 小时调整
sbitK2=P3^6; // 分钟调整
sbitK3=P3^7; // 确定
//数码管字形码
ucharcodeDSY_shuma[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,
0x83,0xC6,0xA1,0x86,0x8E,0xBF,0xFF};//共阳
//显示缓冲:
23-57-18;2011年04月16日
ucharDSY_BUFFER[]={0,0,0xBF,0,0,0xBF,0,0,0,0,0,0,0,0,0xFF};//显示缓冲00-00-00(12-04-10)
ucharCurrent_Time[7];//通过DS1302读取的日期和时间就放在这个数组中。
bitAdjust_Flag;
//*--------子程序声明--------*//
voiddelay(uintK); //延时子程序
voidDisplay();//显示子程序,主要显示小时、分钟和
voidInitialization();//初始化子程序
voidWrite_Byte_TO_DS1302(ucharx); //向DS1302写入一个字节
ucharRead_Byte_FROM_DS1302(); // 从DS1302读取一个字节
voidWrite_Data_TO_DS1302(ucharaddr,uchardat); //向DS1302中的寄存器中写入数据
ucharRead_Data_FROM_DS1302(ucharaddr); //从DS1302的某个寄存器中读取数据
voidGET_Time(); //读取当前时间,年月日,小时、分钟、秒钟
voidSET_Time(); //当调整时间时需要设置时间
//--------------------------------------------
//主程序
//--------------------------------------------
voidmain()
{
Initialization();
while
(1)
{
if(Adjust_Flag==0)
GET_Time();
Display();
}
}
//---------------------------------------------------------------------
//键盘中断服务程序(INT0)
//---------------------------------------------------------------------
voidEX_INT0()interrupt0
{
if(K1==0) //小时调整
{
Adjust_Flag=1; //正在调整
Current_Time[2]=(Current_Time[2]+1)%24;
}
elseif(K2==0) //分钟调整
{
Adjust_Flag=1; //正在调整
Current_Time[1]=(Current_Time[1]+1)%60;
}
elseif(K3==0)
{
SET_Time(); //将调整后的时间写入DS1302
Adjust_Flag=0; //结束调整,时间继续正常显示
}
}
//*--------延时子程序--------*//
voiddelay(uintK)
{
uchari,p=120;
for(i=K;i>0;i--)
{for(;p>0;p--); }
}
//*--------写字节函数,向DS1302写入一个字节--------*//
voidWrite_Byte_TO_DS1302(ucharX) //向DS1302写入一个字节
{
uchari;
for(i=0;i<8;i++)
{
SDA=X&1;
CLK=1;
CLK=0;
X>>=1;
}
}
//*--------读字节函数,从DS1302读取一个字节--------*//
ucharRead_Byte_FROM_DS1302()
{
uchari,byte,t;
for(i=0;i<8;i++)
{
byte>>=1;
t=SDA;
byte|=t<<7;
CLK=1;
CLK=0;
}
//BCD码转换
returnbyte/16*10+byte%16;
}
//-------------------------------------------------------------
//从DS1302指定位置读取数据 ,读数据
//---------------------------------------------------------------
ucharRead_Data_FROM_DS1302(ucharaddr)
{
uchardat;
RST=0;
CLK=0;
RST=1;
Write_Byte_TO_DS1302(addr); //向DS1302写入一个地址
dat=Read_Byte_FROM_DS1302();//在上面写入的地址中读取数据
CLK=1;
RST=0;
returndat;
}
//-------------------------------------------------------------
//向DS1302指定位置写入数据,写数据
//---------------------------------------------------------------
voidWrite_Data_TO_DS1302(ucharaddr,uchardat)
{
CLK=0;
RST=1;
Write_Byte_TO_DS1302(addr);
Write_Byte_TO_DS1302(dat);
CLK=1;
RST=0;
}
//-------------------------------------------------------------
//读取当前时间,年月日,小时、分钟、秒钟
//---------------------------------------------------------------
voidGET_Time()
{
Current_Time[0]=Read_Data_FROM_DS1302(0x81); //读取当前时间秒
Current_Time[1]=Read_Data_FROM_DS1302(0x83); //读取当前时间分钟
Current_Time[2]=Read_Data_FROM_DS1302(0x85); //读取当前时间时钟
Current_Time[3]=Read_Data_FROM_DS1302(0x87); //读取当前时间日
Curre
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 DS1302 数码管 设计 可调 数字