基于AT89C51单片机的篮球比赛计时计分器

news2024/11/22 8:45:39

点击链接获取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.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/519290.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Meta-learning综述

文章目录 几个概念1&#xff09;监督、无监督、弱监督学习&#xff08;Weakly Supervised Learning&#xff09;以及 自监督学习&#xff08;Self-supervised Learning&#xff09;2&#xff09;域偏移、域适应、域泛化3&#xff09;N-way K-shot&#xff08;Few-shot learning…

【Java虚拟机】JVM诊断神器Arthas入门实操

1.Arthas简介快速入门 阿里开源的Java诊断工具&#xff0c;它可以在运行时对Java应用程序进行动态诊断和调试 当你遇到以下类似问题而束手无策时&#xff0c;Arthas可以帮助你解决 这个类从哪个 jar 包加载的&#xff1f;为什么会报各种类相关的 Exception&#xff1f;我改的代…

国考省考行测:数字推理题2

国考省考行测&#xff1a;数字推理题2 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论和行测的重要知识点 …

改进YOLOv8 | 特征融合篇 | YOLOv8 应用 BiFPN 结构 | 《 EfficientDet: 可扩展和高效的目标检测》

模型效率在计算机视觉中变得越来越重要。在本文中,我们系统地研究了目标检测中的神经网络架构设计选择,并提出了几种关键的优化方法来提高效率。首先,我们提出了一种加权双向特征金字塔网络(BiFPN),它可以实现简单快速的多尺度特征融合;其次,我们提出了一种复合缩放方法…

从期望最大化(EM)到变分自编码器(VAE)

本文主要记录了自己对变分自编码器论文的理解。 Kingma D P, Welling M. Auto-encoding variational bayes[J]. arXiv preprint arXiv:1312.6114, 2013. https://arxiv.org/abs/1312.6114 1 带有潜在变量的极大似然估计 假设我们有一个有限整数随机数发生器 z ∼ p θ ( z ) …

Linux | 学习笔记(适合小白)上

操作系统概述&#xff1a; 计算机是由硬件和软件这两个主要部分组成的操作系统是软件的一类&#xff0c;主要作用是协助用户调度硬件工作&#xff0c;充当用户和计算机硬件之间的桥梁常见的操作系统&#xff1a;PC端&#xff1a;Windows&#xff0c;Linux&#xff0c;MacOS&…

电子邮件市场中,如何使用您的Gmail?

Gmail凭借其直观的界面、慷慨的免费存储空间&#xff08;与其他Google工具共享15 GB&#xff0c;如Google Drive和Photos&#xff09;以及作为常规Gmail账户附加的各种免费生产力工具&#xff0c;在电子邮件市场占据主导地位。但是&#xff0c;人们对Google如何使用您的电子邮件…

决策引擎平台建设方案

文档修订历史 时间版本主要内容2023.05.12v1.0.0初始化 1. 概述 1.1 需求 1.1.1 需求背景 当同一个业务场景中&#xff0c;有非常多的业务分支后&#xff0c;需要有非常多的 if 判断&#xff0c;来承载这些简单的业务逻辑&#xff0c;但随着业务的发展&#xff0c;业务逐渐…

Java --- redis7之大数据统计之Bitmap

目录 一、大数据统计之Bitmap 1.1、面试题 1.2、京东签到领取京豆 一、大数据统计之Bitmap 1.1、面试题 1、日活统计 2、签到打卡 3、最近一周的活跃用户等 1.2、京东签到领取京豆 一个月的签到天数&#xff0c;连续签到数 方案1&#xff1a;使用MySQL来实现(小项目) …

NTLM 中继攻击的几种非主流玩法

在企业组织中的常见的一种安全风险是凭证重用&#xff0c;当攻击者攻击 NT LAN Manager 身份验证协议(以下简称 NTLM 身份验证)时就会出现这样的风险&#xff0c;而这个协议通常会在 微软的 活动目录 中默认启用。 NTLM 认证中的不安全性已经被安全研究人员发现超过15年了。该…

使用Vue CLI脚手架

章节概述&#xff1a; 使用Vue CLI脚手架初始化脚手架分析脚手架结构render函数修改默认配置ref属性props配置项mixin混入plugin插件scoped样式Todo-List案例WebStorage自定义事件绑定解绑全局事件总线消息的订阅与发布$nextTick过渡与动画 提示&#xff08;我没有使用markdo…

c++ 常用总结(二)

1. ① 可变参数... 、__VA_ARGS__与##__VA_ARGS__ 结论&#xff1a;##__VA_ARGS__中##的作用就是去掉前面多余的,号 &#xff0c;在使用自定义打印的时候&#xff0c;推荐##__VA_ARGS__而不是__VA_ARGS__ C语言##__VA_ARGS__的用法_fengwang0301的博客-CSDN博客 例1 __VA…

良心推荐!数学建模基础知识-MATLAB快速上手,最适合新手学习的Matlab快速入门教程

目录 1. 如何打开matlab的文件 第一种方法&#xff1a; 第二种创建脚本文件的方法。 2. 如何运行一段代码 写在命令行 写在脚本 3.some tips about matlab 工作区储存的数据 如何加入断点&如何终止运行&代码分节 1. 如何打开matlab的文件 我们写的源代码可以…

探索对抗样本生成方法:保护机器学习模型的安全性

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Comparable和Comparator的用法和区别

文章目录 前言 在这里给大家整理了一下comparable和comparator的用法和区别,这些在以后代码和面试中可能也会出现,那么,就跟着我一起去看看吧! 一 .Comparable 1.Comparable是什么? public interface Comparable<T> comparable是个接口,此接口强行对实现它的每个类的对…

22 memcpy 的调试

前言 同样是一个 很常用的 glibc 库函数 不管是 用户业务代码 还是 很多类库的代码, 基本上都会用到 内存数据的拷贝 不过 我们这里是从 具体的实现 来看一下 它的实现 主要是使用 汇编 来进行实现的, 因此 理解需要一定的基础 测试用例 就是简单的使用了一下 memcpy,…

【Linux】10. 进程地址空间

1. 虚拟地址的引出 2. 感性理解 3. 区域划分 在理解虚拟地址空间之前首先了解区域划分是什么 在小学期间的三八线&#xff0c;让桌子分割成两个区域&#xff0c;类比到地址空间也是这样划分的。 操作系统需要对进程管理&#xff0c;进程存在不同的区域映射不同的虚拟地址 这…

【GAMES101】作业0学习总结

本系列博客为记录笔者在学习GAMES101课程时遇到的问题与思考。 GAMES101&#xff1a;课程官网GAMES101&#xff1a;B站视频GAMES101&#xff1a;相关文件下载(百度网盘) 一、环境搭建 以下说明两种环境搭建方法&#xff0c;一种为用原视频所提及的VirtualBox一键搭建环境&…

随笔-涨薪了

突然想起来上个月工资&#xff0c;绩效部分是按照1.01发的&#xff0c;多了10块钱&#xff0c;这也是一年半来第一次涨薪了&#xff0c;就去小龙、小虎我仨的小群里面嘚瑟一下&#xff1a; 我&#xff1a;两年来第一次涨薪&#xff0c;涨了12。 小龙&#xff1a;羡慕。 小虎…

11-CSS-概述、与HTML的结合方式

一、概述 CSS&#xff08;层叠样式表&#xff09;是一种用于控制网页外观和布局的样式语言。它可以独立于 HTML 或 XHTML 文档&#xff0c;以及任何标记语言使用&#xff0c;因此可以用于设计不同类型的文档&#xff0c;如 XML、SVG、XUL 等。CSS 提供了广泛的样式选择器&…