实用秒表的设计22.docx
《实用秒表的设计22.docx》由会员分享,可在线阅读,更多相关《实用秒表的设计22.docx(16页珍藏版)》请在冰豆网上搜索。
实用秒表的设计22
课程设计报告
题目:
基于51单片机的实用秒表设计
学生姓名:
雷伟
学生学号:
0908020113
系别:
电气信息工程学院
专业:
自动化
届别:
2013届
指导教师:
苗磊
电气信息工程学院制
2012年5月
基于51单片机的实用秒表设计
学生:
雷伟
指导教师:
苗磊
电气信息工程学院自动化系
1课程设计的任务与要求
1.1课程设计的任务
利用单片机的功能,结合LED数码管,并将软、硬件有机的结合起来,使得系统能够开始计时,同时能实现时刻的记录和记录上下翻即秒表的功能。
1.2课程设计的要求
(1)以单片机为控制核心,用LED数码管显示时间;
(2)要求系统具有开始/暂停、记录的上翻/下翻功能;
(3)能同时记录多个相对独立的时间并分别显示;
(4)要求电路结构简单、操作容易、硬件少、成本低。
1.3课程设计的研究基础
定时/计数器的核心是16位加法计数器,TH0、TL0是T0的高、低八位,TH1、TL1是T1的高、低八位。
方式寄存器TMOD用于设定T0和T1的工作方式,控制寄存器TCON用于设定对定时/计数器的启动、停止进行控制[1]。
当定时/计数器用于定时时,加法计数器对内部机器周期进行计数。
当定时/计数器用于计数时,加法计数器对单片引脚上的输入脉冲进行计数。
每输入一个脉冲,加法计数器加1。
当由全1再加1变成全0时产生溢出,使溢出位TF0、TF1置位,如中断允许,则向CPU提出中断,如中断不允许,则只有通过查询方式使用溢出位。
定时/计数器是可编程的,可以设定为对机器周期进行计数实现定时功能,也可以设定为对外部脉冲进行计数实现计数功能。
初始化过程如下:
(1)根据要求选择方式,确定方式控制字,写入方式控制寄存器;
(2)根据要求计算定时/计数器的初值,再由计数值求得初值,写入初值寄存器;
(3)根据需要开放定时/计数器的中断;
(4)设定定时/计数器控制寄存器的值,启动定时寄存器开始工作;
(5)等待定时/计数器时间到,则执行中断服务程序;如用查询处理编写查询程序,判断溢出标志。
2实用秒表系统方案制定
2.1方案提出
方案一:
根据设计任务要求,在I/O口设计一个键盘,通过键盘扫描程序判断是否有按键按下;对于LED数码管显示,采用静态显示。
其框图如图1-1所示:
图1实用秒表硬件框图
方案二:
本方案主要是在按键电路中,直接在I/O口接几个按键,而显示电路中,LED数码管采用动态显示,来达到本设计的要求。
其硬件构成框图如图1-2所示,P0口作为输出控制端口,在P1.0-P1.4接了5个按键,每个按键实现相应的功能。
图2 实用秒表控制系统硬件框图
2.2方案比较
结合设计要求比较以上两种方案可知:
方案一需要编写键盘扫描程序,使得编程有些复杂;静态显示稳定,但占用太多的I/O口。
方案二以按键代替方案一中的键盘,使得编程简单,且动态显示所用的端口比较少。
2.3方案论证
由于使用的按键较少,且系统是一个系统,为了使编写程序尽量简单,采用按键电路。
当LED数码管数目较多时,静态显示会占用很多的I/O口,所以选择动态显示方案以节省端口。
2.4方案选择
综上所述,显然方案二总体上优越于方案一,本次设计采用第二种方案。
3实用秒表系统方案设计
3.1各单元模块功能介绍及电路设计
(1)晶体振荡电路
89C51芯片内部有一个高增益反相放大器,用于构成振荡器。
引线XTAL1和XTAL2分别为反向放大器的输入和输出,两端跨接石英晶体及两个电容就可构成稳定的自激振荡器。
电容器C1,C2起稳定振荡频率,并对振荡频率有微调作用[2]。
(2)按键电路
因按键较少,采用直接端口扫描按键开关,用软件延时消抖提高系统的性能。
当按键被按下时,经扫描后,获得键值,并执行键功能程序,因此按下不同的按键,将执行不同的功能程序[3]。
(3)显示电路
数码管动态显示电路用四个共阴极的LED显示,LED是八段显示器,内部有七个条形发光二极管和一个小圆点发光二极管组成。
3.2电路参数的计算及元器件的选择
单片机采用AT89C51系列,使用12MHz晶振仿真调试,P1口作输出控制端口,P1.0-P1.4端口接4个按键,用作调节开关。
所用的按键较少,且有足够的I/O口使用,为了使程序简单化,直接在I/O口接按键,而不用键盘。
数码管采用动态显示,可以节省I/O口。
电容取30PF,电阻取1KΩ。
3.3特殊器件的介绍
(1)单片机
AT89C51是低电压、高性能CMOS8位单片机,具有丰富的内部资源:
4kB闪存、128BRAM、32根I/O口线、2个16位定时/计数器、5个向量两级中断结构、2个全双工的串行口,具有4.25~5.50V的电压工作范围和0~24MHz工作频率,使用AT89C51单片机时无须外扩存储器。
(2)LED数码管
所有发光二极管的阳极连接在一起,为共阳极接法;所有发光二极管的阴极连接在一起,为共阴极接法。
LED数码管的发光二极管亮暗实质是不同电平的组合,也就是为数码管提供不同的代码,这些代码称为字形代码。
数码管有静态与动态显示方式。
静态显示就是当要显示一个字符时,相应的发光二极管恒定地导通或截止,数据显示稳定,占用I/O资源较多。
动态显示就是一位一位地轮流点亮各位数码管,数据显示有闪烁感,不需要占用太多的I/O口。
3.4系统整体电路图
图3 实用秒表系统电路图
4实用秒表系统仿真和调试
4.1仿真软件介绍
(1)KeiluVision2
uVision2是51系列单片机开发工具,它的集成开发环境IDE是一个基于Windows的软件开发平台,集编辑、编译、仿真于一体,支持汇编语言和C语言的程序设计。
软件中有1个项目管理器,用于对项目文件的管理,包含了测序的环境变化和编辑有关的全部信息。
创建1个新项目的操作步骤如下[4]:
1)启动软件,创建一个项目文件,并从器件数据库选择一款合适的CPU;
2)创建一个新的源程序文件,并把这个原文件添加到项目中;
3)为单片机芯片添加或配置启动程序代码;
4)设置工具选项,使之合适目标硬件;
5)编译项目并生成.HEX文件。
(2)Proteus
Proteus软件具有原理编辑、印制电路板和交互式仿真功能,不仅是模拟电路、数字电路、模/数混合电路的设计与仿真平台,更是最先进的、最完整的多种型号微处理器的设计与仿真平台。
软件由ISIS和ARES构成,其中ISIS是一款智能电路原理图输入系统软件,可作为电子系统仿真平台;ARES是一款高级布线编辑软件,用于制作印制电路板。
创建1个原理图的一般步骤为[5]:
新建设计文件、添加元器件、布线、设置元件属性、电气检测。
4.2系统仿真实现
系统流程图如下所示:
图4 实用秒表系统流程图
(1)在已创建好项目文件的uVision2菜单栏中,执行菜单命令“Project”→“OptionsforTarget‘Target1’”,在弹出的对话框中选择“Output”选项卡,选中“CreateHEXFile”,在“Debug”选项卡,选中“Use:
ProteusVSMSimulator”;
(2)执行菜单命令“Project”→“BuildTarget”,编译源程序,若编译成功,则在“OutputWindow”中显示没有错误,并生成了.HEX文件;
(3)在已绘制好原理图的ProteusISIS中,双击AT89C51,在弹出的对话框的“ProgramFile”项中,选择在uVision2中生成的.HEX文件;
(4)执行菜单命令“Debug”→“UseRemoteDebugMonitor”将这项选中,使uVision2与Proteus真正连接起来,使它们联合调试;
(5)单击“运行”按钮,程序进入调试状态,按下按键,观察现象。
4.3系统测试
方法:
在PC机上,电路设计好后,编写程序,经编译后装入单片机运行,按下不同的按键,观察现象是否达到预期的要求。
结果:
可参考附录的主要功能展示图。
4.4数据分析
单片机装载程序后进行测试,按下“开始/暂停”键,系统开始计时;按下“记录”键,系统存储数据;按下“上翻”或“下翻”,能查看当时纪录的数据;最后按下“清零”键,数码管全显示零。
此结果表明,符合设计要求。
5总结
5.1设计小结
本次设计采选择了P0口的8个端口进行控制,因系统功能要求,在P1.0-P1.4接了5个按键,每个按键都起着相应的调节作用。
用四位LED数码管显示时间,一个"开始/暂停"键,一个"复位"键,一个“记录”键,可同时记录八个相对独立的时间;一个“上翻”键,一个“下翻”键,查看八个不同的计时值。
五个按键分别通过五个端口控制秒表的功能。
LED动态显示是将所有的数码管段选线并接在一起,用一个I/O口控制,公共端通过相应的I/O接口线控制。
根据设计要求,本次课设基本被完成了,由于秒表系统并不一定仅仅局限于计时,定时等功能。
利用AT89C51强大的扩展功能,可以进一步丰富秒表的功能,例如可设定计时时间,倒计时等等众多功能。
5.2收获体会
在本次课程设计中,我感触最深的当属查阅大量的设计资料了。
首先查阅了一些的书本资料,接着又上网搜集了许多有用信息。
开始设计的功能不能全部实现出来,于是拿着程序反复修改,最终找出错误。
经过努力,终于完成秒表的课程设计任务。
由于每一步都是亲自做过的,所以通过这次课程设计,增强了对单片机的理解,锻炼了分析﹑解决程序编写问题的实际本领,真正实现由课本知识向实际能力的转化。
由于能力和水平有限,实验过程过于简陋,实验经验尚浅,错误之处在所难免,恳请老师加以纠正,以后不断学习改进!
5.3展望
经过总结,认为做好课程设计,就必须做到:
在设计程序之前,对单片机的内部结构要有一个系统的了解;要有一个清晰的思路和一个完整的的流程图;在设计程序时,不能妄想一次就将整个程序设计好,反复修改、不断改进是程序设计的必经之路;要养成注释程序的好习惯。
在设计课程过程中遇到问题是很正常,但应该将每次遇到的问题记录下来,并分析清楚,以免下次再碰到同样的问题。
这次课程设计使我明白理论与实际相结合的重要,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从而提高自己的实际动手能力和独立思考的能力。
同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
在接下来的复习中我会再接再厉,加深对单片机相关知识的理解。
6参考文献
[1]谢维成,杨加国,等.单片机原理与应用及C51程序设计[M].清华大学出版社,2009,7.
[2]李建忠.单片机原理及应用[M].西安电子科技大学出版社,2008,2.
[3]陈小忠,黄宁,等.单片机接口技术实用子程序[M].人民邮电出版社,2005,9.
[4]周向红.51单片机课程设计[M].华中科技大学出版社,2011,1.
[5]侯玉宝,陈忠平,李成群,等.基于Proteus的51系列单片机设计与仿真[M].电子工业出版社,2010,8.
7附录
系统主要功能展示图
图5按下“开始/暂停”键的现象
图6按下“清零”键的现象
器件清单
表1器件列表
器件
型号
数量
LED数码管
7SEG-MPX4-CA
1
单片机
AT89C51
1
按键
SPSTPush
6
电容
CAP(30pF)
3
晶振
CRYSTAL
1
电阻
RES(1K)
5
排阻
RESPACK
1
C语言程序
#include
codeunsignedchartab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
codeunsignedchartab1[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
sbitkey1=P1^0;
sbitkey2=P1^1;
sbitkey3=P1^2;
sbitkey4=P1^3;
sbitkey5=P1^4;
staticunsignedcharms,sec;
staticunsignedcharSec[8],Ms[8];
staticinti,j;
voiddelay(unsignedintcnt)
{
while(--cnt);
}
voidmain()
{
unsignedcharkey3_flag=0,key4_flag=0;
TMOD=0x01;
TH0=0xd8;
TL0=0xf0;
ET0=1;
TR0=0;
TMOD=0x10;
TH1=0xf8;
TL1=0xf0;
ET1=1;
TR1=1;
EA=1;
sec=0;
ms=0;
P1=0xff;
i=0;
j=0;
start:
while
(1)
{
if(!
key1)
{
delay(50);
if(!
key1)
while(!
key1)
{;}
TR0=!
TR0;
}
if(!
key2)
{
delay(50);
if(!
key2)
{while(!
key2)
{;}
if(i==8)
{TR0=0;gotostart;}
Sec[i]=sec;
Ms[i]=ms;
i++;
}
}
if(!
key3)
{
delay(50);
if(!
key3)
{while(!
key3)
{;}
TR0=0;
key3_flag=1;
if(j==i)
gotostart;
else
if(key4_flag)
j+=2;
key4_flag=0;
sec=Sec[j];ms=Ms[j];
j++;
}
}
if(!
key4)
{
delay(50);
if(!
key4)
{
while(!
key4)
{;}
TR0=0;
key4_flag=1;
if(j<0)
gotostart;
else
if(key3_flag)
j-=2;
key3_flag=0;
sec=Sec[j];ms=Ms[j];
j--;
}
}
if(!
key5)
{
delay(50);
if(!
key5)
while(!
key5)
{;}
TR0=0;
ms=0;
sec=0;
for(i=0;i<8;i++)
{
Sec[i]=0;Ms[i]=0;
}
i=0;
}
}
}
voidtime1_isr(void)interrupt3using0
{
staticunsignedcharnum;
TH1=0xF8;
TL1=0xf0;
switch(num)
{
case0:
P2=0xfe;P0=tab[sec/10];break;
case1:
P2=0xfd;P0=tab1[sec%10];break;
case2:
P2=0xfb;P0=tab[ms/10];break;
case3:
P2=0xf7;P0=tab[ms%10];break;
default:
break;
}
num++;
if(num==4)
num=0;
}
voidtim(void)interrupt1using1
{
TH0=0xd8;
TL0=0xf0;
ms++;
if(ms==100)
{
ms=0;
sec++;
if(sec==60)
{
sec=0;
}
}
}