单片机数字钟设计.docx
《单片机数字钟设计.docx》由会员分享,可在线阅读,更多相关《单片机数字钟设计.docx(34页珍藏版)》请在冰豆网上搜索。
单片机数字钟设计
单片机课程设计文
摘要
本论文主要讲述了可调式电子日历的设计过程,主要包括硬件设计和程序设计。
硬件主要包括以STC89C52单片机为主要控制电路、时钟电路DS1302、显示模块和按键模块电路等。
程序设计主要包括:
主程序流程图、按键扫描子程序、液晶初始化子程序等。
相比于老师要求我们做的“简易数字钟”的设计要求:
1、开机时,显示12:
00:
00的时间开始计时;2、P0.0控制“秒”的调整,每按一次加1秒;3、P0.1控制“分”的调整,每按一次加1分;4、P0.2控制“时”的调整,每按一次加1个小时。
我们进行了如下拓展:
实现日历和时钟的显示并且能够对年月日时分秒进行调试。
关键词:
STC89C52单片机、DS1302、LCD1602
设计要求与方案论证
1.1设计要求:
1具有年、月、日、时、分、秒等显示功能;
2具备年、月、日、时、分、秒校准功能;
1.2系统基本方案选择和论证
1.2.1单片机芯片的选择方案和论证
方案一:
采用89C51芯片作为硬件核心,采用FlashROM,内部具有4KBROM存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容,但是运用于电路设计中时由于不具备ISP在线编程技术,当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,对芯片的多次拔插会对芯片造成一定的损坏。
方案二:
采用STC89C52,片内ROM全都采用FlashROM;能以3V的超底压工作;同时也与MCS-51系列单片机完全兼容该芯片内部存储器为8KBROM存储空间,同样具有89C51的功能,且具有在线编程可擦除技术,对所下载的程序能够加密,比较安全。
当在对电路进行调试时,由于程序的错误修改或对程序的新增功能需要烧入程序时,不需要对芯片多次拔插,所以不会对芯片造成损坏。
所以选择采用STC89C52作为主控制系统。
1.2.2显示模块选择方案和论证
方案一:
采用点阵式数码管显示,点阵式数码管是由八行八列的发光二极管组成,对于显示文字比较适合,如采用在显示数字显得太浪费,且价格也相对较高,所以不用此种作为显示。
方案二:
采用LED数码管动态扫描,虽然LED数码管价格适中,但要显示多个数字所需要的个数偏多,功耗较大,所以也不用此种作为显示。
方案三:
采用LCD液晶显示屏,液晶显示屏的显示功能强大,可显示大量文字,图形,显示多样,清晰可见,与普通数码管相比功耗较小,硬件连接简单。
所以显示部分采用1602液晶显示。
1.2.3时钟芯片的选择方案和论证
方案一:
直接采用单片机定时计数器提供秒信号,使用程序实现年、月、日、星期、时、分、秒计数。
采用此种方案虽然减少芯片的使用,节约成本,但是,实现的时间误差较大。
所以不采用此方案。
方案二:
采用DS1302时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、周、月、年一级闰年补偿的年进行计数,而且精度高,
RAM作为数据暂存区,工作电压2.5V~5.5V范围内,2.5V时耗电小于300nA.
1.3电路设计最终方案决定
综上各方案所述,对此次作品的方案选定:
采用STC89C52作为主控制系统;DS1302提供时钟;LCD1602液晶作为显示
系统的硬件设计与实现
2.1电路设计框图
图1电路设计框图
2.2系统硬件概述
本电路是由STC89C52单片机为控制核心,具有在线编程功能,低功耗,能在3V超低压工作;时钟电路由DS1302提供,它是一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V~5.5V。
采用三线接口与CPU进行同步通信,并可采用突发方式一次传送多个字节的时钟信号或RAM数据。
DS1302内部有一个31*8的用于临时性存放数据的RAM寄存器。
可产生年、月、日、时、分、秒,具有使用寿命长,精度高和低功耗等特点,同时具有掉电自动保存功能,本电路采用DS1302单字节传送方式实现与主控机之间数据的传送;显示部分由1602构成。
2.3主要单元电路的设计
2.3.1单片机主控制模块的设计
STC89C52单片机为40引脚双列直插芯片,有四个I/O口P0,P1,P2,P3,MCS-51单片机共有4个8位的I/O口(P0、P1、P2、P3),每一条I/O线都能独立地作输出或输入。
单片机的最小系统如下图所示,18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,在片内它是振荡器倒相放大器的输入,XTAL2接外部晶振和微调电容的另一端,在片内它是振荡器倒相放大器的输出.第9引脚为复位输入端,接上电容,电阻及开关后够上电复位电路,如图-2
图2主控制系统
2.3.2时钟电路DS1302
1.DS1302的性能特性
图3示出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始终是输入端。
图3DS1302的引脚图
2.DS1302数据操作原理
DS1302在每次进行读、写程序前都必须初始化,先把SCLK端置“0”,接着把RST端置“1”,最后才给予SCLK脉冲。
DS1302的控制字,此控制字的位7必须置1,若为0则不能把对DS1302进行读写数据。
对于位6,若对程序进行读/写时RAM=1,对时间进行读/写时,CK=0。
位1至位5指操作单元的地址。
位0是读/写操作位,进行读操作时,该位为1;该位为0则表示进行的是写操作。
控制字节总是从最低位开始输入/输出的。
DS1302的日历、时间寄存器内容:
“CH”是时钟暂停标志位,当该位为1时,时钟振荡器停止,DS1302处于低功耗状态;当该位为0时,时钟开始运行。
“WP”是写保护位,在任何的对时钟和RAM的写操作之前,“WP”必须为0。
当“WP”为1时,写保护位防止对任一寄存器的写操作。
2.3.3显示模块的设计
1.1602介绍
字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。
下面以长沙太阳人电子有限公司的1602字符型液晶显示器为例,介绍其用法。
2.1602LCD的基本参数及引脚功能
1602LCD分为背光和不带背光两种,基控制大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别,引脚功能说明
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表1所示:
编号
符号
引脚说明
编号
符号
引脚说明
1
VSS
电源地
9
D2
数据
2
VDD
电源正极
10
D3
数据
3
VL
液晶显示偏压
11
D4
数据
4
RS
数据/命令选择
12
D5
数据
5
R/W
读/写选择
13
D6
数据
6
E
使能信号
14
D7
数据
7
D0
数据
15
BLA
背光源正极
8
D1
数据
16
BLK
背光源负极
表1:
引脚接口说明表
第1脚:
VSS为地电源。
第2脚:
VDD接5V正电源。
第3脚:
VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:
RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄器。
第5脚:
R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:
E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:
D0~D7为8位双向数据线。
第15脚:
背光源正极。
第16脚:
背光源负极。
1602LCD的一般初始化(复位)过程
延时15mS
写指令38H(不检测忙信号)
延时5mS
写指令38H(不检测忙信号)
延时5mS
写指令38H(不检测忙信号)
以后每次写指令、读/写数据操作均需要检测忙信号
写指令38H:
显示模式设置
写指令08H:
显示关闭
写指令01H:
显示清屏
写指令06H:
显示光标移动设置
写指令0CH:
显示开及光标设置
3.LCD1602液晶显示如图5所示:
图5LCD液晶显示
2.3.4按键模块的设计
根据设计要求需要选择四个独立按键分别为选择、加、减、确定,
按键模块如图6所示:
图6按键模块设计
系统的软件设计
3.1主程序流程图
图-A主程序流程图
主程序:
voidmain()
{
init();
write_setds(0x80,0x50);
write_setds(0x82,0x59);
write_setds(0x84,0x10);
write_setds(0x86,0x17);
write_setds(0x88,0x03);
write_setds(0x8a,0x03);
write_setds(0x8c,0x10);
write_setds(0x90,0xa4);
while
(1)
{
keyscan();
}
display();
}
3.2按键扫描子程序
调整时间用4个调整按钮,1个作为选择控制用,另外3个分别作为加调整,减调整和确定用。
时间调整程序流程图如图-B所示:
图-B时间调整程序流程图
voidSET_DS1302()
{
uchari;
Write_DS1302(0x8e,0x00);
for(i=0;i<7;i++)
{
Write_DS1302(0x80+2*i,(DateTime[i]/10<<4|(DateTime[i]%10)));
}
Write_DS1302(0x8e,0x80);
}
/*------------------------------------
读取当前时期时间
------------------------------------*/
voidGetTime()
{
uchari;
for(i=0;i<7;i++)
{
DateTime[i]=Read_Data(0x81+2*i);
}
}
/*------------------------------------
时间和日期转换成数字字符
------------------------------------*/
voidFormat_DateTime(uchard,uchar*a)
{
a[0]=d/10+'0';a[1]=d%10+'0';
}
/*------------------------------------
判断是否为闰年
------------------------------------*/
ucharisLeapYear(uinty)
{
return(y%4==0&&y%100!
=0)||(y%400==0);
}
voidRefreshWeekDay()
{
uinti,d,w=5;
for(i=2000;i<2000+DateTime[6];i++)
{
d=isLeapYear(i)?
366:
365;
w=(w+d)%7;
}
d=0;
for(i=1;id+=DateTime[3];
DateTime[5]=(w+d)%7+1;
}
/*------------------------------------
年月日时分秒++/--
------------------------------------*/
voidDateTime_Adjust(charx)
{
switch(Adjust_Index)
{
case6:
//年
if(x==1&&DateTime[6]<99)DateTime[6]++;
if(x==-1&&DateTime[6]>0)DateTime[6]--;
MonthsDays[2]=isLeapYear(2000+DateTime[6])?
29:
28;
if(DateTime[3]>MonthsDays[DateTime[4]])
DateTime[3]=MonthsDays[DateTime[4]];
RefreshWeekDay();
break;
case4:
//月
if(x==1&&DateTime[4]<12)DateTime[4]++;
if(x==-1&&DateTime[4]>1)DateTime[4]--;
MonthsDays[2]=isLeapYear(2000+DateTime[6])?
29:
28;
if(DateTime[3]>MonthsDays[DateTime[4]])
DateTime[3]=MonthsDays[DateTime[4]];
RefreshWeekDay();
break;
case3:
//日
MonthsDays[2]=isLeapYear(2000+DateTime[6])?
29:
28;
if(x==1&&DateTime[3]if(x==-1&&DateTime[3]>0)DateTime[3]--;
RefreshWeekDay();
break;
case2:
//时
if(x==1&&DateTime[2]<23)DateTime[2]++;
if(x==-1&&DateTime[2]>0)DateTime[2]--;
break;
case1:
//秒
if(x==1&&DateTime[1]<59)DateTime[1]++;
if(x==-1&&DateTime[1]>0)DateTime[1]--;
break;
}
}
3.3液晶初始化子程序
/*************初始化*************/
voidT0_INT()interrupt1
{
TH0=-50000/256;
TL0=-50000%256;
if(++tCount!
=2)return;
tCount=0;
Format_DateTime(DateTime[6],LCD_DSY_BUFFER1+5);
Format_DateTime(DateTime[4],LCD_DSY_BUFFER1+8);
Format_DateTime(DateTime[3],LCD_DSY_BUFFER1+11);
strcpy(LCD_DSY_BUFFER1+13,WEEK[DateTime[5]-1]);
Format_DateTime(DateTime[2],LCD_DSY_BUFFER2+5);
Format_DateTime(DateTime[1],LCD_DSY_BUFFER2+8);
Format_DateTime(DateTime[0],LCD_DSY_BUFFER2+11);
Display_LCD_String(0x00,LCD_DSY_BUFFER1);
Display_LCD_String(0x40,LCD_DSY_BUFFER2);
}
3.4软件测试
可调电子日历是多功能的数字型,可以看当前日期,时间。
在编写程序和调试时出现了较多的问题。
最后经过多次的模块子程序的修改,一步一步的完成,最终解决了软件。
3.5数据计算处理与性能分析:
3.5.1加减键对时间日期改变处理算法:
对于年月日,时分秒来说,每个变量的最大值和最小值都不一样,所以当年月份时分秒改变时,进行处理的算法也不一样,年没有最大值,所以不用采取“封顶”措施,每次年加一处理时,直接自加,而对于月份来说,月份是不能超过13的,所以当月份自加到13时要重新置1,具体处理见程序,在每个语句后,我都有分析注释出来。
1.3时分秒进位算法
当秒,分达到60时,向分进位,且秒数置零,从新开始计数。
当时达到24时,也一样处理。
1.4年月日进位算法
因为每个月份的天数都不同,所以事先先设定一数组:
dayofmonth[]={31,28,31,30,31,30,31,31,30,31,30,31}用以判定12个月的最大值,接着判断天数,当超过本月最大天数时,月份加一,且天数要置1。
月份判断比较简单,只要超过12,年份就加1,月份置1。
3.5.2性能分析:
首先,lcd能够正确的显示1302芯片上面的时间和日期。
其次,可以通过三个按键:
K1,K2和K3键对电子钟进行时间和日期的调整。
按K1键进行校时,可以分别对时及分进行单独校时,使其校正到标准时间,校时时需要校正哪一位哪一位就闪烁。
按K2键是对闪烁位进行加一的操作。
按K3键是对闪烁位进行减一的操作。
多次按K1键,当全部闪烁位全闪烁完毕时,就可以退出调整模式。
实验结论以及实验心得总结
4.1实验结论:
1、在该电子钟的设计中修改定时或调整时间时采用了闪烁,在编程上,首先进行了初始化定义了程序的入口地址以及中断的入口地址,在主程序的开始定义了一组固定单元用来存储计数的秒,分,时以及定时时间的序号等。
其次,时,分,秒显示用了软件译码(查表)的方式,再用了一段固定的程序段进行进制转化。
最后,用查询方式对按键进行判断,若有键按下,则进行软件延时消抖,避免了抖动引起的干扰,执行相应的定时,选时或调时程序段。
对当前时间或定时时间修改后又返回到最初的显示程序段,如此循环下去。
2、在硬件上,选用DS1302,LCD1602相结合,首先DS1302内含有一个实时时钟/日历和31字节静态RAM通过简单的串行接口与单片机进行通信实时时钟/日历电路提供秒分时日日期月年的信息每月的天数和闰年的天数可自动调整时钟操作,这样读取数据简单。
其次,选用LCD1602进行显示时,数据位串行输入,接口连线少,低功耗,显示清晰。
并且本实验的电子钟即要实现时间的现实,还要实现日期的现实,所以若是运用数码管进行显示的话,就算运用动态显示,所占用的IO口多,并且所需的数码管个数多,硬件复杂。
3、proteus是一个非常好用的仿真软件,其具有强大的电路原理图绘制功能,且可以实现模拟电路仿真、数字电路仿真、单片机及其外围电路组成的系统仿真、键盘、LCD系统仿真等多种功能;和keil联合使用时可以检测所编写的程序的正确与否。
将keil和proteus联合起来使用是实现电子设计制作的初步阶段,可避免在实际的硬件操作中因为电路原理图或向单片机烧录的程序有误而造成的难以修改的为题。
4.2实验心得总结:
1、通过本次单片机实训,我们不仅再次巩固复习了去年暑假里参加电子设计赛时学到的知识,还在老师同学的帮助下,进一步了解熟悉了DS1302,LCD1602的使用,及单片机的组成及其强大和不足。
尽管由于忙于考研中间需要熬夜来完成各种过程,但整个过程是快乐而兴奋的!
2、其次,再次巩固了KeilC51工程文件的建立,程序编写以及编译的掌握程度。
最重要的是,因为只是水平有限,要自己编写一整个C程序还是很难必须查阅相关资料,但是最终wemakeit!
我们很快乐!
3、更加熟悉掌握了Proteus的使用方法,再次从实际操作中认识到Proteus在仿真方面的优越性,激发了自己学习Proteus的兴趣;
4、因为自己要修改程序,所以单单花费在程序分析的时间就很多,为了更好的理解程序,我把每句主要程序的后面都注释了该语句的意思,详情可以见程序清单,发现注释语义的工作量也是非常大的。
写实验报告时,每个模块的流程图都是自己画的,用WORD文档画图真的很麻烦,而且不是很美观。
因为时间比较仓促,流程图写的条理性不够,不过相信以后多多练习,就可以做得更好。
5、尽管有参加电子设计大赛的经历了,但是可能由于近一年时间没有接触单片机,编程,看程序的原因了,在整个过程中还是遇到了很多故障,不过通过各种渠道(比如网络,请教同学,老师等等)解决了一些故障,虽然没有全部解决,但能在短短一周内通过此次作业,实现电子钟的功能,还是有点成就感的。
在解决这些问题的过程中发现网络确实是一个很好的学习平台,利用前人的经验可以提高自己的解决实际问题的能力。
通过这一个多礼拜的学习实践,使我们对所学的知识进行了系统的复习和巩固,在以前学习中不够清晰的概念得到了更好的理解。
致谢词
感谢学院,感谢王春梅老师再次给我们提供了一个展现自己的舞台,给我们一次难得煅炼的机会,使得我们的动手能力和专业技能都有了很大的提高。
在设计和制作的过程中,我们深切的体会到,实践是理论运用的最好检验和团队合作的重要性,这一次的设计是对我们所学知识的一次综合性检测,无论是动手能力还是理论知识运用能力都得到了提高,同时加深了我们对网络资源的认识,大大提高了查阅资料的效率,使我们有充足的时间投入到电路设计当中。
在做作品的日子里得到了王春梅老师的悉心指导,在此向我们的王春梅师致以诚挚的谢意。
参考文献
1:
张毅刚,彭喜元,姜守达,乔立言.《新编MCS-51单片机应用设计》
哈尔滨工业大学出版社,2008
2:
马忠梅.《单片机的C语言应用设计》北京航空航天大学出版社2008
3:
王静霞.《单片机应用技术》,电子工业出版社,2009.
4:
:
张道德.《单片机接口技术》,中国水利水电出版社2007
5:
石生.《电路基本分析》,高等教育出版社2008
6:
谭浩强.《C语言程序设计》(第2版),清华大学出版社.
7:
胡宴如,耿苏燕.《模拟电子技术》高等教育出版社 2000
8:
谭永红,雷跃,莫振栋《电子线路实验进阶教程》
北京航空航天大学出版2008
9:
刘国巍,周晓萍,周莉《数字电子技术基础》,国防科技大学出版社2009
10:
张永枫,《单片机应用实训教程》北京:
清华大学出版社,2008.
11:
刘守义,《单片机应用技术》(第2版)西安电子科技大学出版社,2007
12:
先锋工作室《单片机程序设计实例》北京:
清华大学出版社,2003