点击链接获取Keil源码与Project Backups仿真图:
https://download.csdn.net/download/qq_64505944/87778138?spm=1001.2014.3001.5503
源码获取
主要内容:
比赛的计分和计时的工具大多是很简陋的比分牌,十分的不方便。而且大多由于缺少24秒的倒计时,控球时间计时不是很准确。我开发的这个系统原料简单,按键功能强大,计时准确,流动性强,非常适合于学校的篮球比赛等对于计时要求比较高的地方。
基本要求:
(1)篮球比赛上下半场各20分钟,要求能随时暂停,启动后继续计时,一场比赛结束后应可清零重新开始比赛。
(2)计时器由分、秒计数器完成,秒计数器为模60,分计数器能计至40分钟。
(3)“分”、“秒”显示用LED数码管,应配用相应译码器。
(4)用按钮开关控制计时器的启动/暂停。
(5)半场、全场到自动音响提示,用按钮开关关断声音。
主要参考资料:
【1】胡汉才.单片机原理及系统设计.清华大学出版社.2002.
【2】张华主编.电类专业毕业设计指导.机械工业出版社.2001.
【3】彭为等编著.单片机典型系统设计实例精讲.电子工业出版社2006.
【4】何立民.单片机应用系统设计.北京航空航天大学出版社.1994.
【5】邵敏权主编.单片计算机原理实验及应用技术.吉林科学技术出版社.1995.
完 成 期 限:12 月 11 日 - 12 月 26 日
指导教师签名:
课程负责人签名:
摘 要
体育比赛计时计分系统是对体育比赛过程中所产生的时间、比分等数据进行快速采集记录,加工处理,传递数据的信息系统。它负责比照赛的结果和成绩信息进行采集处理、传输分配。篮球比赛的计时计分系统由计时器、计分器等多种电子设备组成,根据目前高水平篮球比赛要求,完善的篮球比赛计时计分系统设备应能够与现场成绩处理、现场大屏幕、电视转播车等多种设备相联,以便实现高比赛现场感、表演娱乐观众等功能目标。比赛具有的不可重复性,决定了篮球计时计分系统是一个实时性很强、可靠性要求极高的电子效劳系统,所以计时计分设备是篮球比赛中不可缺少的电子设备
单片机自20世纪70年代问世以来,以极其高的性价比受到人们的重视和关注所以应用很广,开展很快。目前已经成为测量控制应用系统中的优选机种和新电子产品的关键部位。世界各大电气厂家,测控技术企业,机电行业,竞相把单片机应用于产品更新,作为实现数字化,智能化的核心部件。篮球计时计分器就是以单片机为核心的计时计分系统,由计时器,计分器,综合控制器和24秒控制器等组成模块化设计系统,分为计时显示模块、计分显示模块、定时报警、按键控制键盘模块。模块的程序结构简单、易于编写、任务明确、调试和修改。程序可读性好对程序的修改可局部进行,其他局部可保持不变。编程后利用Keil软件来进行编译将生成的HEX文件装入芯片中,采用Proteus软件仿真,检验功能是否正常,然后用Protel99画硬件的电路图。本设计中系统硬件电路主要有以下几个局部: 单片机AT89C51、计时电路、计分电路、报警电路和按键开关。
本次设计用由AT89C51编程控制LED七段数码管作显示的球赛计时计分系统该系统具有赛程定时设置、赛程时间暂停、及时刷新甲乙双方的成绩以及赛后成绩暂存等功能。具有价格低廉、性能稳定、操作方便并且易于携带等特点,适用于各种公司学校等中小企业
关 键 词:AT89C51、LED显示器、计时计分器
目录
摘 要 Ⅲ
第一章 前言 1
第二章 芯片及特性 2
2.1设计要求 2
2.2 AT89C51芯片介绍 2
第三章 设计方案及可行性 4
3.1设计原理: 4
3.2程序设计难点分析: 4
3.3红外解码模块分析: 4
第四章 硬件设计及仿真结果 11
4.1硬件设计: 11
4.2 Proteus仿真: 11
第五章 结 论 13
源程序代码及注释: 14
参考文献 28
第一章 前言
随着体育活动越来越多的受到人们的重视,篮球比赛也被很多青少年所喜爱。比赛的计分和计时的工具大多是很简陋的比分牌,十分的不方便。而且大多由于缺少24秒的倒计时,控球时间计时不是很准确。我开发的这个系统原料简单,按键功能强大,计时准确,流动性强,非常适合于学校的篮球比赛等对于计时要求比较高的地方。单片机主要用于控制,它的应用领域遍及各行各业,大到航天飞机,小至日常生活中的冰箱、彩电,单片机都可以大显其能。单片机将微处理器、存储器、定时/计数器、I/O接口电路等集成在一个芯片上的大规模集成电路,本身即是一个小型化的微机系统。单片机技术与传感与测量技术、信号与系统分析技术、电路设计技术、可编程逻辑应用技术、微机接口技术、数据库技术以及数据结构、计算机操作系统、汇编语言程序设计、高级语言程序设计、软件工程、数据网络通信、数字信号处理、自动控制、误差分析、仪器仪表结构设计和制造工艺等的结合,使得单片机的应用非常广泛。
根据课题要求,介绍一种篮球赛计时计分器的设计方法,即单片机带外围扩展来驱动数码管工作的电路。电路的核心元件为单片机,用10个7段共阴极LED数码管作为显示器。4个用于记录赛程时间,2个用于显示分钟,2个用于显示秒钟。6个用于记录甲、乙两队的比赛分数,每队3个,显示分数范围可达0999分,足够比赛中得分的现实的需求。比赛前,将时间设置好,比赛开始时启动计时,直至倒计时到零为止。计时范围到达0 99分钟,能满足实际赛程计时的需求。为了配合计时器调整时间和计分器校正比分,设计了7个按键,3个用于启动和暂停赛程时间。4个用于输入甲、乙两队的分数,另外,还设计了定时报警系统即比赛时间到时,扬声器发出报警声提示比赛结束该系统具有赛程定时设置,赛程时间暂停,及时刷新甲、乙双方的成绩以及赛后成绩暂存等功能。设计分为软件设计和硬件设计两局部。主控芯片采用AT89C51,使用汇编语言编写软件程序,主体分为计时显示模块、计分显示模块定时报警、按键控制模块。编程后利用Keil C51软件来进行编译,再将生成的HEX文件装入芯片中,采用Proteus软件来仿真,检验功能是否能够正常实现,随后可用Protel99画出硬件电路图。
通过本次基于单片机的篮球赛计时计分器的设计,可以了解有关单片机开发设计实例的过程,加深对单片机的理解和应用以及掌握单片机与外围接口的方法和技巧。
第二章 芯片及特性
2.1设计要求
(1)篮球比赛上下半场各20分钟,要求能随时暂停,启动后继续计时,一场比赛结束后应可清零重新开始比赛。
(2)计时器由分、秒计数器完成,秒计数器为模60,分计数器应能计至40分钟。
(3)“分”、“秒”显示用LED数码管,应配用相应译码器。
(4)用按钮开关控制计时器的启动/暂停。
(5)半场、全场到自动音响提示,用按钮开关关断声音。
2.2 AT89C51芯片介绍
AT系列单片机是美国ATMEL公司在IntelMCS-51单片机技术基础上开发出的一种新产品,片内带有4k E2ROM,编程/擦除全部采用电实现(有5V和12V两种模式),既能进行在线编程擦写,亦可采用电话线进行远程编程擦写。可重复性强,使用寿命长,可重复擦写 1000次以上,并且擦写速度快,4k编程大约需3s,擦除仅需10ms。程序保存时间长,可达100年,与IntelMCS-51系列单片机完全兼容,且有超强的加密功能,能完全替代IntelMCS-8751/Intel MCS-8752和Intel MCS-87C51/Intel MCS-87C52,低电压,低电流,低功耗,除了有DIP、PLCC、QFP等多种封装形式,还有商用级、工业级、汽车用级、军用级等多种规格。因此,目前它在微计算机产品开发中的应用越来越“火”。
AT89C51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。 由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,为很多嵌入式控制系统提 供了一种灵活性高且价廉的方案。
图2-1 AT89C51芯片
第三章 设计方案及可行性
3.1设计原理:
主函数,识别是否有红外遥控按键按下,一直保持循环。如果有按键按下,去执行按键检测。
为了实现篮球计分器的功能,左边两个数码管和右边两个数码管要分别计数。
因为是四个数码管的不同显示,需要用到四个不同的存储单元存放要显示的数字。
遥控信号的发送和解码由相应的解码程序来完成,按键识别后,分别执行不同的功能函数(这是我们主要要完成的)。
以按键一功能函数为例,甲队加一分,那么就需要在第二个数码管上的数字显示加一,当计数到10时,置零,第一位数码管显示加一。
此外,在LED显示程序和数码管显示程序都放在显示函数中。按键功能执行函数执行完毕,会把相应的数码管显示和LED显示相应存储单元内容刷新,然后调用显示函数。
3.2程序设计难点分析:
1、精确的延时,没有精确的延时,无法对遥控发送的信号进行解码,这是编写C程序比较困难的一部分。
2、四位数码管的显示,以多少的频率刷新,让人才能看起来同时显示四个不同的值。
3、按键识别后,对四个存储单元内容的操作(数据传送,加法,转移指称,判断等等)。
4、按键按下后,对应的发光二极管亮;比较比分的数值,led7和led8分别亮。
5、没有精确的延时,无法对遥控发送的信号进行解码,这是编写C程序比较困难的一部分。另外,除了延时,还需要很多的位操作指令,所以解码函数用C语言写非常复杂。
3.3红外解码模块分析:
3.3.1编码方式:
采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”,其波形如图2所示。
图2 遥控码的“0”和“1” (注:所有波形为接收端的与发射相反)
上述“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制以提高发射效率,达到降低电源功耗的目的。然后再通过红外发射二极管产生红外线向空间发射,如图3所示。
图3 遥控信号编码波形图
UPD6121G产生的遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的电器设备,防止不同机种遥控码互相干扰。该芯片的用户识别码固定为十六进制01H;后16位为8位操作码(功能码)及其反码。UPD6121G最多额128种不同组合的编码。
遥控器在按键按下后,周期性地发出同一种32位二进制码,周期约为108ms。一组码本身的持续时间随它包含的二进制“0”和“1”的个数不同而不同,大约在45~63ms之间,图4为发射波形图。
图4 遥控连发信号波形
当一个键按下超过36ms,振荡器使芯片激活,将发射一组108ms的编码脉冲,这108ms发射代码由一个引导码(9ms),一个结果码(4.5ms),低8位地址码(9ms18ms),高8位地址码(9ms18ms),8位数据码(9ms18ms)和这8位数据的反码(9ms18ms)组成。如果键按下超过108ms仍未松开,接下来发射的代码(连发码)将仅由起始码(9ms)和结束码(2.25ms)组成。
图5 引导码 图6连发码
3.3.2红外信号的接收:
接收电路可以使用一种集红外线接收和放大于一体的一体化红外线接收器,不需要任何外接元件,就能完成从红外线接收到输出与TTL电平信号兼容的所有工作,而体积和普通的塑封三极管大小一样,它适合于各种红外线遥控和红外线数据传输。
接收器对外只有3个引脚:Out、GND、Vcc与单片机接口非常方便,如图7所示。
图7
① 脉冲信号输出,直接接单片机的IO 口。
② GND接系统的地线(0V);
③ Vcc接系统的电源正极(+5V);
3.3.4解码程序:
ORG 0000H
MAIN:
JNB P2.2,IR ;遥控扫描
LJMP MAIN ;在正常无遥控信号时,一体化红外接收头输出是高电平,程序一直在循环。
;=================================================
; 解码程序
IR:
;以下对遥控信号的9000微秒的初始低电平信号的识别,波形见图5。
MOV R6,#10
IR_SB:
ACALL DELAY882 ;调用882微秒延时子程序
JB P2.2,IR_ERROR ;延时882微秒后判断P2.2脚是否出现高电平如果有就退出解码程序
DJNZ R6,IR_SB ;重复10次,目的是检测在8820微秒内如果出现高电平就退出解码程序
;识别连发码,和跳过4.5ma的高电平。
JNB P2.2, $ ;等待高电平避开9毫秒低电平引导脉冲
ACALL DELAY2400
JNB P2.2,IR_Rp ;这里为低电平,认为是连发码信号,见图6。
ACALL DELAY2400 ;延时4.74毫秒避开4.5毫秒的结果码
;以下32数据码的读取 ,0和1的识别 请看图2
MOV R1,#1AH ;设定1AH为起始RAM区
MOV R2,#4
IR_4BYTE:
MOV R3,#8
IR_8BIT:
JNB P2.2,$ ;等待地址码第一位的高电平信号
LCALL DELAY882 ;高电平开始后用882微秒的时间尺去判断信号此时的高低电平状态
MOV C,P2.2 ;将P2.2引脚此时的电平状态0或1存入C中
JNC IR_8BIT_0 ;如果为0就跳转到IR_8BIT_0
LCALL DELAY1000
IR_8BIT_0:
MOV A,@R1 ;将R1中地址的给A
RRC A ;将C中的值0或1移入A中的最低位
MOV @R1,A ;将A中的数暂时存放在R1中
DJNZ R3,IR_8BIT ;接收地址码的高8位
INC R1 ;对R1中的值加1,换下一个RAM
DJNZ R2,IR_4BYTE ;接收完16位地址码和8位数据码和8位数据,
;存放在1AH/1BH/1CH/1DH的RAM中
;解码成功
JMP IR_GOTO
IR_Rp:
;这里为重复码执行处
;按住遥控按键时,每过108ms就到这里来
JMP IR_GOTO
IR_ERROR:
;错语退出
LJMP MAIN ;退出解码子程序
;=================================================
;遥控执行部份
IR_GOTO:
;这里还要判断1AH和1BH 两个系统码或用户码,用于识别不同的遥控器
;MOV A,1AH
;CJNE A,#xxH,IR_ERROR ;用户码1不对则退出
;MOV A,1BH
;CJNE A,#xxH,IR_ERROR ;用户码2不对则退出
;判断两个数据码是否相反
MOV A,1CH
CPL A
CJNE A,1DH,IR_ERROR ;两个数据码不相反则退出
;遥控执行部份
;MOV A,1DH ;判断对应按键
;CJNE A,#xxH,KaTeX parse error: Expected 'EOF', got '#' at position 40: …处 ;CJNE A,#̲xxH,+6
;LJMP -à跳到对应按键执行处
;.
MOV P1,1DH ;将按键的键值通过P1口的8个LED显示出来!
CLR P2.3 ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功
LCALL DELAY2400
LCALL DELAY2400
LCALL DELAY2400
SETB P2.3 ;蜂鸣器停止
;清除遥控值使连按失效
MOV 1AH,#00H
MOV 1BH,#00H
MOV 1CH,#00H
MOV 1DH,#00H
LJMP MAIN
;=================================================
; 延时子程序
;=============================882
DELAY882: ;1.085x ((202x4)+5)=882
MOV R7,#202
DELAY882_A:
NOP
NOP
DJNZ R7,DELAY882_A
RET
;=============================1000
DELAY1000: ;1.085x ((229x4)+5)=999.285
MOV R7,#229
DELAY1000_A:
NOP
NOP
DJNZ R7,DELAY1000_A
RET
;=============================2400
DELAY2400: ;1.085x ((245x9)+5)=2397.85
MOV R7,#245
DELAY2400_A:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,DELAY2400_A
RET
END
第四章 硬件设计及仿真结果
4.1硬件设计:
(1)红外接收与解码模块
通用红外遥控系统由发射和接收两大部分组成。应用编/解码专用集成电路芯片来进行控制操作,如图1所示。发射部分包括键盘矩阵、编码调制、LED红外发送器;接收部分包括光、电转换放大器、解调、解码电路。
(2)数码管显示
JD51上有四位共阳LED数码管,其标号分别为LED1—LED4,低电平选通,且任何时候仅有一位输出低电平,显示时对各显示器进行动态扫描,显示器分时轮流工作。虽然每次只有一个显示器显示,但是由于人的视觉暂留现象我们仍会感觉所有的显示器都在同时显示。
(3)LED灯显示
P0口作为输出口控制8个发光二极管的亮灭,控制数码管的显示。
4.2 Proteus仿真:
4.2.1遇到的问题:
在电路连接上遇到的问题主要就是proteus不提供红外遥控器这个外设,所以就需要自己去解决红外编码、解码、发射的问题,对于初学proteus的人来说较为复杂。
4.2.2解决方案:
(1)方案一:
另使用一块51单片机,外设使用按键矩阵。对其编程使其实现按对应的按键,使单片机可以模拟输出对应红外编码的信号。
(2)方案二:
对proteus仿真电路进行结构改变,不使用红外接收信号,在此使用按键直接对单片机进行操作,替代红外的功能。加入比赛计时功能,并根据网上的资料加入比分互换、比赛暂停、减一分、时间复位、时间加减等按键。
4.2.3软件设计及实现
主程序流程图设计:
软件框架设计:
(1)主函数:
识别是否有红外遥控按键按下,一直保持循环;
按键解码程序:判断遥控器上不同的按键按下;
(2)按键功能执行函数:
每个按键对应的功能不同,需要编写不同的函数实现,比如按键1,是使第二个数码管显示的内容加一,那么执行功能函数即让存储第二个数码管显示内容的单元数值加一;
(3)显示函数:
循环调用显示函数,让数码管显示不同的计分数值,相应的LED灯显示。
第五章 结 论
本文介绍了一个利用AT89C52设计篮球计时计分器的设计。文章对计时计分器的组成结构和设计部分的元件功能做了详细的介绍。通过这次期末课程设计,让我学到了许多没有学到的知识,增强了自己的独立思考能力和实际动手能力,特别是一些专业性很强的知识和老师们的一些工作经验让我受益匪浅,这是我在短时间内都不能学到的。对所学的知识进行了一次综合的总结和运用,在写作过程中,使我在排版方面和绘画电路图方面得到了进一步提升。但由于本人知识水平有限,还存在很多错误与不足之处,望老师多提宝贵意见,多加批评指点。
源程序代码及注释:
1、汇编代码:
ORG 0000H
MOV 2AH,#00 //四个用于保存目前甲乙队得分的个十位数
MOV 2BH,#00
MOV 2CH,#00
MOV 2DH,#00
ORG 30H
START: SETB P2.5 //打开74HC573锁存使能
MOV 1AH,#00H //四个用于读入红外信号
MOV 1BH,#00H
MOV 1CH,#00H
MOV 1DH,#00H
MAIN:
LCALL DISPLAY
JNB P3.2,IR //一旦红外收到低电平,跳转至开始读入红外数据
LJMP MAIN
DISPLAY:
LEDR1:
SETB P2.3
MOV DPTR,#TAB
MOV A,2AH
MOVC A,@A+DPTR
CLR P2.0
MOV P0,A
LCALL DELAY
LEDR2:
SETB P2.0 //熄灭第一个数码管
MOV DPTR,#TAB //指针指向TAP
MOV A,2BH //将甲队得分个位数存入a
MOVC A,@A+DPTR //让a通过变址寻址得到a对应数的数码管编码
CLR P2.1 //点亮第二个数码管
MOV P0,A //将数据写入数码管
LCALL DELAY //延时让数码管保持亮一段时间
LEDR3:
SETB P2.1
MOV DPTR,#TAB
MOV A,2CH
MOVC A,@A+DPTR
CLR P2.2
MOV P0,A
LCALL DELAY
LEDR4:
SETB P2.2
MOV DPTR,#TAB
MOV A,2DH
MOVC A,@A+DPTR
CLR P2.3
MOV P0,A
LCALL DELAY
COM:MOV A,2AH
CLR C
SUBB A,2CH
JZ COM1 //累加器为0十位相等
JNC LED7 //不存在借位,则甲队领先
MOV P1,#01111111B //乙队领先
RET
LED7:
MOV P1,#10111111B
RET
COM1: //比较个位
MOV A,2BH
CLR C
SUBB A,2DH
JZ COM2 //累加器为0,个位也相等
JNC LED7 //不存在借位,则甲队领先
MOV P1,#01111111B
COM2:MOV P1,#11111111B //无人领先二极管全部熄灭
RET
DELAY: MOV R5,#2
D2:MOV R4,#10
D1:DJNZ R4,D1
DJNZ R5,D2
RET ;延迟40微秒
IR:
;以下对遥控信号的9000微秒的初始低电平信号的识别
MOV R6,#8
IR_SB:
ACALL DELAY882 ;调用882微秒延时子程序
JB P3.2,IR_ERROR ;延时882微秒后判断P2.2脚是否出现高电平如果有就退出解码程序
DJNZ R6,IR_SB ;重复10次,目的是检测在8820微秒内如果出现高电平就退出解码程序
;识别连发码,和跳过4.5ma的高电平。
JNB P3.2, $ ;等待高电平避开9毫秒低电平引导脉冲
ACALL DELAY2400
JNB P3.2,IR_Rp ;这里为低电平,认为是连发码信号。
ACALL DELAY2400 ;延时4.74毫秒避开4.5毫秒的结果码
;以下32数据码的读取 ,0和1的识别
MOV R1,#1AH ;设定1AH为起始RAM区
MOV R2,#4
IR_4BYTE:
MOV R3,#8
IR_8BIT:
JNB P3.2,$ ;等待地址码第一位的高电平信号
LCALL DELAY882 ;高电平开始后用882微秒的时间尺去判断信号此时的高
;电平状态
MOV C,P3.2 ;将P2.2引脚此时的电平状态0或1存入C中
JNC IR_8BIT_0 ;如果为0就跳转到IR_8BIT_0
LCALL DELAY1000
IR_8BIT_0:
MOV A,@R1 ;将R1中地址的给A
RRC A ;将C中的值0或1移入A中的最低位
MOV @R1,A ;将A中的数暂时存放在R1中
DJNZ R3,IR_8BIT ;接收地址码的高8位
INC R1 ;对R1中的值加1,换下一个RAM
DJNZ R2,IR_4BYTE ;接收完16位地址码和8位数据码和8位数据,
;存放在1AH/1BH/1CH/1DH的RAM中
;解码成功
JMP IR_GOTO
IR_Rp:
;这里为重复码执行处
;按住遥控按键时,每过108ms就到这里来
JMP IR_GOTO
IR_ERROR:
;错误退出
LCALL DISPLAY
LJMP MAIN ;退出解码子程序
;=================================================
;遥控执行部份
IR_GOTO:
;判断两个数据码是否相反
MOV A,1CH
CPL A
CJNE A,1DH,IR_ERROR ;两个数据码不相反则退出
;将按键的键值通过P1口的8个LED显示出来!
CLR P2.4 ;蜂鸣器鸣响-嘀嘀嘀-的声音,表示解码成功
LCALL DELAY2400
LCALL DELAY2400
LCALL DELAY2400
SETB P2.4 ;蜂鸣器停止
LCALL JZPD //跳入判断键值
LCALL DISPLAY
LCALL DISPLAY
;清除遥控值使连按失效
MOV 1AH,#00H
MOV 1BH,#00H
MOV 1CH,#00H
MOV 1DH,#00H
LJMP MAIN
;键值判断
JZPD: MOV A,1DH
IRD0: CJNE A,#0E9H,IRD1 //按键"0"判断显示,不是则跳转判断是否为1
MOV 2AH,#00
MOV 2BH,#00
MOV 2CH,#00
MOV 2DH,#00 //四个数值存储单元内容清零
RET
IRD1: CJNE A,#0F3H,IRD2 //按键"1"判断显示,不是就跳转判断是否为2
INC 2BH //甲队分数个位加一
MOV A,2BH
CLR C //清除借位标志位
SUBB A,#10
JZ ZL1 //a为0跳转
JNC ZW1 //c为0则跳转,即不存在借位
MOV P1,#11111110B //二极管1亮起
LCALL DELAY2400
RET
IRD2: CJNE A,#0E7H,IRD3 //按键"2"判断显示
INC 2BH
INC 2BH
MOV A,2BH
CLR C
SUBB A,#10
JZ ZL1
JNC ZW1
MOV P1,#11111101B
LCALL DELAY2400
RET
IRD3: CJNE A,#0A1H,IRD4 //按键"3"判断显示
INC 2BH
INC 2BH
INC 2BH
MOV A,2BH
CLR C
SUBB A,#10
JZ ZL1
JNC ZW1
MOV P1,#11111011B
LCALL DELAY2400
RET
ZL1:MOV 2BH,#00 //此时刚好进位,相当于甲队个位分数清零,向前进位
INC 2AH
RET
ZW1:MOV 2BH,A //此时刚好进位,且进为后个位不为0相当于甲队个位分数清零,向前进位
INC 2AH
RET
IRD4: CJNE A,#0F7H,IRD5 //按键"4"判断显示
INC 2DH
MOV A,2DH
CLR C
SUBB A,#10
JZ ZL2
JNC ZW2
MOV P1,#11110111B
LCALL DELAY2400
RET
IRD5: CJNE A,#0E3H,IRD6 //按键"5"判断显示
INC 2DH
INC 2DH
MOV A,2DH
CLR C
SUBB A,#10
JZ ZL2
JNC ZW2
MOV P1,#11101111B
LCALL DELAY2400
RET
IRD6: CJNE A,#0A5H,IRDEND //按键"6"判断显示
INC 2DH
INC 2DH
INC 2DH
MOV A,2DH
CLR C
SUBB A,#10
JZ ZL2
JNC ZW2
MOV P1,#11011111B
LCALL DELAY2400
RET
IRDEND:
RET //键值读取函数结束
ZL2:MOV 2DH,#00
INC 2CH
RET
ZW2:MOV 2DH,A
INC 2CH
RET
;=================================================
; 延时子程序
;=============================882
;1.085x ((202x4)+5)=882
DELAY882:
MOV R7,#202
DELAY882_A:
NOP
NOP
DJNZ R7,DELAY882_A
RET
;=============================1000
;1.085x ((229x4)+5)=999.285
DELAY1000:
MOV R7,#229
DELAY1000_A:
NOP
NOP
DJNZ R7,DELAY1000_A
RET
;=============================2400
;1.085x ((245x9)+5)=2397.85
DELAY2400:
MOV R7,#245
DELAY2400_A:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
DJNZ R7,DELAY2400_A
RET
TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;共阳数码管的不带小数点的时间显示码分别代表0~9
END
2、C语言代码:
#include<reg52.h>
#define uchar unsigned char
unsigned char code table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0x0F8,0x80,0x90}; //数码管显示
uchar dispbuf[4]={0,0,0,0};//用于记录比分
uchar databuf[4]={0,0,0,0};//红外读入四组信号
void delay(unsigned char m);//延迟函数
void display(); //显示函数
void detect(); //红外读数据函数
void IR_goto(); //按键功能操作
sbit P32=P3^2;
sbit P25=P2^5;
void main()
{
P2=0x10; //打开74HC573锁存使能
display();//调用显示函数
while(1)
{
if(!P32) detect();//一直循环直到读到红外信号
display();
}
}
void display()
{
unsigned char dispdata; //数值数据
unsigned char i,j=0xFE; //j=11111110 让四个数码管循环显示
for(i=0;i<4;i++)
{
P2=j;
dispdata=dispbuf[i];
P0=table[dispdata];//显示数码管的数字
delay(200);//延时
j=(j<<1)|0x01; //j位左移与00000001或
if(j==0xEF)j=0xFE;
}
if(dispbuf[0]>dispbuf[2])
P1=0xBF; //甲队领先
else if(dispbuf[0]==dispbuf[2])
if(dispbuf[1]>dispbuf[3])
P1=0xBF; //甲队领先
else if(dispbuf[1]==dispbuf[3])
P1=0xFF; //平手
else
P1=0x7F; //乙队领先
else P1=0x7F; //乙队领先
}
void detect() //读取红外模块
{
uchar i;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return;
delay(250);
if(P32) return; //一旦有高电平则退出
while(!P32) {} //等到p32是高电平,否则一直循环避开9ms脉冲
delay(250);
delay(250);
delay(250);
delay(250);
delay(200); //延时约4.5
if(!P32) //低电平认为是连发码
{
IR_goto();
display();
return;
}
delay(250);
delay(250);
delay(250);
delay(250);
delay(200); //延时约4.5避开结果码
while(!P32) {} //等待第一位高电平信号
for(i=0;i<4;i++) //以下为4组数据码读取
{
while(!P32) {}
delay(210);
delay(210);
if(P32)
{
databuf[i]=databuf[i]|0x01;
delay(250);
delay(250);
}
else
databuf[i]=databuf[i]&0xFE;
while(!P32) {}
delay(210);
delay(210);
if(P32)
{
databuf[i]=databuf[i]|0x02;
delay(250);
delay(250);
}
else
databuf[i]=databuf[i]&0xFD; //
while(!P32) {}
delay(210);
delay(210);
if(P32)
{
databuf[i]=databuf[i]|0x04;
delay(250);
delay(250);
}
else
databuf[i]=databuf[i]&0xFB; //
while(!P32) {}
delay(210);
delay(210);
if(P32)
{
databuf[i]=databuf[i]|0x08;
delay(250);
delay(250);
}
else
databuf[i]=databuf[i]&0xF7; //
while(!P32) {}
delay(210);
delay(210);
if(P32)
{
databuf[i]=databuf[i]|0x10;
delay(250);
delay(250);
}
else
databuf[i]=databuf[i]&0xEF; //
while(!P32) {}
delay(210);
delay(210);
if(P32)
{
databuf[i]=databuf[i]|0x20;
delay(250);
delay(250);
}
else
databuf[i]=databuf[i]&0xDF; //
while(!P32) {}
delay(210);
delay(210);
if(P32)
{
databuf[i]=databuf[i]|0x40;
delay(250);
delay(250);
}
else
databuf[i]=databuf[i]&0xBF; //
while(!P32) {}
delay(210);
delay(210);
if(P32)
{
databuf[i]=databuf[i]|0x80;
delay(250);
delay(250);
}
else
databuf[i]=databuf[i]&0x7F; //
}
IR_goto(); //判断键值判断
display(); //显示
}
void IR_goto()
{
uchar i;
databuf[2]=~databuf[2]; //与反码对比判断
if(databuf[2]!=databuf[3]) return;
P2=P2&0xEF;
delay(250);
P2=P2|0x10;
if(databuf[3]==0xE9) //按键"0"判断显示
{
for(i=0;i<4;i++)
dispbuf[i]=0x00; //显示全部清零
}
if(databuf[3]==0xF3) //按键"1"判断显示
{
dispbuf[1]=dispbuf[1]+1;
if(dispbuf[1]>=10)
{
dispbuf[0]=dispbuf[0]+1;
dispbuf[1]=dispbuf[1]-10;
}
P1=0xFE;
delay(250);
delay(250);
delay(250);
delay(250);
}
if(databuf[3]==0xE7) //按键"2"判断显示
{
dispbuf[1]=dispbuf[1]+2;
if(dispbuf[1]>=10)
{
dispbuf[0]=dispbuf[0]+1;
dispbuf[1]=dispbuf[1]-10;
}
P1=0xFD;
delay(250);
delay(250);
delay(250);
delay(250);
}
if(databuf[3]==0xA1) //按键"3"判断显示
{
dispbuf[1]=dispbuf[1]+3;
if(dispbuf[1]>=10)
{
dispbuf[0]=dispbuf[0]+1;
dispbuf[1]=dispbuf[1]-10;
}
P1=0xFB;
delay(250);
delay(250);
delay(250);
delay(250);
}
if(databuf[3]==0xF7) //按键"4"判断显示
{
dispbuf[3]=dispbuf[3]+1;
if(dispbuf[3]>=10)
{
dispbuf[2]=dispbuf[2]+1;
dispbuf[3]=dispbuf[3]-10;
}
P1=0xF7;
delay(250);
delay(250);
delay(250);
delay(250);
}
if(databuf[3]==0xE3) //按键"5"判断显示
{
dispbuf[3]=dispbuf[3]+2;
if(dispbuf[3]>=10)
{
dispbuf[2]=dispbuf[2]+1;
dispbuf[3]=dispbuf[3]-10;
}
P1=0xEF;
delay(250);
delay(250);
delay(250);
delay(250);
}
if(databuf[3]==0xA5) //按键"6"判断显示
{
dispbuf[3]=dispbuf[3]+3;
if(dispbuf[3]>=10)
{
dispbuf[2]=dispbuf[2]+1;
dispbuf[3]=dispbuf[3]-10;
}
P1=0xDF;
delay(250);
delay(250);
delay(250);
delay(250);
}
for(i=0;i<4;i++)
databuf[i]=0x00;
return;
}
void delay(unsigned char m)
{
while(--m);
}
参考文献
[1]胡汉才.单片机原理及系统设计.清华大学出版社.2002.
[2]张华主编.电类专业毕业设计指导.机械工业出版社.2001.
[3]彭为等编著.单片机典型系统设计实例精讲.电子工业出版社2006.
[4]何立民.单片机应用系统设计.北京航空航天大学出版社.1994.
[5]邵敏权主编.单片计算机原理实验及应用技术.吉林科学技术出版社.1995.
[6] 李广弟.单片机基础.北京:北京航空航天大学出版社,2001.7
[7] 余发山.单片机原理及应用技术.徐州:中国矿业大学出版社, 2003.
[8] 马家辰, 孙玉德, 张颖等. MCS-51单片机原理及接口技术.哈尔滨:哈尔滨工业大学出版社, 1997
[9] 崔华, 蔡炎光 .单片机实用技术.北京:清华大学出版社, 2001.
[10] 周润景,张丽娜.基于PROTEUS的电路及单片机系统设计及仿真. 北京:北京航空航天大学出版社,2006.
[11] 宋凤娟,廉文利,付云强.单片机89C51在调速系统中的应用.微计算机信息,2007.