📄 222.asm
字号:
;*******************
; 完 整 程 序 *
;*******************
;*************************************;预定义 Begin
;*************************************;预定义 End
ORG 0000h
AJMP Main
ORG 000BH ;定时器0(TO) TF0,开机画面由TO中断导入
LJMP INTT0
ORG 001BH
LJMP INTT1
;*****************
;Main主程序 *
;*****************
;*****************************************Main Begin
Main:
MOV P0,#00H ;P0口的P0.0,P0.1,P0.2接MAX7219
MOV P1,#00H ;P1口的P1.0,P1.1,P1.2接74LS138,P1.5,P1.6接74LS595
MOV P2,#00H ;P2口的P2.0,P2.1,P2.2,P2.3接四个按键
MOV R4,#00H ;由R4来标志发球者,默认为A键发球(A键B键C键D键分别对应R4的值XEH,XDH,XBH,X7H)
MOV R5,#00H ;由R5来标志速度,默认为OOH,最慢;03H,最快
MOV R6,#00H ;由R6来标志赛制,默认为5局3胜制,每局5个球00H,11个为01H
;7局4胜制,每局5个球02H,6个为03H
MOV R7,#00H ;由R7来标志单打或双打,默认为单打00H,双打为01H
MOV SP,#70H ;指定堆栈区从70H开始
;........................接口及工作寄存器的初始化......;
ACALL MusicInit ;开机音乐
ACALL ShowInit ;开机画面,由下向上显示“欢迎”“光临”
ACALL Keyin ;进入菜单时的键查询,5s内查询A键B键状态
ACALL Menu ;进入菜单,进行游戏设置
ACALL GameStart ;游戏开始
;*****************************************Main End
;**********************
;进入菜单定时查询程序 *
;**********************
;*****************************************Keyin Begin
Keyin: PUSH 30H
PUSH 31H
MOV 30H,#31H
DD1: MOV 31H,#63H
DD2: DJNZ 31H,KEYON
DJNZ 30H,DD1
POP 31H
POP 30H
RET ;5s内无键按下,返回进入菜单
KEYON: ACALL Delay10ms
MOV C,0A0H ;P2.0
JC SETON ;A键按下,进入菜单,进行游戏设置
MOV C,0A3H ;P2.3
JC PLAYON ;D键按下,游戏直接开始
SJMP DD2 ;都不是,再查询
SETON: POP 31H
POP 30H
LJMP Menu
PLAYON:POP 31H
POP 30H
LJMP GameStart
;*****************************************Keyin end
;*****************************
;菜单,设置速度,赛制,单/双打*
;D键退出此子程序,游戏开始 *
;*****************************
;*****************************************Menu Begin
Menu: ACALL LedInit ;LED初始化,全黑
MOV R1,#06H ;置循环次数
MOV DPTR,#LedTab1 ;送出0,C,0,B,0,A;
DISP1: MOV A,R1 ;DIG5~DIG0地址
PUSH A
MOVC A,@A+DPTR
MOV B,A ;SEG5~SEG0数据
POP A
LCALL INPUT ;LED显示
DJNZ R1,DISP1
KEYIN2: JNB P2.3,GameStart ;D键按下,游戏开始
JNB P2.0,KEYA ;A键按下,转,设置速度
JNB P2.1,KEYB ;B键按下,转,设置赛制
JNB P2.2,KEYC ;C键按下,转,设置单打/双打
LJMP KEYIN2 ;无键按下,继续等待
;.............................
KEYA: MOV A,R5
ANL A,#04H
JZ SPEOUTA ;速度达到最高档,循环归0档
INC R5 ;速度提高一档
LJMP SPESHOA
SPEOUTA:MOV R5,#00H
SPESHOA:MOV DPTR,#LedTab
MOV A,R5
MOVC A,@A+DPTR
MOV B,A
MOV A,#01H ;第二个LED显示速度档
LCALL INPUT ;显示
LCALL Delay100ms ;延迟0.1s
LJMP KEYIN ;继续查询
;.............................
KEYB: MOV A,R6
ANL A,#04H
JZ SPEOUTB ;速度达到最高档,循环归0档
INC R6 ;速度提高一档
LJMP SPESHOB
SPEOUTB:MOV R6,#00H
SPESHOB:MOV A,R6
MOV DPTR,#LedTab
MOVC A,@A+DPTR
MOV B,A
MOV A,#01H ;第二个LED显示速度档
LCALL INPUT ;显示
LCALL Delay100ms ;延迟0.1s
LJMP KEYIN ;继续查询
;.............................
KEYC: MOV A,R7
ANL A,#02H
JZ SPEOUTC ;速度达到最高档,循环归0档
INC R7 ;速度提高一档
LJMP SPESHOC
SPEOUTC:MOV R7,#00H
SPESHOC:MOV A,R7
MOV DPTR,#LedTab
MOVC A,@A+DPTR
MOV B,A
MOV A,#01H ;第二个LED显示速度档
LCALL INPUT ;显示
LCALL Delay100ms ;延迟0.1s
LJMP KEYIN ;继续查询
;....................................................
LedTab1:DB 00H,7EH,4EH,7EH,7FH,7EH,77H ;0,C,0,B,0,A;
;*****************************************Menu End
;***************
;游戏运行程序 *
;***************
;*****************************************GameStart Begin
;...................游戏开始音乐
GameStart:ACALL MusicInit ;引用开机音乐作为游戏开始音乐
;...................比分赛分,相关标志位的初始化
MOV 2AH,#00H ;2AH字节单元存放左方的比分
MOV 2BH,#00H ;2BH字节单元存放右方的比分
MOV 2CH,#00H ;2CH字节单元存放左方的局分
MOV 2DH,#00H ;2DH字节单元存放右方的局分
MOV 2EH,#00H ;2EH字节单元存放每局最高得分(5或11)
MOV 2FH,#00H ;2FH字节单元存放每赛最高局分(3或4)
CLR 02H ;02H作为单打时的修改R4的标志位
CLR 03H ;03H同02H一起作为双打时的修改R4的标志位
CLR 04H ;04H作为一局结束的标志位
CLR 05H ;05H作为比赛结束的标志位
MOV A ,R6
RRC A
JNC SCORE0
MOV 2EH,#11
AJMP GAMESCORE0
SCORE0: MOV 2EH,#5
GAMESCORE0:RRC A
JNC GAMESCORE2
MOV 2FH,#3
GAMESCORE2:MOV 2FH,#4
;...................比分赛分初始归0
MOV R1,#06H ;置循环次数
DISP2: MOV A,R1 ;DIG5~DIG0地址
MOV B,#7EH ;SEG5~SEG0数据
LCALL INPUT ;LED显示全0,表示比赛的比分为0,局分为0比0
DJNZ R1,DISP2
;...................
GAMEAGAIN:MOV R4,0FEH ;默认A(左上)为发球方
SHOOTAGAIN:LCALL Shoot ;调用发球子程序
LCALL Shootback ;调用接球子程序
LCALL Score ;调用比分,局分修改及得分,胜负判定程序
JB 05H,GAMEOVER ;比赛结束,转
JB 04H,GAMEAGAIN ;04H为一,一局结束,新开局,转
AJMP SHOOTAGAIN ;一局比赛继续进行
GAMEOVER: ACALL LedInit ;关LED显示,全黑
MOV R0 ,0FFH ;一定时间内,考查按键情况
CHECKGAME:JNB P2.0,CHECKKEYA ;A键按下,回到开机状态
AJMP CHECKKEYD
CHECKKEYA:AJMP Main
CHECKKEYD:JNB P2.3,GameStart ;D键按下,原设置情形的游戏重新开始
JNB P2.1,ELELOST
DJNZ R0 ,CHECKGAME ;继续查询
ELELOST: MOV PCON,#01H ;使PD位为1,进入掉电方式,复位方可退出
;*****************************************GameStart End
;************
;Shoot发球 *
;************
;*****************************************Shoot Begin
Shoot:
;.....................发球初始化,将设置R5所得到的速度等级转化为延迟时间的次数,并存于25H字节单元
MOV A,R5
CJNE A,#00H,SPEED1
MOV 25H,#20
AJMP Shoot2
SPEED1:CJNE A,#01H,SPEED2
MOV 25H,#40
AJMP Shoot2
SPEED2:CJNE A,#02H,SPEED3
MOV 25H,#60
AJMP Shoot2
SPEED3:MOV 25H,#80
MOV 26H,25H ;第一次发球,球的运行延迟时间的次数
;.....................
Shoot2:
SETB P1.7 ;关行显示
CLR P1.6 ;为送列数据作准备
;.......................由R4确定发球方
MOV A ,R4
ANL A ,#04H ;取R4的低四位
MOV R4 ,A
ShootA: CJNE A,#0EH,ShootB ;R4不为XEH,即不是A发球,转
MOV R0 ,#7EH ;R0为第一组列数据
MOV R1 ,#0FFH ;R1为第二组列数据
MOV R2 ,#00H ;R2为第一行数据
LJMP Shootout
ShootB: CJNE A,#0DH,ShootC ;R4不为XDH,即不是B发球,转
MOV R0 ,#7EH ;R0为第一组列数据
MOV R1 ,#0FFH ;R1为第二组列数据
MOV R2 ,#07H ;R2为第七行数据
LJMP Shootout
ShootC: CJNE A,#0BH,ShootD ;R4不为XBH,即不是C发球,转
MOV R0 ,#0FFH ;R0为第一组列数据
MOV R1 ,#0FEH ;R1为第二组列数据
MOV R2 ,#00H ;R2为第一行数据
LJMP Shootout
ShootD:
MOV R0 ,#0FFH ;R0为第一组列数据
MOV R1 ,#0FEH ;R1为第二组列数据
MOV R2 ,#07H ;R2为第七行数据
;......................送行列显示信号
Shootout:
MOV SBUF,R1 ;串口0方式发送
WAITA:JBC TI,GO3 ;等待发送完毕
AJMP WAITA
GO3: MOV SBUF,R0
WAITB:JBC TI,GO4
AJMP WAITB ;列数据送完了
GO4: MOV A,R2
ORL A,#0F0H
MOV R2,A
MOV A,P1
ORL A,#0FH
ANL A,R2
MOV P1,A ;修改行数据
SETB P1.6 ;送列数据
NOP
NOP
CLR P1.7 ;开行扫描
;.......................等待发球指令
TRYR4:MOV A,P1 ;检测按键
ANL A,#0FH
XRL A,R4
JNZ TRYR4 ;键入与发球者不相符,转,重新检测,实际上,可以凭此使游戏暂停
ACALL Delay100ms ;延迟0.1s
ACALL MusicInit2 ;击球音乐
ACALL Delay100ms ;延迟0.1s
ACALL Moveon ;球向对手方移动
RET
;*****************************************Shoot End
;***************
;Shootback接球 *
;***************
;*****************************************Shootback Begin
Shootback:SETB P1.7 ;关行显示
;......................确定接球方
MOV A ,R4
CJNE A ,0FEH,DIRECTB ;球不是从A处来,转
JB 01H,TURNA ;改向标志为1,转
MOV R4 ,#0FBH
AJMP TAKEON
TURNA: MOV R4 ,#0F7H
AJMP TAKEON
DIRECTB: CJNE A ,0FDH,DIRECTC ;球不是从B处来,转
JB 01H,TURNB ;改向标志为1,转
MOV R4 ,#0F7H
AJMP TAKEON
TURNB: MOV R4 ,#0FBH
AJMP TAKEON
DIRECTC: CJNE A ,0FDH,DIRECTD ;球不是从C处来,转
JB 01H,TURNC ;改向标志为1,转
MOV R4 ,#0FEH
AJMP TAKEON
TURNC: MOV R4 ,#0FBH
AJMP TAKEON
DIRECTD: JB 01H,TURND ;改向标志为1,转
MOV R4 ,#0FDH
AJMP TAKEON
TURND: MOV R4 ,#0FEH
;......................确定在一定时间内是否接球
TAKEON: MOV 27H,#00H ;27H字节单元为接球所用的单位延迟时间间隔
CHECK: ACALL Delay10ms ;单位延迟时间间隔10ms
INC 27H
MOV A ,26H
RL A ;26H字节单元的来球延迟次数乘以2,作为接球的上限次数
CLR C
SUBB A ,27H
JC TAKEONEND0 ;按键太晚了,超过上限,失败,转
MOV A ,P1
ORL A ,#0F0H
XRL A ,R4
JNZ CHECK ;A为0表示按键不符合要求,继续查询
MOV 28H,#00H ;28H字节单元记录按键按下到解除所用延迟次数
CHECK2: ACALL Delay10ms
INC 28H
MOV A ,#20
CLR C
SUBB A ,28H
JC TAKEONEND0 ;按键解除超过0.2s,不合理,失败,转
MOV A ,P1
ORL A ,#0F0H
XRL A ,R4
JZ CHECK2 ;A为0表示按键未松开,继续查询
AJMP SPEEDALU
TAKEONEND0:LJMP TAKEONEND1
;......................计算球返回的速度(需要多少个延迟次数)
SPEEDALU: MOV A ,25H
MOV B ,#4
MUL AB
MOV B ,#10
DIV AB ;完成(25H)*4/10
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -