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

📄 success.asm

📁 本课题要求在研究PC机键盘通信协议的基础上
💻 ASM
📖 第 1 页 / 共 2 页
字号:
NEXT:   RRC   A               ;调整待查列
        JNC   FIND            ;被查列为低电平,按键找到,转出
        INC   R7              ;未找到,键号加1
        DJNZ  R3,NEXT         ;被扫描行的待查列未完,转回NEXT
        DJNZ  R2,SCAN         ;待扫描行数未完,转回SCAN
        SJMP  NOKEY           ;未找到按键
FIND:   MOV   P1,#0F0H
LOOSEN: MOV   A,P1
        ORL   A,#0FH
        CPL   A
        JNZ   LOOSEN          ;以上5条全扫描,等待松按
        SETB  WKLED
        LCALL DELAY100
        CLR   WKLED            ;以上3条熄灭LED再点亮,表示获得按键
        ACALL DISP            ;显示键值
        ACALL SEND            ;发送键码
NOKEY:  SETB  EX0             ;开INT0中断,以便响应以后的其它按键
        MOV   P1,#0F0H        ;置键盘行线P1.0-P1.3为0,作好响应按键的准备
        RETI

;子程序---键号转换并向PC机发送按键,入口参数:R7=键号
SEND:   MOV   A,R7
        MOV   DPTR,#TAB_KBD
        MOVC  A,@A+DPTR       ;发送键号对应的接通键码
        ACALL SEND_B
        MOV   A,#0F0H         ;发送断开键码F0
        ACALL SEND_B
        MOV   A,R7
        MOV   DPTR,#TAB_KBD
        MOVC  A,@A+DPTR       ;加发键号对应的接通键码
        ACALL SEND_B
        RET

TAB_KBD:DB    16H             ;'1'的接通键码
        DB    25H             ;'4'的接通键码
        DB    3DH             ;'7'的接通键码
        DB    45H             ;'0'的接通键码
        DB    1EH             ;'2'的接通键码
        DB    2EH             ;'5'的接通键码
        DB    3EH             ;'8'的接通键码
        DB    66H             ;'Back'的接通键码
        DB    26H             ;'3'的接通键码
        DB    36H             ;'6'的接通键码
        DB    46H             ;'9'的接通键码
        DB    5AH             ;'Enter'的接通键码
        DB    05H             ;'F1'的接通键码
        DB    06H             ;'F2'的接通键码
        DB    04H             ;'F3'的接通键码
        DB    0CH             ;'F4'的接通键码

;子程序---发送1个字节,入口参数:A=字节数据, 出口参数:A=原字节数据
SEND_B: MOV   22H,A           ;转存A
        MOV   C,KBCLK         ;等待PC允许发送,即KBCLK、KBDAT均未被PC拉为低电平
        JNC   CANCEL
        MOV   C,KBDAT
        JNC   CANCEL
        LCALL SLEEP
        MOV   C,P
        CPL   C               ;重要! 因为PC接收是按奇校验方式进行校验的,即8位+P位=9位为奇
        MOV   20H.0,C         ;转存奇偶校验位
        MOV   R4,#08H
        CLR   C               ;发起始位0
        MOV   KBDAT,C
        CLR   KBCLK
        LCALL SLEEP
        SETB  KBCLK
        LCALL SLEEP
        MOV   C,KBCLK         ;每发完1位都检查KBCLK是否被拉低,被拉低则放弃
        JNC   CANCEL
LOOP_S: RRC   A               ;发8位数据位
        MOV   KBDAT,C
        CLR   KBCLK
        LCALL SLEEP
        SETB  KBCLK
        LCALL SLEEP
        MOV   C,KBCLK
        JNC   CANCEL
        DJNZ  R4,LOOP_S
        MOV   C,20H.0         ;发奇偶校验位
        MOV   KBDAT,C
        CLR   KBCLK
        LCALL SLEEP
        SETB  KBCLK
        LCALL SLEEP
        MOV   C,KBCLK
        JNC   CANCEL
        SETB  C               ;发停止位1
        MOV   KBDAT,C
        CLR   KBCLK
        LCALL SLEEP
        SETB  KBCLK
        LCALL SLEEP           ;发送完毕后KBCLK、KBDAT均保持高电平
CANCEL: MOV   A,22H           ;恢复A
        RET

;子程序---接收1个字节,出口参数:A=字节数据
RECEV_B:CLR   20H.2
        MOV   R4,#08H
LOOP_R: CLR   KBCLK           ;接8位数据位
        LCALL SLEEP
        SETB  KBCLK
        LCALL SLEEP
        MOV   C,KBDAT
        RRC   A
        MOV   C,KBCLK         ;每接收1位都检查KBCLK是否被拉低,被拉低则放弃
        JNC   SKIP
        DJNZ  R4,LOOP_R
        CLR   KBCLK           ;接奇偶校验位
        LCALL SLEEP
        SETB  KBCLK
        LCALL SLEEP
        MOV   C,KBDAT
        MOV   20H.1,C
        MOV   C,KBCLK
        JNC   SKIP
STOP:   CLR   KBCLK           ;接停止位
        LCALL SLEEP
        SETB  KBCLK
        LCALL SLEEP
        MOV   C,KBCLK
        JNC   SKIP
        MOV   C,KBDAT
        JNC   STOP
        CLR   KBDAT           ;拉低KBDAT(即应答位)以通知PC接收完毕
        LCALL SLEEP
        SETB  KBDAT           ;接收完毕后KBCLK、KBDAT均保持高电平
        SETB  KBCLK
        SETB  20H.2
SKIP:   NOP
        RET

;子程序---键号转换并显示,入口参数:R7=键号
DISP:   CLR C
        MOV   A,#15           ;判断是否为'F4'键
        SUBB  A,R7
        JZ    FUNC4
        MOV   A,#14           ;判断是否为'F3'键
        SUBB  A,R7
        JZ    FUNC3
        MOV   A,#13           ;判断是否为'F2'键
        SUBB  A,R7
        JZ    FUNC2
        MOV   A,#12           ;判断是否为'F1'键
        SUBB  A,R7
        JZ    FUNC1
        MOV   A,#11           ;判断是否为'Enter'键
        SUBB  A,R7
        JZ    ENTER
        MOV   A,#7            ;判断是否为'Back'键
        SUBB  A,R7
        JZ    BACK
        MOV   A,R6            ;如果是数字序列开始,先清除原功能键显示,数字滚动显示
        JNZ   NUM
        ACALL LCD_CLR
NUM:    MOV   A,R7
        MOV   DPTR,#TAB_ASC
        MOVC  A,@A+DPTR       ;取键号对应的ASCII码
        ACALL LCD_DSP
        INC   R6              ;记录数字按键个数
        MOV   A,R7
        MOV   @R0,A           ;数字键号存入缓冲区
        INC R0                ;指向下一个缓冲区地址
        SJMP  RETURN
FUNC1:  ACALL LCD_CLR
        MOV   A,#46H          ;'F'的ASCII码
        ACALL LCD_DSP
        MOV   A,#31H          ;'1'的ASCII码
        ACALL LCD_DSP
        SJMP  ORDER
FUNC2:  ACALL LCD_CLR
        MOV   A,#46H          ;'F'的ASCII码
        ACALL LCD_DSP
        MOV   A,#32H          ;'2'的ASCII码
        ACALL LCD_DSP
        SJMP  ORDER
FUNC3:  ACALL LCD_CLR
        MOV   A,#46H          ;'F'的ASCII码
        ACALL LCD_DSP
        MOV   A,#33H          ;'1'的ASCII码
        ACALL LCD_DSP
        SJMP  ORDER
FUNC4:  ACALL LCD_CLR
        MOV   A,#46H          ;'F'的ASCII码
        ACALL LCD_DSP
        MOV   A,#34H          ;'2'的ASCII码
        ACALL LCD_DSP
        SJMP  ORDER
ENTER:  ACALL LCD_CLR
        MOV   A,#45H          ;'E'的ASCII码
        ACALL LCD_DSP
        MOV   A,#6EH          ;'n'的ASCII码
        ACALL LCD_DSP
        MOV   A,#74H          ;'t'的ASCII码
        ACALL LCD_DSP
        MOV   A,#65H          ;'e'的ASCII码
        ACALL LCD_DSP
        MOV   A,#72H          ;'r'的ASCII码
        ACALL LCD_DSP
        SJMP  ORDER
BACK:   ACALL LCD_CLR
        MOV   A,R6
        JZ    NONUM
        MOV   R0,#30H         ;重置数字键存储缓冲区首址
        DEC   R6              ;去掉最后一个数字键
        MOV   A,R6
        JZ    NONUM
        MOV   R4,A            ;置待重显数字键数目
RECALL: MOV   A,@R0
        MOV   DPTR,#TAB_ASC
        MOVC  A,@A+DPTR       ;取键号对应的ASCII码
        ACALL LCD_DSP
        INC   R0
        DJNZ  R4,RECALL
        SJMP  RETURN
NONUM:  MOV   A,R7            ;无数字键可消退时显示一个光标块
        MOV   DPTR,#TAB_ASC
        MOVC  A,@A+DPTR       ;取键号对应的ASCII码
        ACALL LCD_DSP
        SJMP  RETURN
ORDER:  MOV   R6,#00H         ;清除数字键已按次数
        MOV   R0,#30H         ;重置数字键存储缓冲区首址
RETURN: RET

TAB_ASC1:DB    30H             ;'0'的ASCII码
         DB    31H             ;'1'的ASCII码
         DB    32H             ;'2'的ASCII码
         DB    33H             ;'3'的ASCII码
         DB    34H             ;'4'的ASCII码
         DB    35H             ;'5'的ASCII码
         DB    36H             ;'6'的ASCII码
         DB    37H             ;'7'的ASCII码
         DB    38H             ;'8'的ASCII码
         DB    39H             ;'9'的ASCII码

TAB_ASC: DB    31H             ;'1'的ASCII码
         DB    34H             ;'4'的ASCII码
         DB    37H             ;'7'的ASCII码
         DB    30H             ;'0'的ASCII码
         DB    32H             ;'2'的ASCII码
         DB    35H             ;'5'的ASCII码
         DB    38H             ;'8'的ASCII码
         DB    0FFH             ;'Back'的假借ASCII码
         DB    33H             ;'3'的ASCII码
         DB    36H             ;'6'的ASCII码
         DB    39H             ;'9'的ASCII码

;子程序---LCD显示字符,入口参数:A=字符的ASCII码
LCD_DSP:MOV   DPTR,#8100H     ;指定LCD数据口地址
        MOVX  @DPTR,A
        ACALL F_BUSY
        RET

;子程序---LCD显示清除,并设显示起始在第二行最末
LCD_CLR:MOV   DPTR,#8000H     ;指定LCD指令口地址
        MOV   A,#01H          ;清屏并置AC为0
        MOVX  @DPTR,A
        ACALL F_BUSY
        MOV   A,#(0C0H+10H)   ;设置DDRAM地址
        MOVX  @DPTR,A
        ACALL F_BUSY
        RET


LCD_SET_H:MOV   DPTR,#8000H     ;指定LCD指令口地址
          MOV   A,#38H          ;功能设置,8位接口,双行显示,5X7点阵
          MOVX  @DPTR,A
          ACALL F_BUSY
          MOV   A,#0CH          ;开显示,关光标,不闪烁
          MOVX  @DPTR,A
          ACALL F_BUSY
          MOV   A,#06H          ;显示移位,AC为增量方式
          MOVX  @DPTR,A
          ACALL F_BUSY
          MOV   A,#(80H+00H)   ;设置DDRAM地址,显示起始在第二行最末
          MOVX  @DPTR,A
          ACALL F_BUSY
          RET
LCD_SET_L:MOV   DPTR,#8000H     ;指定LCD指令口地址
          MOV   A,#38H          ;功能设置,8位接口,双行显示,5X7点阵
          MOVX  @DPTR,A
          ACALL F_BUSY
          MOV   A,#0CH          ;开显示,关光标,不闪烁
          MOVX  @DPTR,A
          ACALL F_BUSY
          MOV   A,#06H          ;显示移位,AC为增量方式
          MOVX  @DPTR,A
          ACALL F_BUSY
          MOV   A,#(80H+01H)   ;设置DDRAM地址,显示起始在第二行最末
          MOVX  @DPTR,A
          ACALL F_BUSY
          RET


;子程序---LCD初始化及功能设置
LCD_SET:MOV   DPTR,#8000H     ;指定LCD指令口地址
        MOV   A,#01H          ;清屏并置AC为0
        MOVX  @DPTR,A
        ACALL F_BUSY
        MOV   A,#38H          ;功能设置,8位接口,双行显示,5X7点阵
        MOVX  @DPTR,A
        ACALL F_BUSY
        MOV   A,#0CH          ;开显示,关光标,不闪烁
        MOVX  @DPTR,A
        ACALL F_BUSY
        MOV   A,#07H          ;显示移位,AC为增量方式
        MOVX  @DPTR,A
        ACALL F_BUSY
        MOV   A,#(0C0H+10H)   ;设置DDRAM地址,显示起始在第二行最末
        MOVX  @DPTR,A
        ACALL F_BUSY
        RET

;子程序---LCD软件复位
LCD_RST:MOV   DPTR,#8000H     ;指定LCD指令口地址
        LCALL DELAY20
        MOV   A,#30H
        MOVX  @DPTR,A
        LCALL DELAY20
        MOV   A,#30H
        MOVX  @DPTR,A
        LCALL DELAY20
        MOV   A,#30H
        MOVX  @DPTR,A
        LCALL DELAY20
        MOV   A,#34H          ;功能设置
        MOVX  @DPTR,A
        ACALL F_BUSY
        MOV   A,#04H          ;关显示
        MOVX  @DPTR,A
        ACALL F_BUSY
        MOV   A,#01H          ;清屏
        MOVX  @DPTR,A
        ACALL F_BUSY
        MOV   A,#06H          ;设定输入方式
        MOVX  @DPTR,A
        ACALL F_BUSY
        RET

;子程序---判断LCD是否忙,并等待直至非忙状态
F_BUSY: PUSH  DPH
        PUSH  DPL
        PUSH  PSW
        PUSH  A
        MOV   A,#0FFH
LOOP2:  MOV   DPTR,#8200H
        MOVX  A,@DPTR
        JB    ACC.7,LOOP2
        POP   A
        POP   PSW
        POP   DPL
        POP   DPH
        RET

;子程序---延时100ms
DELAY100:MOV   R4,#64H
DL4:    ACALL DELAY1
        DJNZ  R4,DL4
        RET

;子程序---延时20ms
DELAY20:MOV   R3,#14H
DL3:    ACALL DELAY1
        DJNZ  R3,DL3
        RET

;子程序---延时1ms
DELAY1: MOV   R1,#0AH
DL2:    MOV   R2,#18H
DL1:    NOP
        NOP
        DJNZ  R2,DL1
        DJNZ  R1,DL2
        RET

;子程序---延时42us,用以形成12000b/s的KBCLK
SLEEP:  MOV   R2,#14H
DL5:    DJNZ  R2,DL5
        RET

        ;编译到此前为止
        END

⌨️ 快捷键说明

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