基于ds1302和单片机的时钟设计
发布时间:2012-03-29 20:43:03
发布时间:2012-03-29 20:43:03
单片机课程设计报告
题 目:基于DS1302电子实时时钟
姓 名:XXX
同 组 人:XXX
班级学号:XX
指导老师:XXXXX
日 期:2011-12-22
目 录
摘要
第一部分:题目要求………………………………………4
第二部分:方案论证与选择………………………………4
第三部分:电路设计与参数选择…………………………7
第四部分:系统软件设计…………………………………10
第五部分:系统调试与仪器使用…………………………12
第六部分:测试数据与结果分析…………………………18
第七部分:使用说明书……………………………………19
总 结……………………………………………………19
摘要
本作品是以89C52单片机为核心,DS1302时钟芯片、数码管做显示器及74LS08与门构成的24小时制单功能电子实时时钟。这种单功能电子实时时钟不仅具有了一般数字钟的基本功能,并且通过两个按钮实现时钟运行与停止功能。如果我们要设置时间,只需在软件程序上改变时钟芯片的初始化程序。在电子产品盛行的今天,像这样的设计我们可以给它更大的发展空间。
第一部分 题目要求
我们设计的这种24小时制功能钟,可以在数码管上显示时、分、秒,并且我们可以通过按钮来控制时钟的运行及停止(按钮KEY1控制时钟停止运行,按钮KEY2控制时钟运行)并采用220V交流电源供电。
第二部分 方案论证与选择
一、 系统功能框图
在现今的这个社会,每天的时间都很紧迫,有些人怕误了时间做自己重要的事,尤其是对现在的学生而言,他们早上要早起,上课要准时,这样都少不了有一个时钟;早上干早班的人,在外出行的人,工厂里某些要严格按时间标准来控制的产品等等一些我们身边无时无刻都有的,而在这个关键的部分就要用到我们本次设计的时钟来计时了。下面我们就介绍一下本次设计的基本设计框图。
二、系统主要部分有:
1:中央处理器电路:采用单片机芯片机外围电路构成最小系统。
2:时钟信号产生电路:时钟芯片
3:人机接口电路:按键电路、数码管显示电路。
三、方案论证及选择
1.时钟电路部分
方案一:利用单片机内部的定时功能来实现时钟的走时,通过计算可知,使定时器每25ms产生一次中断,当产生40次中断后秒单元将加一,以此类推,从而实现时、分、秒的走时,并加以显示。
由于这种方式在断电的情况下将停止走时,且通电后必须再初始化,而且需要调表,故不用此方法。
方案二:我们选用DS1302时钟芯片, 该芯片是美国DALLAS公司推出的一种高性能、低功耗的实时时钟芯片,附加31字节静态RAM,采用SPI三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号和RAM数据。实时时钟可提供秒、分、时、日、星期、月和年,一个月小与31天时可以自动调整,且具有闰年补偿功能。工作电压宽达2.5~5.5V。采用双电源供电(主电源和备用电源),可设置备用电源充电方式,提供了对后背电源进行涓细电流充电的能力。 DS1302用于数据记录,特别是对某些具有特殊意义的数据点的记录上,能实现数据与出现该数据的时间同时记录,因此广泛应用于测量系统中。
外部引脚分配
各引脚的功能为:
Vcc1:备用电源;Vcc2:主电源。当Vcc2>Vcc1+0.2V时,由Vcc2向DS1302供电,当Vcc2< Vcc1时,由Vcc1向DS1302供电。
SCLK:串行时钟,输入;
I/O:三线接口时的双向数据线;
CE:输入信号,在读、写数据期间,必须为高。该引脚有两个功能:第一,CE开始控制字访问移位寄存器的控制逻辑;其次,CE提供结束单字节或多字节数据传输的方法。
DS1302有关日历、时间的寄存器共有12个,其中有7个寄存器(读时81h~8Dh,写时80h~8Ch),存放的数据格式为BCD码形式。
所以,最后本设计采用DS1302时钟芯片。
2、显示部分
本设计中,显示部分我们可以采用1602液晶显示器或多个LED数码管显示器,下面我们就对这两个显示进行比较,看看那个显示器更加的适合该设计。
比较一:采用LCD1602液晶显示器。在我们的日常生活中,我们对LCD1602液晶显示器并不陌生,在计算器、万用表、电子表及很多家用电子产品中都可以用到它显示的主要是数字、专用符号和图形。特别是在单片机的人机交流界面中用它作为输出器件有显示质量高、采用数字式接口、体积小、重量轻。功耗低等优点。通常按显示方式咳咳分为段式、字符式、点阵式等。但是在用它做显示器的时候,我们要对它进行编程,比如我们要显示一个字符,那么这个时候就复杂了,因为一个字符由6x8或8x8点阵组成,我们这时候既要找到和显示屏幕上某几个位置对应的显示RAM区8字节,还要使每个字节的不同位为“1”,其他的为“0”,为“1”的点亮,为“0”的不亮。这样一来在显示简单的数字上就大大的加大了我们设计的难度,所以,对于一些简单的数字,我们不应采用LCD1602液晶显示来显示。
比较二:使用多个LED数码管显示。LED数码管实际上是由七个发光管组成8字形构成的,加上小数点就是8个。这些段分别由字母a,b,c,d,e,f,g,dp来表示。当数码管特定的段加上电压后,这些特定的段就会发亮,以形成我们眼睛看到的
2个8数码管
字样了。如:显示一个“2”字,那么应当是a亮b亮g亮e亮d亮f不亮c不亮dp不亮。LED数码管有一般亮和超亮等不同之分,也有0.5寸、1寸等不同的尺寸。小尺寸数码管的显示笔画常用一个发光二极管组成,而大尺寸的数码管由二个或多个发光二极管组成,一般情况下,单个发光二极管的管压降为1.8V左右,电流不超过30mA。发光二极管的阳极连接到一起连接到电源正极的称为共阳数码管,发光二极管的阴极连接到一起连接到电源负极的称为共阴数码管。常用LED数码管显示的数字和字符是0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。再一个,数码管相对于LCD1602液晶显示器来说具有亮度大、接口设计比较容易,价格相对较便宜等优点。且在本次设计中恰好能把我们要显示的数字显示出来。所以,本次设计采用多个LED数码管显示器来显示数字。
3、按键部分
方案一:并口输入式的按键控制。它的优点是电路设计简单,但每一管脚对应一个按键,虽然说单片机有多个外部引脚,但本系统采用多个LED数码管显示、时钟芯片等外围电路,他们占用外部接口线较多,要是此时要在单片机上再添加几个按键的话,那么这样单片机的外部引脚就有点供应不了,所以在占用如此多管脚的情况下,该方案是不可取的。
方案二:我们可以采用芯片74LS08与门来扩展接口,虽然在该设计中我们只用到二个按钮,但用这个芯片就足可以了。我们采用这种方式只占用1个口线,另外按键去抖动较方便,是一种明智的选择。
第三部分 电路设计与参数选择
一、 单片机最小系统电路设计和元件的选择
根据设计要求和计算简便的原则,我们选择12M的石英晶振、30PF的陶瓷电容、22uF的瓷片电容、10k电阻、+5V电源,最小系统图如下:
二、数码管显示电路设计
电路如下图:
我们这里采用8个数码管来显示时分秒,在单片机的P0引脚上外接上10k的上拉电阻。P0口输出段码,P2口输出位码。
三、DS1302时钟芯片电路设计
部分电路图如下:
在这里我们采用32.768kMZ的晶振接在DS1302的X1和X2之间,DS1302的5、6、7引脚分别接在单片机的P1.2、P1.1、P1.0三个引脚上,VCC2接上+5V电源,VCC1可以外接电源。
四、按键电路设计
部分电路图如下:
这里我们采用74LS08与门芯片来扩展接口,同时,我们在编程时用外部中断0来设计程序,以便更好的实现效果。在按键与单片机13和14引脚之间接上一10k的上拉电阻,电阻上接+5V电源。
第四部分 软件设计部分
一、 主程序单元部分。
主程序流程图如上所示
在主程序中调用时分秒显示子程序,通过按键来判断DS1302时钟芯片运行还是停止。
二、外部中断部分
用外部中断0来是秒停止或开始计数。
三、 显示程序单元部分。
此系统的显示部分采用的是多个LED数码管显示,主要显示时分秒,内的数据通过输出端口一次输出到显示器上。
时、分、秒显示流程图如下:
注释:该显示大概流程图是这样,但在该程序设计中是把时、分、秒的显示程序分别提出来单独做一个子程序。
四、DS1302时钟芯片判断时钟是否停止流程图
第五部分 系统调试与仪器使用
一、 系统调试
调试工作分硬件调试和软件调试两部分,调试方法介绍如下:
首先,硬件调试主要是先搭建硬件平台,然后利用万用表等工具对电路检测,最后用程序进行功能调试,硬件调试比较费时,需要细心和耐心也需要熟练掌握电路原理。
然后,可以直接应用编辑或仿真软件进行调试,比如单片机C51编辑软件Keil.该软件提供了一个集成开发环境uVision,它包括C编辑、宏编辑、连接器、库管理和一个功能强大的仿真调试器。通过编译。运行,可以检查程序错误。但使用此方法,仍需要十分了解所使用元器件的工作方式和管脚连接方式。软件调试过程中要仔细耐心,即便是要多写一两个字符,都无法编译成功。而有时往往在Keil中编译。运行无错,但烧录到单片机中运行出错,很有可能是编程时管脚或时序编辑得不对。
还有一种方式,即应用仿真软件搭建电路的软件平台,再导入程序进行仿真调试,如果电路出错,可以在计算机上方便的修改电路,程序出错可以重新编辑程序,这种方法节时、省力、经济、方便。我们这里应用的是Protuse7.5.总之,调试过程是一个软硬件结合调试的过程,硬件电路是基础,软件是检测硬件电路和实现其功能的关键。
1、 时钟显示:
我们首先进行时钟信号测试、多个LED数码管显示的的调试,以实现基本功能,看看在把程序导进去是否有线路没有接通或虚焊的现象出现。
在这个过程中,我们主要让数码管上有数字显示出来,具体是什么数这就不用关了。
2、 DS1302的调试
该电路含DS1302芯片、主电源、备用电源、晶振等部分。在与单片机连接的过程中需要注意以下几点:
1)、清楚DS1302与单片机连接的管脚。本设计定义为:DS1302的SCLK连接P1.0,I/O口连接P1.1,RST口连接P1.2.
2)、注意电源正负极连接。
3)、DS1302连接32.768KHz的晶振。该晶振体形比较小,在焊接是要小心的,注意不要将晶振引脚弄断。同时也要尽量使晶振离DS1302的X1、X2引脚近距离焊接。
4)、编写DS1302的时钟/日历程序,只要能够正确显示时间。烧录进单片机,检查电路电源正负极连接是否正确。检查无误后再上电检查。
3、按键电路调试
按键电路比较简单,故而调试起来也比较容易,只需要保证按键焊接正确,没有虚焊或忘焊的现象出现一般不会出很大的问题。
二、程序导入所用仪器
采用51单片机开发板软件和PZISP软件把程序导入89C51单片机中。
三、源程序
#include
#include
#define uchar unsigned char
#define uint unsigned int
sbit DATA=P1^1; //位定义1302芯片的接口,数据输出端定义在P1.1引脚
sbit RST=P1^2; //位定义1302芯片的接口,复位端口定义在P1.1引脚
sbit SCLK=P1^0; //位定义1302芯片的接口,时钟输出端口定义在P1.1引脚
sbit key1=P3^3;
sbit key2=P3^4;
uchar code displaytable[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar second,minute,hour;
void delaynus(uchar n)
{
uchar i;
for(i=0;i
}
void delayms(uchar n)
{
uchar i;
while(n--)
for(i=0;i<120;i++);
}
void write1302(uchar dat)
{
uchar i;
SCLK=0; //拉低SCLK,为脉冲上升沿写入数据做好准备
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续写8个二进制位数据
{
DATA=dat&0x01; //取出dat的第0位数据写入1302
delaynus(2); //稍微等待,使硬件做好准备
SCLK=1; //上升沿写入数据
delaynus(2); //稍微等待,使硬件做好准备
SCLK=0; //重新拉低SCLK,形成脉冲
dat>>=1; //将dat的各数据位右移1位,准备写入下一个数据位
}
}
void writeset1302(uchar Cmd,uchar dat)
{
RST=0; //禁止数据传递
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
delaynus(2); //稍微等待,使硬件做好准备
write1302(Cmd); //写入命令字
write1302(dat); //写数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
}
unsigned char read1302(void)
{
uchar i,dat;
delaynus(2); //稍微等待,使硬件做好准备
for(i=0;i<8;i++) //连续读8个二进制位数据
{
dat>>=1; //将dat的各数据位右移1位,因为先读出的是字节的最低位
if(DATA==1) //如果读出的数据是1
dat|=0x80; //将1取出,写在dat的最高位
SCLK=1; //将SCLK置于高电平,为下降沿读出
delaynus(2); //稍微等待
SCLK=0; //拉低SCLK,形成脉冲下降沿
delaynus(2); //稍微等待
}
return dat; //将读出的数据返回
}
uchar readset1302(uchar Cmd)
{
unsigned char dat;
RST=0; //拉低RST 178 / 192
SCLK=0; //确保写数居前SCLK被拉低
RST=1; //启动数据传输
write1302(Cmd); //写入命令字
dat=read1302(); //读出数据
SCLK=1; //将时钟电平置于已知状态
RST=0; //禁止数据传递
return dat; //将读出的数据返回
}
void setprotect(bit flag)//设置保护
{
if(flag)
writeset1302(0x8e,0x80);//写入保护指令
else
writeset1302(0x8e,0x00);//写入不保护指令
}
void stoptime(bit flag) // 是否将时钟停止
{
uchar dat;
dat=readset1302(0x81);
setprotect(0);
if(flag)
writeset1302(0x80, dat|0x80);
else
writeset1302(0x80, dat&0x7f);
}
void init_ds1302(void)
{
setprotect(0); //根据写状态寄存器命令字,写入不保护指令
writeset1302(0x80,((0/10)<<4|(0%10))); //根据写秒寄存器命令字,写入秒的初始值
writeset1302(0x82,((0/10)<<4|(0%10))); //根据写分寄存器命令字,写入分的初始值
writeset1302(0x84,((12/10)<<4|(12%10))); //根据写小时寄存器命令字,写入小时的初始值
}
void displayhour(uchar h)//显示小时
{
P2=0xfe;
P0=displaytable[h/10];
delayms(1);
P2=0xfd;
P0=displaytable[h%10];
delayms(1);
P2=0xfb;
P0=0x40;
delayms(1);
}
void displayminute(uchar m) //显示分钟
{
P2=0xf7;
P0=displaytable[m/10];
delayms(1);
P2=0xef;
P0=displaytable[m%10];
delayms(1);
P2=0xdf;
P0=0x40;
delayms(1);
}
void displaysecond(uchar s) //显示秒
{
P2=0xbf;
P0=displaytable[s/10];
delayms(1);
P2=0x7f;
P0=displaytable[s%10];
delayms(1);
}
void main()
{
uchar ReadValue; //缓冲数据用的
init_ds1302(); //ds1302初始化
IT0=1; //外部中断0
EX0=1;
EA=1;
while(1)
{
ReadValue = readset1302(0x81); //从秒寄存器读数据
second=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F);//将读出数据转化
displaysecond(second); //显示秒
ReadValue = readset1302(0x83); //从分寄存器读
minute=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
displayminute(minute); //显示分
ReadValue = readset1302(0x85); //从分寄存器读
hour=((ReadValue&0x70)>>4)*10 + (ReadValue&0x0F); //将读出数据转化
displayhour(hour); //显示小时
}
}
void int0() interrupt 0 //外部中断0
{
if(key1==0)
{
stoptime(1);
}
else if(key2==0)
{
stoptime(0);
}
}
第六部分 测试数据与结果分析
我们利用一只走时准确的电子表进行时钟比对,证明本作品走时准确,按键是否会实现效果。
显示图
从以上图中可以看出,数码管显示的与DS1302 Clock –U2上Time显示出来的数相同,虽然与Date后的数不同,但那是我们没有编写那个程序。
第七部分 多 功 能 数 字 钟 使 用 说 明
这次设计的电子实时时钟采用多个LED数码管显示,我们可以用仿真软件给以教程。DS1302在计时时,数码管上显示时分秒,当我们按下key1按钮时,DS1302计时停止,这个我们可以从数码管上看出来,当我们按下key2按钮时,DS1302有开始计时。
总 结
从这次的设计中让我更加的了解DS1302的工作原理,让我对按照时序图来设计程序更加有趣,在以前,看到很多芯片的数据手册,要把它们这些芯片和单片机连接起来就的编写程序,而老师又不会给程序给我们,别的人就算是给了自己也不会,因为根本看不懂,到最后只有靠自己来设计程序,但每次看到那时序图就傻了,根本就不知道从哪着手。通过这次对DS1302芯片的设计让我对看时序图设计程序摸到了路线和套路。
经过本次设计,让我收益非浅。但也发现了自己的一些不足,在今后的学习过程中将更加努力,以适应社会和时代发展要求。