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

📄 222.asm

📁 单片机控制的乒乓游戏的全部程序
💻 ASM
📖 第 1 页 / 共 4 页
字号:
        INC  B                 ;显示字的下一行(每行两字节)
        INC  B
        MOV  A  ,R1
        ANL  A  ,#40H          ;R1为40H时,显示完
        JZ   MOVOUT
        AJMP DISLOOP
MOVOUT: RET                    ;移动显示结束
;
;
;***************
;单字显示程序
;***************
;显示表中某个字
DIS1:   MOV  R3 ,#5AH          ;静止显示时间控制(16ms*#5A=1.6s)
DIS11:  MOV  R2 ,#00H          ;一帧扫描初始值(行地址从00-0FH)
        MOV  DPTR,#ShowTab     ;取表首值
        MOV  R1 ,#00H          ;查表偏址(显示第一个字)
        SETB TR0               ;开扫描(每次一帧)
WAIT11: JBC  01H,DIS111        ;为1,扫描一帧结束
        AJMP WAIT11
DIS111: DJNZ R3 ,DIS11
        RET
;**************
;扫描程序
;**************
;1ms刷新一次,扫描一帧需8ms;
INTT0:  PUSH ACC
        MOV  TH0,#0F8H         ;定时器1ms初值重置
        MOV  TL0,#30H
        JBC  00H,GOEND         ;00H为8行扫描结束标志,为1时,结束
        INC  R1                ;取行右边字节偏址
        MOV  A  ,R1
        MOVC A  ,@A+DPTR       ;查表
        MOV  SBUF,A            ;串口0方式发送
WAIT:   JBC  TI ,GO            ;等待发送完毕
        AJMP WAIT
GO:     DEC  R1                ;取行左边字节首址
        MOV  A  ,R1
        MOVC A  ,@A+DPTR
        MOV  SBUF,A
WAIT1:  JBC  TI ,GO1
        AJMP WAIT1
GO1:    SETB P1.7               ;关行显示,准备刷新
        NOP                     ;串口寄存器数据稳定
        SETB P1.6               ;产生上升沿,行数据打入输入端
        NOP
        NOP
        CLR  P1.6               ;恢复低电平,为下次上升沿送数据作准备
        MOV  A  ,R2             ;修改行显示地址
        ORL  A  ,#0F0H          ;修改******地址
        MOV  R2 ,A              ;修改******地址
        MOV  A  ,P1             ;修改******地址
        ORL  A  ,#0FH           ;修改******地址
        ANL  A  ,R2             ;修改******地址
        MOV  P1 ,A              ;修改完成,P1口的高4位没变,低4位为当前R2低4位所指定的行;
        CLR  P1.7               ;开行显示
        INC  R2                 ;R2的低4位为有效信息,此处加1即指示下一行扫描的地址值
        INC  R1
        INC  R1                 ;下一行数据地址
        MOV  A  ,R2
        ANL  A  ,#07H
        JNZ  GO2                ;判断一帧扫描是否结束,没有,转,不修改标志00H
        SETB 00H                ;R2为08H,现为末行扫描,置标志
GO2:    POP  ACC
        RETI
GOEND:  CLR  TR0                ;一帧扫描完,关扫描
        SETB 01H                ;一帧扫描完,置结束标志
        POP  ACC
        RETI                    ;退出
;
;
;************
;扫描文字表
;************
;
ShowTab:DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH  ;**黑屏**
        DB 0F7H,77H,0F7H,0A8H,10H,0EAH,4AH,2AH,0BBH,0A0H,59H,0AAH,56H,0BBH,7EH,00H     ;**欢迎**
        DB 0ADH,0B7H,0ABH,0B7H,0EFH,0A0H,01H,17H,0D7H,3BH,0D7H,20H,36H,0AAH,0F1H,0A0H  ;**光临**
        DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH  ;**黑屏**

;*****************************************ShowInit End








;********************
;Moveon球运动轨迹   *
;********************
;*****************************************Moveon Begin
Moveon:MOV  R3,#14        ;设计每条球的轨迹为14列(第1~15列)
;.......................行数据处理初始化
       MOV  22H,R2        ;R0的数据交由22H保存
       MOV  23H,#00H
       MOV  24H,#15
       MOV  DPTR,#MoveTab
;.......................列数据处理初始化
       MOV  21H,R0        ;R0的数据交由21H保存
       MOV  A,R0          ;R0的数据交由累加器A来移动处理
       SETB 00H           ;00H为列数据第一,二字节大循环移位时C的暂存
       PUSH A
;.......................列数据处理
MOVESTEP:
       MOV  A,21H       ;从21H中取出暂存的R0值,用作球运行方向的判定
       CJNE A,#7FH,MOVELEFT;球由右向左移动,转
       MOV  C,00H         ;C从00H中取出暂存值
       POP  A             ;R0右大循环
       RRC  A
       MOV  R0,A
       PUSH A
       MOV  A,R1          ;R2右大循环
       RRC  A
       AJMP MOVEE


MOVELEFT:
         MOV  C,00H       ;C从00H中取出暂存值
         POP  A           ;R0左大循环
         RLC  A
         MOV  R0,A
         PUSH A
         MOV  A,R1        ;R2左大循环
         RLC  A
MOVEE:   MOV  R1,A
         MOV  00H,C       ;保存C值

;已经得到待送出的列值R0,R1;

;.......................行数据处理
        MOV  A,22H
        CJNE A,00H,MOVEEITHT;A不等于0转,行从第八行开始
        MOV  A,23H
        MOVC A,@A+DPTR       ;A得到行数据
        MOV  R2,A
        JB   1BH,MOVLOW      ;23H字节单元的3位为1表示偏址超过7,转
        JNB  01H,MOVLOW      ;位01H为0表示球没有改向,转
        DEC  23H             ;减1为下一个行数据的偏址
        AJMP MOVSHOW
MOVLOW: INC  23H             ;加1为下一个行数据的偏址
        AJMP MOVSHOW
MOVEEITHT:
        MOV  A,24H
        MOVC A,@A+DPTR       ;A得到行数据
        MOV  R2,A
        JB   23H,MOVHIGH     ;24H字节单元的3位为1表示偏址超过7,转
        JNB  01H,MOVHIGH     ;位01H为0表示球没有改向,转
        INC  24H
        AJMP MOVSHOW
MOVHIGH: DEC  24H
;.......................送出行列数据,在点阵上显示相应的亮点
MOVSHOW:SETB P1.7             ;关行显示
        CLR  P1.6             ;为送列数据作准备
        MOV  SBUF,R1          ;串口0方式发送
WAITC:  JBC  TI,GO5           ;等待发送完毕
        AJMP WAITC
GO5:    MOV  SBUF,R0
WAITD:  JBC  TI,GO6
        AJMP WAITD            ;列数据送完了
GO6:    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             ;开行扫描
;.......................根据速度标志字节26H确定相应的单位延迟时间的次数
        MOV  A,R5
        PUSH A               ;R5入栈,誊出一个寄存器
        MOV  R5,26H
DELAYUNIT:LCALL Delay10ms     ;单位延迟时间
        DJNZ R5,DELAYUNIT
        POP  A
        MOV  R5,A
;.......................球运行停止条件
        DJNZ R3,MOVESTEP ;R3没减为0时,球继续运动
        RET

MoveTab:DB 01H,02H,02H,04H,04H,04H,08H,10H,20H,20H,20H,40H,40H,80H;
  ;扫描用第1   2   2   3   3   3   4    5  6   6   6   7   7   8   行行地址
;*****************************************Moveon End




;***************************************
;游戏结束界面,由左向右显示图形,可循环*
;使用第一套寄存器,标志位为06H,07H      *
;采用定时器1来定时中断扫描             *
;按照8*8字模块顺序存放字模             *
;***************************************

;*****************************************Showwin Begin
Showwin:
;.........................初始化

        CLR  RS1               ;使用第一套寄存器
        SETB RS0
        CLR  01H               ;备用标志位清零,00H开始扫描标志,01H为1帧,扫描结束标志
        CLR  00H
        MOV  A  ,#0FFH	       ;端口初始化
        MOV  P1 ,A
        MOV  P2 ,A
        MOV  P3 ,A
        MOV  P0 ,A
        CLR  P1.6              ;串行寄存器输入打入输出控制位
        CLR  P1.3
        MOV  TMOD,#10H         ;使用T1作16位定时器,行扫描用
        MOV  TH1,#0F8H         ;定时器每次中断为1ms初值(24MHz)65536-1m*(24M/12)=63536
        MOV  TL1,#030H
        MOV  SCON,#00H         ;串行口控制字,0方式传送显示字节
        MOV  IE ,#88H          ;T1中断允许,总中断允许
        MOV  DPTR,#ShowTab2    ;DPTR指向图形码数据区
        MOV  R7 ,#3            ;R7指示图形循环执行的次数
;......................先显示前两个字模
        MOV  R5 ,#00H
        MOV  R0 ,#40H          ;数据缓存起点40H
        MOV  A  ,R5
        MOVC A  ,@A+DPTR       ;取出ShowTab2当前的数据
        MOV  @R0,A             ;送进显存中
        INC  R0                ;R0加1
        MOV  A  ,R5
        ADD  A  ,#8
        MOV  R0 ,A             ;R5加8
        MOV  A  ,R5
        MOVC A  ,@A+DPTR       ;取出ShowTab2当前的数据
        MOV  @R0,A             ;送进显存中
        INC  R0                ;R0加1
        MOV  A  ,R5
        CLR  C
        SUBB A  ,#7
        MOV  R5 ,A             ;R5减7
        MOV  A  ,R0
        CJNE A  ,#50H,ROLL1    ;R0还未到50H,两个字模还未送完,继续,转
        MOV  R1 ,#00H          ;偏址为0

        LCALL DIS1C            ;显示最前面的两个字模

;.........................循环显示部分
ROLL:   MOV  R6 ,#04H          ;R6表示显示8*8LED点阵图形的个数(取偶数)
ROLL1:  MOV  R0 ,#50H          ;R0指向用作数据缓存区的用户RAM区域50H
        MOV  A  ,R5
        MOVC A  ,@A+DPTR       ;取出ShowTab2当前的数据
        MOV  @R0,A             ;送进显存中
        INC  R0                ;R0加1
        MOV  A  ,R5
        ADD  A  ,#8
        MOV  R0 ,A             ;R5加8
        MOV  A  ,R5
        MOVC A  ,@A+DPTR       ;取出ShowTab2当前的数据
        MOV  @R0,A             ;送进显存中
        INC  R0                ;R0加1
        MOV  A  ,R5
        CLR  C
        SUBB A  ,#7
        MOV  R5 ,A             ;R5减7
        CJNE A  ,#60H,ROLL1    ;R0还未到60H,后两个字模还未送完,继续,转
;..........................左移并显示
        MOV  R4 ,#10H          ;左移16列即为两个字模,作为两个字模是否完全移完的标志
ROLLROW:MOV  R0 ,#51H
        MOV  A  ,@R0
        RLC  A
        MOV  @R0,A             ;
        DEC  R0
        MOV  A  ,@R0
        RLC  A
        MOV  @R0,A             ;
        MOV  00H,C
        SUBB A  ,#0FH
        MOV  @R0,A             ;
        DEC  R0
        MOV  A  ,@R0
        MOV  C  ,00H
        RLC  A
        MOV  @R0,A             ;四次左大循环,得到一列数据
        CJNE R0 ,#4EH,ROLLROW  ;一共需八轮循环,不足,转
        LCALL DIS1C            ;显示经过移动一列的字模
        DEC  R4
        CJNE R4 ,#0,ROLL1      ;没有移完16列,继续,转
        DEC  R6
        DEC  R6
        CJNE R6 ,#04H,ROLL1    ;一次完整的循环显示,未完则转

        DJNZ R7 ,RECYCLEROLL   ;循环(R7)次后,退出
        AJMP RESET
RECYCLEROLL:AJMP ROLL          ;

RESET:  CLR  RS0               ;换回第0套寄存器
        CLR  RS1
        RET
;.......................图形码,经过程序处理后存放在40H到5FH的连续的用户RAM区域
ShowTab2:DB  0FFH,0C7H,0FFH,0BBH,0FFH,6DH,0FFH,55H,0FFH,5DH,0FFH,62H,0FFH,0BEH,0FFH,0C1H
         DB  0FCH,7EH,0FBH,0BCH,0E7H,0DAH,0DBH,0E5H,0ABH,0F5H,0DBH,0EAH,0E7H,9CH,0F8H,7EH


;*****************************************Showwin End
;************;
;单字显示程序;
;************;
;*****************************************DIS1C Begin
DIS1C:  MOV  R3 ,#0EH          ;静止显示时间控制(8ms*#14=0.112s)
DIS11C: MOV  R2 ,#00H          ;一帧扫描初始值(行地址从00H-07H)
        SETB TR1               ;开扫描(每次一帧)
WAIT11C:JBC  01H,DIS111C       ;为1,扫描一帧结束
        AJMP WAIT11C
DIS111C:DJNZ R3 ,DIS11C
        RET
;*****************************************DIS1C End
;***********************;
;定时器1中断扫描扫描程序;
;***********************;
;*****************************************INTT1 Begin
;.......................1ms刷新一次,扫描一帧需8ms;
INTT1:  MOV  R1 ,#40H           ;R1通过间址方式找到所要显示数据,数据放在以40H为首的连续用户RAM区域中
        PUSH ACC
        MOV  TH1,#0F8H          ;定时器1ms初值重置
        MOV  TL1,#30H
        JBC  00H,GOENDB         ;00H为8行扫描结束标志,为1时,结束
        INC  R1                 ;取行右边字节偏址
        MOV  SBUF,@R1           ;串口0方式发送
WAITBA:  JBC  TI ,GOB             ;等待发送完毕
        AJMP WAITBA
GOB:    DEC  R1                 ;取行左边字节首址
        MOV  SBUF,@R1
WAIT1B: JBC  TI ,GO1B
        AJMP WAIT1B
GO1B:   SETB P1.7               ;关行显示,准备刷新
        NOP                     ;串口寄存器数据稳定
        SETB P1.6               ;产生上升沿,行数据打入输入端
        NOP
        NOP
        CLR  P1.6               ;恢复低电平,为下次上升沿送数据作准备
        MOV  A  ,R2             ;修改行显示地址
        ORL  A  ,#0F0H          ;修改******地址
        MOV  R2 ,A              ;修改******地址
        MOV  A  ,P1             ;修改******地址
        ORL  A  ,#0FH           ;修改******地址
        ANL  A  ,R2             ;修改******地址
        MOV  P1 ,A              ;修改完成,P1口的高4位没变,低4位为当前R2低4位所指定的行;
        CLR  P1.7               ;开行显示
        INC  R2                 ;R2的低4位为有效信息,此处加1即指示下一行扫描的地址值
        INC  R1
        INC  R1                 ;下一行数据地址
        MOV  A  ,R2
        ANL  A  ,#07H
        JNZ  GO2B               ;判断一帧扫描是否结束,没有,转,不修改标志00H
        SETB 00H                ;R2为08H,现为末行扫描,置标志
GO2B:   POP  ACC
        RETI
GOENDB: CLR  TR1                ;一帧扫描完,关扫描
        SETB 01H                ;一帧扫描完,置结束标志
        POP  ACC
        RETI                    ;退出
;*****************************************INTT1 End

⌨️ 快捷键说明

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