资源描述
学校
嵌入式应用基础课程设计报告
基于AT89C51的篮球比赛计分器
课程设计
学 院:
学生姓名:
班 级:
学 号:
指导教师:
摘 要
随着单片机在各个领域的广泛应用,许多用单片机作控制的球赛计分器也应运而生,如用单片机控制LCD液晶显示器的计分器,用单片机控制LED七段显示器的计分器等等。
本次设计的篮球计分系统以AT89C51单片机为核心元件,通过七段共阴极LED来显示比分。采用CD4094(8位移位存贮总线寄存器)进行串行口扩展显示器接口,并利用74LS21(双四输入与门)来实现比分的刷新功能。
关键词:篮球计分器;AT89C51;显示;矩阵键盘;LED数码管
- 1 -
目 录
1前言 1
2系统方案设计 2
2.1 总体方案 2
2.1.1 设计内容 2
2.1.2 设计要求 2
2.2 系统组成 3
3 硬件设计 4
3.1 AT89C51的介绍 4
3.2 复位电路 4
3.3 键盘控制电路 5
3.4 显示电路 6
4 软件设计 8
4.1 主程序设计 8
4.2 键盘识别及处理程序设计 9
4.3 显示子程序设计 9
4.4 复位程序设计 10
5 系统调试 12
5.1 硬件接线及调试 12
6 总结 13
6.1 设计心得 13
参考文献 15
致 谢 16
附 录 17
- 1 -
1前言
体育比赛记分系统是对体育比赛过程中所产生的比分等数据进行快速采集记录,加工处理,传递利用的信息系统。根据不同运动项目的不同比赛规则要求,体育比赛的记分系统包括测量类,评分类,命中类,制胜类得分类等多种类型。
比如篮球比赛是根据运动队在规定的比赛时间里得分多少来决定胜负的,因此,篮球比赛的记分系统是一种得分类型的系统。篮球比赛的记分系统由计分器等多种电子设备组成,同时,根据目前高水平篮球比赛要求,完善的篮球比赛记分系统设备应能够与现场成绩处理,现场大屏幕,电视转播车等多种设备相联,以便实现高比赛现场感,表演娱乐观众等功能目标。
由于单片机的集成度高,功能强,通用性好,特别是它具有体积小,重量轻,能耗低,价格便宜,可靠性高,抗干扰能力强和使用方便等独特的优点,使单片机迅速得到了推广应用,目前已经成为测量控制应用系统中的优选机种和新电子产品的关键部位。世界各大电气厂家,测控技术企业,机电行业,竞相把单片机应用于产品更新,作为实现数字化,智能化的核心部件。篮球计分器就是以单片机为核心的计分系统。
- 1 -
基于AT89C51的篮球比赛计分器
2系统方案设计
2.1 总体方案
此计分器的设计采用模块化结构,主要由以下2个组成,即键盘模块、以及译码显示模块。以单片机为核心,配以一定的外围电路和软件,以实现比赛计分器的功能。它由硬件部分和软件部分组成。系统设计方案的硬件电路设计方框图如图2-1所示。
矩
阵 键 盘
89C51
甲显示器
乙显示器
图2-1 硬件电路设计方框图
2.1.1 设计内容
(1)给甲、乙两队分别设置加分按钮,各按钮按下分别实现给甲、乙队加1、2、3分。
(2)给甲、乙两队分别设置减分按钮,各按钮按下分别实现给甲、乙队减1、2、3分。
(3)设置一个复位按钮,按下实现甲、乙队总分回到初试分及显示
(4)预置分通过甲、乙两队加分按钮实现。
2.1.2 设计要求
(1)方案合理、正确,系统稳定、可靠。
(2)软件设计要求尽可能精练、简短和运行可靠。
(3)硬件电路要求简单明了,以节约成本。
2.2 系统组成
硬件电路由复位按钮、80C51单片机、矩阵键盘和8位共阴极LED显示器等组成。
软件部分主程序主要由系统初始化段、键盘识别、键值处理、8位共阴极LED显示器扫描显示子程序组成。
3 硬件设计
3.1 AT89C51的介绍
AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。AT89C2051是一种带2K字节闪烁可编程可擦除只读存储器的单片机。单片机的可擦除只读存储器可以反复擦除100次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C2051是它的一种精简版本。AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
3.2 复位电路
为确保微机系统中电路稳定可靠工作,复位电路是必不可少的一部分,复位电路的第一功能是上电复位。一般微机电路正常工作需要供电电源为5V±5%,即4.75~5.25V。由于微机电路是时序数字电路,它需要稳定的时钟信号,因此在电源上电时,只有当VCC超过4.75V低于5.25V以及晶体振荡器稳定工作时,复位信号才被撤除,微机电路开始正常工作。
目前为止,单片机复位电路主要有四种类型:
(1)微分型复位电路;
(2)积分型复位电路;
(3)比较器型复位电路;
(4)看门狗型复位电路
在此介绍一下看门狗型的复位电路:
看门狗型复位电路主要利用CPU正常工作时,定时复位计数器,使得计数器的值不超过某一值;当CPU不能正常工作时,由于计数器不能被复位,因此其计数会超过某一值,从而产生复位脉冲,使得CPU恢复正常工作状态。典型的看门狗型复位电路如图3-1所示:
图3-1 看门狗型复位电路
此复位电路的可靠性主要取决于软件设计,即将定时向复位电路发出脉冲的程序放在何处。一般设计,将此段程序放在定时器中断服务子程序中。然而,有时这种设计仍然会引起程序走飞或工作不正常。原因主要是:当程序“走飞”发生时定时器初始化以及开中断之后的话,这种“走飞”情况就有可能不能由看门狗复位电路校正回来。因为定时器中断一真在产生,即使程序不正常,看门狗也能被正常复位。为此提出定时器加预设的设计方法。即在初始化时压入堆栈一个地址,在此地址内执行的是一条关中断和一条死循环语句。在所有不被程序代码占用的地址尽可能地用子程序返回指令RET代替。这样,当程序走飞后,其进入陷阱的可能性将大大增加。而一旦进入陷阱,定时器停止工作并且关闭中断,从而使看门狗复位电路会产生一个复位脉冲将CPU复位。当然这种技术用于实时性较强的控制或处理软件中有一定的困难。
3.3 键盘控制电路
在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过一个按键加以连接。这样,一个端口(如P1口)就可以构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线就可以构成20键的键盘,而直接用端口线则只能多出一键(9键)。如图3-2所示。
图3-2 矩阵式键盘电路
需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O口作为输出端,而列线所接的I/O口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。具体的识别及编程方法如下所述。
矩阵式键盘的按键识别方法
确定矩阵式键盘上何键被按下介绍一种“行扫描法”。行扫描法行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。
判断键盘中有无键按下将全部行线Y0-Y3置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。
判断闭合键所在的位置在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
3.4 显示电路
显示器采用两个四位共阴极LED显示器,来实现显示器的动态扫描,八个二极管连接一个阴极的结构,只要另一段为高电平,二极管就会发光,从而形成一段。将八段顺序排列后就成为具有一定编码的共阴显示器了。动态扫描的频率有一定的要求,频率太低,LED将出现闪烁现象。如频率太高,由于每个LED点亮的时间太短,LED的亮度太低,肉眼无法看清,所以一般均取几个ms左右为宜,这就要求在编写程序时,选通某一位LED使其点亮并保持一定的时间,程序上常采用的是调用延时子程序。
4 软件设计
4.1 主程序设计
主程序主要由系统初始化段、开中断、键盘识别、键值处理、两个4位共阴极LED显示器扫描显示子程序和中断处理子程序等组成。通过对以上各段和子程序的结合,以实现系统功能。该系统主程序流程图如下图4-1所示。
开始
显示
键盘识别
键值
判断键值
a队 b队
对应处理减
对应处理加
对应处理加
对应处理减
显示
图4-1 主程序流程图
4.2 键盘识别及处理程序设计
按键识别及处理程序主要由键盘识别和键值处理组成。其中键盘识别子程序不断地对键盘进行判断是否有键按下。当有键按下时则转到键码处理即甲、乙总分处理子程序对相应按键进行相应处理,即可实现对甲、乙两队总分的计算与处理。
键盘识别即依次判断第一列、第二列、第三列、第四列是否有键按下。如果有键按下,先得出列,再反向赋值得出行,最后得出所在行和列的位置。
键值处理即先定义各按键,再对按键值进行保存,通过判断键值来判断分别对甲队或是乙队加减分,最后显示出甲队、乙队得分。甲、乙总分处理子程序流程图如下图4-2所示。
甲或乙
除以100
除以10
个位
十位
百位
商
商
余数
余数
商
余数
余数
除以100
除以10
图4-2 键值处理子程序流程图
4.3 显示子程序设计
由于该系统使用的是8位LED显示器显示计分器比分,因此显示采用动态扫描显示方法,即由显示器扫描显示子程序控制显示器逐个循环从左至右依次点亮各个显示器。这样虽然在任一时刻只要一个显示器点亮,但是由于人眼具有视觉残留效应,看起来与全部显示器持续点亮效果一样。显示器扫描显示子程序显示每一位用如图4-3所示流程方法完成。
从80C51的P1口送显示器位码
读相应位存储单元数据(中间两位显示“——”无此步)
由读得数据查表确定段码由80C51送相应显示器位
下一位显示
上一位显 示
图4-3 显示子程序流程图
4.4 复位程序设计
在矩阵键盘中设置相应的复位按键,当识别到复位按键按下时,执行复位程序。
在主程序运行过程中,只要系统识别到与单片机引脚相连的按键按下,程序则会转去执行复位程序,完成对甲、乙总分的清零,与此同时也就使显示器各位计数同时也清零,执行完毕后,返回主程序,等待识别下一个按键。流程图如4-4所示。
复位按键的存在,保证了计分器能的多次使用,当比赛结束后,通过按键复位到初始状态,继续进行下一场比赛。
开始
键值判断
按键按下
比分清零
返回
图4-4 复位程序流程图
5 系统调试
5.1 硬件接线及调试
接线是设计中最关键的一步,我的接线原则是从全局出发,逐个模块连接调试,最后总体调试。
逐个模块接线再调试,可以为总体调试省去很多时间,只要每个模块正常运行,几个模块通过地址总线连接之后,结果也就接近了。
调试前的直观检查:
检查连线是否正确,在通电之前应先检查一下电路的连线是否正确,包括错线,少线和多线的情况。根据课程设计的需求所写出的程序检查接线是否正确。这是一种以元件为中心进行查线的方法。把每个元件引脚的连线一次查清 ,检查每个接线处在程序中是否出现,这种方法不但可以查出错线和少线,还容易查处多线的情况。
在接线时应该注意数码管段选、片选连线的顺序,防止出现接反的状况,同时对矩阵键盘也要检查是否正确,是否能正常使用,是否按照实验要求的顺序接线。
2、元器件安装时情况
检查元、器见引脚之间有无短路;连接处有无接触不良。
模拟调试结果记录如下:通电后,显示器初始显示“000--000”。按照键盘分布说明按键,分布给甲、乙加1分、2分和3分,显示器跟踪显示出总分,然后模拟比赛细节,随意给甲、乙加分或是减分,均达到预期效果。在甲、乙均有一定总分的情况下对甲、乙进行减分处理,当减到0后便不能够再进行减分操作,与程序设计相符。在甲、乙均有一定总分的情况下,按清零按钮,显示结果清零。重复进行上面操作,结果均符合设计要求。
6 总结
6.1 设计心得
通过这次的课程设计,我对一些专业的电子设计有了更深的了解,同时也尝试着去应用自己所掌握的知识。这次课程设计主要是对电路的设计,对单片机开发板的应用,对相关应用软件的操作的一个综合性的考核。经过这次的课程设计,让我受益颇多,同时也明白自己还有很多的不足之处,明白自己应该在以后的学习生活中更加虚心学习,在学习生活中也不应该仅仅只是注重理论上的学习,结合本专业的情况而言,实践能力与理论知识是同等重要的。都说理论与实践相结合,理论源于实践,实践是理论的应用与发展,因此,我们更应该注重平时的实践能力,丰富自己,也丰富人生。
课程设计不仅给我们提供了一个很好的展现和应用自己所学知识的平台,而且给检验自己所学的知识和实现知识价值能力提供了一个机会。
在设计过程中不可避免的会遇到很多的问题,诸如接线问题、调试问题等,看似很简单的电路,要动手把它给设计出来,其实是一件十分不容易的事,主要原因是我们没有经常动手设计过电路,平时都是直接用查阅到的电路或者依靠书本,根本没有通过自己的努力去设计过电路。尤其是在最后调试部分,会因为各种原因而无法得到设计的结果,由于单片机系统的知识似懂非懂,而且很多知识当时弄明白了,现在要用的时候又不记得,造成需要花费大量的时间去重新查阅各种资料和程序命令,但一旦问题解决了,就会豁然开朗。
在这次课程设计中,我在整个设计过程中懂得了许多东西,也培养了独立思考和设计的能力,树立了对知识应用的信心,相信会对今后的学习工作和生活有非常大的帮助,并且提高了自己的动手实践操作能力, 使自己充分体会到了在设计过程中的成功喜悦。虽然这个设计做的并不是那么完美,但这是经过自己的努力得到的成功,想想也是知足的了,但是更加重要的是在设计过程中所学到的东西是这次课程设计的最大收获和财富。
通过本次课程设计我受益匪浅,不仅使我学会了用单片机编写程序的方法,而且对学过的相关知识得到了进一步的巩固和提高,通过阅读相关专业书籍掌握了一些曾经模糊的知识以及自己并未在课本上学到的知识;同时也熟悉了实验设备,对本专业的学习方案有了更深刻的认识,也让我明白了,我们专业是很重视学生的动手能力的,真正的实践能力会为我们带来很多意想不到的机会。更重要的是,在我学习和掌握这些知识的同时,能够在思维上得到提高和升华,提高了自己思维能力和对实验的热爱,让我觉得实验的方方面面都是十分有趣的。这次课程设计使我完善了知识结构、拓宽了知识面,开阔了眼界、提高了对各科知识综合应用的能力;同时也锻炼和培养了我的基本素质,它使我更加耐心、谨慎、细致。让我学会在以后的学习生活里应该以积极的态度面对困难,因为我知道,解决了困难的欣喜是无可替代的。
做任何事情其实需要的不仅仅是能力,更应有信心。只有自己相信了自己,别人才会相信你。这次课程设计其实本质上并不困难,看似很难的事,其实往往是我们把它夸大了。迎面面对生活中的挫折,坚强与努力,信心与勇气,最终会让一个人得到成功的果实的。这次的课程设计给我的不只是知识上的巩固与提升,也许让我学到的远远不是这些。
参考文献
[1] 许立梓.微型计算机原理及应用.北京:机械工业出版社,2002
[2] 刘乐善.微型计算机接口技术及应用.武汉:华中理工大学出版社,2000
[3] 邹逢兴.计算机硬件技术基础试验教程.北京:高等教育出版社,2000
[4] 周佩玲.16位微型计算机原理接口及其应用.北京:中国科学技术大学出版社,2000
[5] 吴秀清.微型计算机原理与接口技术.北京:中国科学技术出版社,2001
[6] 邓亚平.微型计算机接口技术.北京:清华大学出版社,2001
[7] 王迎旭.单片机原理及及应用.北京:机械工业出版社,2001
[8] 周航慈.单片机应用程序设计技术.北京:北京航空航天大学出版社,2002
[9] 谢宜仁.单片机实用技术问答.北京:人民邮电出版社,2002
致 谢
首先要感谢王克进老师对我的悉心指导,无论是在嵌入式的理论讲解中,还是在单片机实验课上,亦或是课程设计的过程中,都要谢谢老师的教导与帮助,使我学到了理论知识,锻炼了实践操作能力,培养了科学的思维,教会了我学习、思考的方法,对以后的学习、工作、生活产生了积极影响,谢谢老师!
同时,在这次课程设计中也要谢谢关心帮助我的同学们,谢谢大家的帮助,没有大家的相互探讨,就没有相互的促进与提高,正是在老师、同学的帮助下,成功的完成了课程设计。
还要感谢信息工程学院的诸位老师为我们提供了良好的设计条件,让我们顺利完成此次课程设计。
15
附 录
/*
PO控制连接段选,P2连接位选,P1连接矩阵键盘
矩阵键盘按下按键,数码管显示相应的数据
比赛开始后,初始状态为000--000
比赛结束后,可复位为000--000
*/
#include<reg51.h>
sbit key = P1; // P1连接矩阵键盘
void LED(); //数码管显示
void kaishi(); //开始或复位
void exchange(); //交换得分
void guan(); //关闭
void jixu(); //继续
void ajian(int t); // a-t
void bjian(int t); // b-t
void delay(unsigned int i); //延时程序
unsigned char keyscan(void); //矩阵键盘扫描
unsigned int a,b,m;
unsigned charj[16]={0x7e,0x7d,0x7b,0x77,0xbe,0xbd,0xbb,0xb7,0xde,
0xdd,0xdb,0xd7,0xee,0xed,0xeb,0xe7}; //键值
unsigned char Disp_Tab[]={0x3f,0x06,0x5b,0x4f,0x66,
0x6d,0x7d,0x07,0x7f,0x6f,0x40}; //段选
unsigned char dispbit[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdF,0xbF,0x7F}; //位选
main()
{ a=0;b=0;m=0;
while (1)
{
unsigned key;
LED(); // 显示数码管
key=keyscan();//调用键盘扫描,
switch (key)
{
case 0x7e: a=a+1;LED(); break; //a队加1
case 0x7d: a=a+2;LED(); break; /a队加2
case 0x7b: a=a+3;LED(); break; //a队加3
case 0x77: a=0;b=0;kaishi(); break; // 复位
case 0xbe: ajian(1);LED(); break; //a队减1
case 0xbd: ajian(2);LED(); break; //a队减2
case 0xbb: ajian(3);LED(); break; //a队减3
case 0xb7: jixu(); break; // 暂停,继续
case 0xde : b=b+1;LED(); break; //b队加1
case 0xdd: b=b+2;LED(); break; //b队加2
case 0xdb: b=b+3;LED(); break; //b队加3
case 0xd7: exchange();LED(); break; //交换比分
case 0xee: bjian(1);LED(); break; //b队减1
case 0xed: bjian(2);LED(); break; //b队减2
case 0xeb: bjian(3);LED(); break; //b队减3
case 0xe7:guan(); break; //关闭
}
}
}
void kaishi()
{
m=1;
LED();
}
void ajian(int t)
{
if(a>=t)
{a=a-t; }
}
void bjian(int t)
{
if(b>=t)
{b=b-t; }
}
void jixu()
{
m=!m;
LED();
}
void guan()
{
m=0;
LED();
}
void exchange ()
{
unsigned int i;
i=a;
a=b;
b=i;
}
void LED()
{
unsigned int i,d,LedNumVal=1 ; //变量定义
unsigned int LedOut[10]; //变量定义
unsigned int DelayCNT=0;
for(d=0;d<30;d++)
{
if(++DelayCNT>=20) //控制数字变化速度
{
DelayCNT=0; //20个扫描周期清零一次
}
if(m==1)
{ LedOut[2]=Disp_Tab[a/100];
LedOut[1]=Disp_Tab[a%100/10];
LedOut[0]=Disp_Tab[a%10];
LedOut[3]=0x40;
LedOut[4]=0x40;
LedOut[7]=Disp_Tab[b/100];
LedOut[6]=Disp_Tab[b%100/10];
LedOut[5]=Disp_Tab[b%10];
}
if(m==0)
{
LedOut[0]=0x40;
LedOut[1]=0x40;
LedOut[2]=0x40;
LedOut[3]=0x40;
LedOut[4]=0x40;
LedOut[5]=0x40;
LedOut[6]=0x40;
LedOut[7]=0x40;
}
for( i=0; i<9; i++)
{
P0 = LedOut[i]; //P0控制段选
switch(i) //使用switch 语句控制位选
{
case 0:P2 = 0x7F; break;
case 1:P2 = 0xbF; break;
case 2:P2 = 0xdF; break;
case 3:P2 = 0xeF; break;
case 4:P2 = 0xf7; break;
case 5:P2 = 0xfb; break;
case 6:P2 = 0xfd; break;
case 7:P2 = 0xfe; break;
}
delay(150); //扫描间隔时间 太长会数码管会有闪烁感
}
}
}
void delay(unsigned int i)
{
char j;
for(i; i > 0; i--)
for(j = 200; j > 0; j--);
}
unsigned char keyscan(void)//键盘扫描函数,使用行列反转扫描法
{
unsigned char cord_h,cord_l;//行列值
P1=0x0f; //行线输出全为0
cord_h=P1&0x0f; //读入列线值
if(cord_h!=0x0f) //先检测有无按键按下
{
delay(20); //去抖
if(cord_h!=0x0f)
{
cord_h=P1&0x0f; //读入列线值
P1=cord_h|0xf0; //输出当前列线值
cord_l=P1&0xf0; //读入行线值
return(cord_h+cord_l);//键盘最后组合码值
}
}return(0xff); //返回该值
}
6
展开阅读全文