⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pingpang_game.txt

📁 利用单片机实现乒乓球的游戏~~按键为击球
💻 TXT
字号:
       ORG 0000H
       LJMP START
       0RG 0003H
       LJMP INT0
       ORG 000BH
       LJMP TIME0
;-----------------------------------------------端口地址
       QIUOUT EQU 8100H
       PCOMM EQU 8706H
       LOUT EQU 8702H		;定义行输出接口(注:如果使用8279,这两个接口地址可能右所变化)
       CIN EQU 8700H		;和列输入接口的设备地址
;-----------------------------------------------相关标志位
       SAIZHI EQU 10H.0		;0为11分制,1为21分制
       FAQIUQ EQU 10H.1		;0表示该A发球,1表示该B发球
       FAQIUM EQU 10H.2		;0表示未发球,1表示已发球
       JIQIUF EQU 10H.3		;0表示A击球,球往右移,1表示B击球,球往左移
       AAJIAN EQU 10H.4		;为1时,A按下相应按键
       BAJIAN EQU 10H.5		;为1时,B按下相应按键
       DEFENA EQU 10H.6		;为1时,A得分了
       DEFENB EQU 10H.7		;为1时,B得分了
;----------------------------------------------暂存单元设置
       QIUSUD EQU 11H		;球移动的速度
       ADEFEN EQU 12H		;A的得分
       BDEFEN EQU 13H		;B的得分
       ASHENG EQU 14H		;A的获胜局数
       BSHENG EQU 15H		;B的获胜局数
       FAQIUS EQU 16H		;连续发球的计数器
       LEDDAT EQU 17H		;LED管显示球路的数据
;---------------------------------------------赛制信息
       ZONGFE EQU 18H		;赛制下的局总分
       HUANFA EQU 19H		;赛制下的换发球次数
       HUOSJS EQU 20H           ;赛制下获胜需要的获胜局数

;----------------------------------------------------初始化
 START:MOV 10H,#0
       MOV 11H,#5
       MOV 12H,#0
       MOV 13H,#0
       MOV 14H,#0
       MOV 15H,#0
       MOV 16H,#0
       MOV 17H,#01H
;---------------------------------------读入赛制信息,确定比赛比分,换发球次数,获胜局数
       MOV A,#FFH
       MOV P1,A 
       MOV A,P1
       JB ACC.0,SA
       MOV 18H,#11
       MOV 19H,#2
       MOV 20H,#3
       SJMP SB
    SA:MOV 18H,#21
       MOV 19H,#5
       MOV 20H,#4
;---------------------------------------------初始化8279数码管显示程序
    SB:MOV  DPTR,#COM8279
       MOV A,#0D3H   
    SC:MOVX A,@DPTR
       JB   ACC.7,SC
       MOV  A,#34H
       MOVX @DPTR,A
       MOV  A,#10H
       MOVX @DPTR,A       
;-------------------------------------------
  B-SD:MOV  R0,QIUSUD     ;R0标志:定时10个50ms为0.5S ,读入球速信息
       LCALL QIULED       ;输出显示LED管
       LCALL FENLED       ;显示当前比分,若为初始化则为0 
       MOV TMOD,#01H
       MOV  TL0,#0     
       MOV  TH0,#76       ;定时器0送初值(50ms定时)
       SETB TR0
       SETB ET0
       SETB EA            ;允许定时中断
;--------------------------------------------------键盘扫描子程序,若没有键按下,则一直循环扫描
   KEY:MOV DPTR,#PCOMM
       MOV A,#90H
       MOVX @DPTR,A       ;将8255的A口设置为方式0输入,B口设置为方式0输出
       LCALL KEYIN
       MOV A,R7
       CJNE A,#00H,KEY1   ;根据键值确定按键按下的为哪个??
       SETB AAJIAN         ;0键按下,即击球按键A被按下 ,事实上,A,B不能被同时按下,如果被同时按下则认为A按下
       SJMP KEY2
  KEY1:CJNE A,#06H,KEY2
       SETB BAJIAN         ;6键按下,即击球按键B被按下
  KEY2:CJNE A,#02H,KEY3
       MOV  A,QIUSUD         ;2键按下,减速键
       CJNE A,#2,SK1       ;球移动速度的下限值是0.1s=50*2
       SJMP KEY4
   SK1:SUBB A,#02H
       MOV  QIUSUD,A 
  KEY3:CJNE A,#03H,KEY4
       MOV  A,QIUSUD         ;3键按下,加速键
       CJNE A,#10,SK2      ;球移动速度的上限值是0.5s=50*10
       SJMP KEY4
   SK2:ADD  A,#02H
       MOV  QIUSUD,A         ;修改后(加或者减)的速度值重新存回SUDU中
  KEY4:JB  AAJIAN,ACHULI     	;                 
       JB  BAJIAN,BCHULI     	;有键按下转处理程序
       JB  DEFENA,ACHULI3	;无键按下或者按下的是其他键
       JB  DEFENB,BCHULI3      	;有A,B得分标志则清标志转相应的处理单元 
       SJMP KEY            	;则循环查询键盘
;--------------------------------------------------
;注意:即使AB均没有按键,仍有可能得分,所以得分判断不应该尽在按键时才有,在某方未能及时击球,也应该置位相应标志位,并给予处理
;--------------------------------------------------
;对按键A按下时做出以下的判断   
ACHULI:CLR  AAJIAN          	 ;清按键A标志
       JB FAQOIM,AHCULI1         ;若已发球,则转ACHULI1
       JB FAQIUQ,KEY       	 ;若未发球,且A没有发球权,则不判分转KEY
       SETB FAQIUM         	 ;未发球,且A有发球权,则按下A键后即表示A发球,置已发球标志
       CLR JIQIUF          	 ;置击球标志:A击球,球往右移动
;---------------------------------发球计数控制
       INC FAQIUS  
       MOV A,FAQIUS
       CJNE A,HUANFA,SE1
       MOV FAQIUS,#0             ;超过发球数,则清零发球计数器,取反发球权标志位
       CPL FAQIUQ
       SJMP SE2
   SE1:MOV FAQIUS,A   
   SE2:MOV LEDDAT,#01H           ;A的预发球状态
       SJMP  KEY           	 ;判分结束转KEY
ACHULI1:MOV   A,LZHI              ;发球状态下,A键按下,表示A试图在接球,判断A是否合法击球
       CJNE  A,#01H,ACHULI2  	 ;若23H中值(LED显示值)不为#01H,则转ACHULI2(失分)(A提前击球)
       CLR   JIQIUF         	 ;置击球标志:A击球,且满足回球规则,为合法击球,清击球标志位,继续读键盘按键
       SJMP  KEY          	 ;A准确击球转判分结束
ACHULI2:SETB   DEFENB       	 ;A未能准确击球失分,则B得分置B得分标志
;----------------------------------B得分,判断比赛获胜局,局比分,比赛结束否?
ACHULI3:INC BDEFEN 
       CLR  DEFENB
       MOV A,BDEFEN
       CJNE A,ZONGFE,PFEND1 ;B得分未超过11,则转判分结束PFEND1
       MOV  FENA,#00H
       MOV  FENB,#00H      ;清空当局得分
       INC  BSHENG        ;
       MOV  A,BSHENG
       CJNE A,HUOSJS,PFEND1
       LJMP WIN1          ;B得分到11,则转主程序重新开始游戏                    
;-----------------------------------------------------------------------
对按键B按下时做出以下的判断
BCHULI:CLR  JIANB
       JB  FAQIUM,BCHULI1   	 ;若已发球,则转BCHULI1
       JNB  FAQIUQ,KEY   	    ;若未发球,且B没有发球权,则不判分转KEY
       SETB  FAQIUM         	  ;未发球,且B有发球权,则B按键发球,同时置已发球标志
       SETB  JIQIUF          	;置击球标志:B击球
;----------------发球计数控制
       MOV A,FAQIUS
       INC A
       CJNE A,HUANFA,SF1
       MOV FAQIUS,#0
       CPL FAQIUQ
       SJMP SF2
   SF1:MOV FAQIUS,A   
   SF2:MOV LEDDAT,#01H
       MOV   LEDDAT,#80H
       SJMP  KEY            	;判分结束转KEY
BCHULI1:MOV   A,LZHI         ;
       CJNE  A,#80H,BCHULI2  	;若23H中值(LED显示值)不为#80H,则转PFENB2(失分)(B提前击球)
       SETB  JIQIUF           	;置击球标志:B击球
       SJMP  KEY          	  ;判分结束不需要重新开始游戏转KEY 
BCHULI2:SETB  DEFENA          	;B失分即A得分置A得分标志      
;----------------------------
BCHULI3:INC ADEFEN
       CLR   DEFENA 
       MOV  A,ADEFEN
       CJNE  A,ZONGFE,PFEND1  ;A得分未超过11,则转判分结束PFEND1,继续比赛                  
       MOV   FENA,#00H      ;A得分超过11,则清A得分计数器
       MOV   FENB,#00H      ;清空当局得分
       INC   BIFENA         ;A的获胜局数自增1,转而判断获胜局是否超过4     
       MOV   A,BIFENA
       CJNE  A,#03H,PFEND1  ;A比分未到3,转
       LJMP  WIN1           ;A比分到3,则转主程序清比分重新开始游戏
;----------------------------------------------------------------
PFEND1:CLR  TR0             ;一局比赛完,关定时中断
       CLR  FAQIUM          ;清空已发标志
       JB   FAQIUQ,PFEND2   ;根据发球权赋LED值用于显示待发球状态
       MOV  LEDFAT,#01H     ;发球权在A     
       LJMP B-SD            ; 
PFEND2:MOV  LEDDAT,#80H     ;发球权在B 
       LJMP B-SD            ;判分结束需要重新开始游戏转B-SD         ;判分结束  
;-----------------------------------------------------------------
 WIN1: WHATAREYOUFUCKINGDOING? DISPLAY
;----------------------------------------------------------中断服务程序
TIME0: PUSH ACC
       PUSH PSW
       PUSH DPH
       PUSH DPL
       CLR TR0
       MOV TH0,#76
       MOV TL0,#0 
       DJNZ R0,TIME4
       MOV R0,QIUSUD
       JB FAQIUM TIME2
       JB FAQIUQ TIME1
       CPL LEDDAT.0
       LCALL QIULED
       SJMP TIME4
 TIME1:CPL LEDDAT.7
       LCALL QIULED
 TIME2:MOV A,LEDDAT
       JB JIQIUF,TIME3
       CLR C
       RLC A
       MOV LEDDAT,A
       LCALL QIULED
       JNC TIME4
       SETB DEFENA
       SJMP TIME4
 TIME3:CLR C
       RRC A
       MOV LEDDAT,A
       LCALL QIULED
       JNC TIME4
       SETB DEFENB
 TIME4:POP DPL
       POP DPH
       POP PSW
       POP ACC
       SETB TR0
       RETI
;-----------------------------------------------读键盘子程序
MS20:  MOV R3,#128	       ;延时20ms子程序
MS1:   MOV R4,#70
       DJNZ R4, $
       DJNZ R3, MS1
       RET
KEYIN: MOV R7,#16		;2×8键盘处理子程序,预设置无效键值
       MOV DPTR,#LOUT		;先向行接口输出“全0”数据
       MOV A,#0FCH
       MOVX @DPTR, A
       MOV DPTR,#CIN		;再读入列接口数据
       MOVX A,@DPTR
       CPL A			;判是否有键被按下?
       JZ K05		        ;没有,执行返回操作
       ACALL MS20		;可能有,执行延时去抖动
       MOVX A,@DPTR		;重新读入列接口数据
       CPL A			;判是否确实有键被按下
       JZ K05		        ;没有,执行返回操作
       MOV R6,#0		;有,初始化行计数器
       MOV R5,#0FEH		;设置行扫描初值
K01:   MOV DPTR,#LOUT		;输出行扫描数据
       MOV A,R5
       MOVX @DPTR,A
       MOV DPTR,#CIN		;并读入列数据
       MOVX A,@DPTR
       CPL A			;判当前行是否有键被按下?
       JNZ K02			;有,进行后续处理
       INC R6			;无,增量行计数器
       MOV A,R5			;并变换行扫描数据
       RL A
       MOV R5,A
       CJNE R6,#2,K01		;判是否扫描完了全部行,若未完就再扫描下一行
       RET			;完了,返回主调程序
  K02: MOV R5, #0FFH		;初始化列计数器
  K03: INC R5		        ;增量列计数器
       RR A		        ;将读入的列数据循环右移1位
       JNB ACC.7,K03	        ;判当前列是否为所按键的列号,若不是则继续以上动作
       MOV A,R6			;是,利用公式
       RL A		        ;键值=行编号×8+列编号
       RL A
       RL A
       ADD A, R5		;计算出键值
       MOV R7,	A
       MOV DPTR,#LOUT		;向行接口输出“全0”数据
       MOV A, #0FCH
       MOVX  @DPTR, A
       MOV DPTR,#CIN		;等待用户松开按键
 K04:  MOVX A, @DPTR
       CPL A
       JNZ K04
       ACALL MS20
       MOVX A,@DPTR
       CPL A
       JNZ K04
 K05:  RET			;返回主调程序
;--------------------------------------------------------
QIULED:MOV DPTR,#QIUOUT
       MOV A,LEDDAT
       MOV @DPTR,A
       RET
       
  

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -