基于89C51单片机的秒表课程设计

单片机原理及系统课程设计

专    业:  电气工程及其自动化   

班    级:           

姓    名:             

学    号:          

指导教师:             

兰州交通大学自动化与电气工程学院

 年 月 日

1 引言

随着电子技术的发展,电子技术在各个领域的运用也越来越广泛,人们对它的认识也逐步加深。秒表计时器常常用于体育竞赛及各种其他要求有较精确时间的各领域中。其中启/停开关的使用方法与传统的机械计时器相同,即按一下启/停开关,启动计时器开始计时,再按一下启/停开关计时终止。而复位开关可以在任何情况下使用,即使在计时过程中,只要按一下复位开关,计时应立即终止。

2 设计方案及原理

以单片机为核心,设计一个秒表,具有计时功能,按键有启动计时、数据清零、停止、时间显示。

采用3个LED数码管显示时间,计时范围设置为0~99.9秒,即精确到0.1秒,用按键控制秒表的“开始”、“暂停”、“复位”,按“开始”按键,开始计时;按“暂停”按键,系统暂停计时;再按“开始”键,系统继续计时;数码管显示当前计时值;按“复位”按键,系统清零。

3 硬件设计

MCS-51系列单片机是8位单片机产品,89C51是其中的典型代表,基本模块包括以下几个部分:

(1)CPU:89C51的CPU是8位的,另外89C51内部有1个位处理器;

(2)R0M:4KB的片内程序存储器,存放开发调试完成的应用程序;

(3)RAM:256B的片内数据存储器,容量小,但作用大;

(4)I/O口:P0-P3,共4个口32条双向且可位寻址的I/O口线;

(5)中断系统:共5个中断源,3个内部中断,2个外部中断;

(6)定时器/计数器:2个16位的可编程定时器/计数器;

(7)通用串行口:全双工通用异步接收器/发送器;

(8)振荡器:89C51的外接晶振与内部时钟振荡器为CPU提供时钟信号;

(9)总线控制:89C51对外提供若干控制总线,便于系统扩展。

89C51单片机内部的振荡电路是一个高增益反相放大器,引线XTAL1和XTAL2分别为反相振荡放大器的输入及内部时钟工作电路的输入和来自反相振荡器的输出,该反相放大器可以配置为片内振荡器。

采用上电复位,上电后,由于电容充电,使RST持续一段时间的高电平,从而实现上电复位操作。

采用3个LED数码管,LED是七段显示器,内部有7个条形发光二极管和1个小圆点发光二极管,根据各管的亮暗组成字符。用Proteus软件画出主电路图见附录一。

4 软件设计

(1)秒表的初始化

根据程序流程图,先进行秒表的初始化,即:①将I/O口P3全写一,为秒表的控制输入做好准备;②将数码管全部置零,使其处于秒表计时的初始状态;③将工作寄存器R0~R2以及30H初始化,留待后面的计时程序备用;④将定时器0置于工作方式1,并为其装入计时预置数D8FE(因为程序运行过程中占用的时间会导致一定误差,此为经实物测试之后的修正值),即将定时器定为每10ms溢出;⑤开总中断允许和定时器0中断允许。初始化完成后,即进入之后的按键扫描程序。

(2)按键检测程序

轮流检测开始计时(P3.2)、暂停计时(P3.3)、秒表清零(P3.4)三个按键。若发现有一个按键出现低电平(可能被按下),则延时10ms(调用延时子程序DELAY),延时完成后,若发现低电平消失,则说明该按键实际上未被按下,此时转回按键检测处继续检测;若发现仍然是低电平,则说明此键确实被按下了,此时就跳转至相应的程序标号处,执行相应的功能。

(3)开始计时

若确认“开始计时”键被按下,则跳转至程序标号“RUN”处,将定时器0计时允许控制位TR0置位,则定时器开始运行。此动作完成后,返回按键检测程序,等待操作者的下一次指令。

(4)计时程序

定时器0计时至10ms,溢出,引发中断,程序跳转至定时器0中断服务程序入口000BH处执行。程序跳转至中断服务程序TIME0。由于秒表的最小计时单位是0.1s,即100ms,因此需加入软件计时,使定时器0溢出10次之后才改变数码管的显示状态。因此每来一次中断就将30H中的数加1,若30H中的数没有到10,则给定时器0重新装入预置数,之后中断返回并继续等待中断;到10了,才进入显示程序,改变数码管的显示状态,执行完毕之后中断返回并继续等待中断。

(5)显示程序

将数码管的段选码放在数表TAB中。每次100ms计时完成后,将R0中的值(初值为0)送入A,然后自加1。若R0中的值没到10,则使用累加器A查表,并将查得的数码管段选码送入毫秒位数码管。之后将30H中的数置零,中断返回。若发现R0中的数到10了,则将R0置零,并转入秒位进位子程序SECOND,向秒位进位,之后,继续照常向毫秒位送数。

(6)暂停计时

若确认“暂停计时”键被按下,则跳转至程序标号“PAUSE”处,将定时器0计时允许控制位TR0置零,则定时器暂停运行。此动作完成后,返回按键检测程序,等待操作者的下一次指令。

(7)秒表清零

若确认“秒表清零”键被按下,则跳转至程序标号“STOP”处,将TR0置零,关闭定时器0运行。并且将数码管、工作寄存器、定时器0预置数全部重置,使其处于秒表计时的初始状态。此动作完成后,返回按键检测程序,等待操作者的下一次指令。

(8)延时程序

用于按键延时防抖,延时10ms。程序清单见附录二。

程序流程图如图1所示。

图1 程序流程图

4.3 程序仿真

将以上程序清单导入先前做好的Proteus仿真电路,汇编之后,按

键开始进行仿真。

仿真结果如图2。

图2 仿真结果图

仿真开始后,第一个按钮为计时按钮,点击开始计时;第二个按钮为暂停按钮,点击则暂停计时;第三个按钮为复位按钮,点击后秒表复位归零。三个显示器分别是十秒、秒、微秒的显示。如图2显示的为21.9秒。

5 总结

在此次课程设计中秒表虽然是一个非常简单的功能,但要在单片机中使用汇编语言来实现这个功能,仍然花了我不少心思。

首先是计时的问题,由于单片机计时器最大只能计时65.5ms,因此要实现毫秒位的变化,我采用了软件计时的方法,单片机只需计时10ms,然后用软件重复10次,即可达到计时100ms的目的。

显示方面,为了使编程简单,我使用了静态显示。不过这使得占用I/O口线过多,而且连线复杂繁琐,为实物的制作带来了不便。在以后的学习和应用中我会努力加深动态扫描显示的理解,争取熟练运用。

根据书本知识,我们一开始只给P0口加上了上拉电阻,但是实物做成后我们发现P1和P2口得输出显示非常暗,初步确定是驱动能力不足的问题后,我们给二者也加上了上拉电阻,结果使得显示正常了。由此我们了解到,实践才是检验真理的唯一标准,有时候书本上的知识需要经过实践的改进,才能运用到实际中。

此次课程设计巩固了我的基础知识,提高了我的应用水平,锻炼了我的动手能力,使我受益匪浅。然而,在吸取经验的同时,我也吃了不少教训。在编程、仿真、焊接方面都走了不少弯路。但是,学则要有所收获,经过此次的锻炼,我在很多方面都已经有所提高,知识也掌握得更加扎实了。

   在今后的学习和实践中,我将继续努力钻研,提高自己,争取在学术和记忆上获得更大的进步。

参考文献

[1]张毅刚, 彭喜元.单片机原理及接口技术[M].人民邮电出版社.

[2]单片机课程设计实例指导  李光飞等.   北京航空航天大学出版社

[3]51系列单片机原理、开发与应用实例   孙进平等编著

[4]单片机程序设计实例   先锋工作室编著   清华大学出版社 

.

7 附录

附录一主电路图

附录二 主程序

ORG 0000H          ;程序开始

AJMP START         ;跳转到主程序START

ORG 000BH          ;定时器0中断的地址入口

AJMP TIME0         ;定时器0溢出,跳转到中断程序TIME0

START:             ;主程序

MOV P3,#0FFH       ;输入端口P3全写1

MOV P0,#3FH        ;

MOV P1,#3FH        ;

MOV P2,#0BFH       ;数码管初始化

MOV 30H,#00H       ;

MOV R0,#00H        ;

MOV R1,#0AH        ;

MOV R2,#00H        ;工作寄存器初始化

MOV TMOD,#01H      ;定时器0工作于方式1

MOV TH0,#0D8H      ;

MOV TL0,#0FEH       ;定时器0预置数(D8FEH=55550D)

SETB EA            ;开总中断允许

SETB ET0           ;开定时器0中断允许

READ:              ;读键程序

L1:JB P3.2,L2      ;

LCALL DELAY        ;按键延时防抖

JB P3.2,L1         ;

AJMP RUN           ;确认计时键被按下,开始/继续计时

L2:JB P3.3,L3      ;

LCALL DELAY        ;按键延时防抖

JB P3.3,L2         ;

AJMP PAUSE         ;确认暂停键被按下,暂停计时

L3:JB P3.4,L1      ;

LCALL DELAY        ;按键延时防抖

JB P3.4,L3         ;

AJMP STOP          ;确认清零键被按下,秒表重置

RUN:               ;计时键按下,跳转至此

SETB TR0           ;定时器0开始/继续运行

AJMP READ          ;

PAUSE:             ;暂停键按下,跳转至此

CLR TR0            ;

AJMP READ          ;   

TIME0:             ;定时器0溢出,中断,跳转至此

INC 30H            ;

MOV A,30H          ;

CJNE A,#0AH,TIME1  ;30H单元中的值到10了吗?(计时到10毫秒了吗,也就是说,该向毫秒位送数了吗?)

MOV DPTR,#TAB      ;30H中的值到10了,顺序执行

MOV A,R0           ;

INC R0             ;

CJNE R0,#0AH,GET   ;R0中的值到10了吗?(该向秒位进位了吗?)

MOV R0,#00H        ;

LCALL SECOND       ;到了,R0清零,调用进位子程序SECOND,向秒位进位

GET:               ;没到,跳过进位子程序

MOVC A,@A+DPTR     ;

MOV P1,A           ;查表并向数码管毫秒位送数

MOV 30H,#00H       ;重置30H单元

TIME1:             ;

MOV TH0,#0D8H      ;

MOV TL0,#0FEH       ;给定时器0重新预置数

RETI               ;中断返回

SECOND:            ;秒位进位子程序

PUSH ACC           ;

PUSH PSW           ;将ACC和PSW推入堆栈保护

MOV A,R1           ;

INC R1             ;

CJNE R1,#14H,GET1  ;R1中的值到20了吗,也就是说,该向十秒位进位了吗?

MOV R1,#0AH        ;

LCALL SECOND1      ;到了。R1重置,调用进位子程序SECOND1,向十秒位进位

GET1:              ;没到,跳过进位子程序

MOVC A,@A+DPTR     ;

MOV P2,A           ;查表并向数码管秒位送数

POP PSW            ;

POP ACC            ;PSW,ACC出栈

RET                ;子程序返回

SECOND1:           ;十秒位进位子程序

PUSH ACC           ;

PUSH PSW           ;将ACC和PSW推入堆栈保护

MOV A,R2           ;

INC R2             ;

CJNE R2,#0AH,GET2  ;R2中的值到10了吗,也就是说,该将此位归零了吗?

MOV R2,#00H        ;到了,R2清零

GET2:              ;没到,跳过清零程序

MOVC A,@A+DPTR     ;

MOV P0,A           ;查表并向数码管十秒位送数

POP PSW            ;

POP ACC            ;PSW,ACC出栈

RET                ;子程序返回

STOP:              ;清零键按下,跳转至此

MOV P3,#0FFH       ;

MOV P0,#3FH        ;

MOV P1,#3FH        ;

MOV P2,#0BFH       ;数码管清零

MOV 30H,#00H       ;

MOV R0,#00H        ;

MOV R1,#0AH        ;

MOV R2,#00H        ;工作寄存器初始化

CLR TR0            ;计时器0停止计时

MOV TH0,#0D8H      ;

MOV TL0,#0FEH       ;定时器0预置数

AJMP READ          ;

DELAY:             ;延时10ms子程序

MOV R3,#50D        ;

D1:MOV R4,#100D    ;

D2:DJNZ R4,D2      ;

DJNZ R3,D1         ;

RET                ;子程序返回

TAB: DB 06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,3FH,86H,0DBH,0CFH,0E6H,0EDH,0FDH,87H,0FFH,0EFH,0BFH ;数码管段选码数表

END                ;程序结束

 

第二篇:课程设计 单片机 60秒秒表

1任务及要求

1.1设计任务

学会用已经学过的单片机原理与应用的知识,来设计一个实用性的结构简单化的小型电子产品。编写一个程序,实现秒计时器从00—59计时的基本功能。利用Proteus工具来演示秒计时器的计时。

1.2设计要求

利用MCS-51系列单片机作为秒表的主控制器芯片,在单片机的P0端口和P2端口分别接两个共阴数码管,P0口驱动显示秒时间的十位,P2口驱动显示秒时间的个位。要求做到性能稳定,结构简单通俗易懂,结构模块化,从而做到节约成本。

(1)熟悉电路,了解P0和P1口的作用。

(2)熟悉WAVE编译环境。

(3)熟练掌握汇编语言,调用延时程序。

2设计思想

2.1硬件设计

将单片机设计成控制器,在AT89C51的P0口和P2口都接7SEG-COM-CATHODE,P0口接上拉电阻,分别显示十位和个位数字。

2.2软件设计

通过单片机实现控制00-59的计数,根据设计的要求,将0到59的数据除以10,分别取商和余数。并且当一秒钟到来时,计数单元加1,到达60时,则自动返回到0,从新秒计数。同时在计数过程中调用延时程序。

3电路原理与电路图

3.1电路原理

编写程序对80C51芯片进行初始化,在编程过程中主要使用延迟程序来实现秒计时器的计时功能。用Proteus软件来实现秒计时器的仿真,其中将P0口和P1口分别作为高低位输出端口。

3.2电路原理图

图3.1电路原理图

4流程图与算法描述

4.1函数流程图

4.1.1实验系统流程图

 

图4.1.1 实验系统流程示意图

4.1.2延时程序流程图

 

图4.1.2 延时程序流程图

4.2 算法描述

根据设计的要求,利用单片机控制,实现秒计数并显示,具体设计如下:

(1)将0到59的数据通过对10整除和对10求余,将数据的个位和十位分开。

DIV    AB

(2)加1计数

   INC    @R0

(3)延时程序

DELAY:  MOV     R5,#100

DELAY2: MOV     R6,#20

DELAY1: MOV     R7,#248

          DJNZ    R7,$

          DJNZ    R6,DELAY1

          DJNZ    R5,DELAY2

5仿真分析

程序采用汇编语言编写,并用protues软件编译。用学校的Proteus软件画电路图和进行仿真。编译通过以后,用Proteus软件进行仿真和调试,把编译过后生成的hex文件加载到单片机中运行后就可以看到仿真的结果了。

测试数据及结果如下:

 

图5-1 运行的结果

6课程设计总结

6.1 设计体会

此次课程设计,我获益良多,在之前了解相关的单片机理论知识的基础上,通过自己的动手实践,理论与实践的结合使得对知识的理解更加深刻,并且慢慢学会培养自己的创新精神,感觉很有成就感,但同时我也认识到自己在单片机方面还有很多不足,尤其是单片机指令系统及AT89C51各引脚的第二功能等等知识不够熟练,因此在设计中遇到了很多不懂的知识,通过自己主动地查资料和请教老师及同学,这些问题也逐步得到解决。

设计过程中,刚开始着手设计时,虽然表面看上去很容易,不过实际也不是难题,可我还是没有一点头绪,之后花费了大量的时间和精力,同时得到老师和同学的帮助,才能顺利的完成课程设计,但还是存在一些小问题,需要进一步钻研和解决。设计时,不断调试程序和修改程序,提高了自己对单片机的应用能力,分析问题和解决问题的能力。在实践过程中陈老师和同学给了我很大的帮助和鼓励,借此机会向他们表达我的感激之情。.

6.2 存在问题与建议

通过这次课程设计我深刻的体会到了自己单片机知识的贫乏,编程时总是出现错误,导致我需要不断地翻书查阅资料。

在设计时,因能力有限,没有充分利用所学的理论知识,如果适当的对该设计增加功能,并对程序进行改进,就可以既允分利用资源,还可以充分节约资源,更适应市场的需求。

参考文献

[1] 李泉溪.单片机原理与实例仿真[M].北京:北京航空航天大学出版社,2009

[2] 江世明.基于Protues的单片机应用技术[M].北京:电子工业出版社,2009

[3] 沈永林.嵌入式单片机技术[M].北京:清华大学出版社,2007

[4] 常东超.C程序设计教程[M].北京::清华大学出版社,2009

附录(源程序清单)

ORG     0

        LJMP    START            ;启动指令

        ORG     30H              ;跳出中断入口

START:  MOV  P0,#0               ;将p0口清零

         MOV  P2,#0              ;将p2口清零

 MOV     @R0,#00        ;将值0赋给R0           

NEXT:   MOV     A,@R0          ;实现P0口从零到5的变化,以及P2口从零到九的变化

MOV     B,#10

        DIV     AB

        MOV     DPTR,#TABLE     ;建表

        MOVC    A,@A+DPTR     ;将表的首地址传给累加器A

        MOV     P0,A

        MOV     A,B

        MOVC    A,@A+DPTR

        MOV     P2,A

        LCALL   DELAY             ;调用延时程序

        INC     @R0

        MOV     A,@R0

        CJNE    A,#60,NEXT        ;比较循环     

        LJMP    START

DELAY:  MOV     R5,#100          ;延时程序

DELAY2: MOV     R6,#20

DELAY1: MOV     R7,#248

        DJNZ    R7,$

        DJNZ    R6,DELAY1

        DJNZ    R5,DELAY2

        RET

TABLE:  DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH

        END                   

相关推荐