📄 jzhave3out.asm
字号:
ORG 0000H
LJMP WAIT
ORG 0080H
WAIT:
MOV P2,#0F0H ;USE P2.0~P2.3
MOV P1,#0FFH
MOV A,P0 ;USE P0.0~P0.3
ANL A,#0FH ;准备判断低四位
MOV R2,A ;R2存储P0低四位,以避免反复读取P0
;CLR C
;SUBB A,#07H ;判断第一行(L5)被拉低否
;JZ HAVEONE0
JNB ACC.3,GETIT
MOV A,R2
;CLR C
;SUBB A,#0BH
;JZ HAVEONE1
JNB ACC.2,GETIT
MOV A,R2 ;USE P0.0~P0.3 ;准备判断低四位
;CLR C
;SUBB A,#0DH
;JZ HAVEONE2
JNB ACC.1,GETIT
MOV A,R2 ;USE P0.0~P0.3 ;准备判断低四位
;CLR C
;SUBB A,#0EH
;JZ HAVEONE3
JNB ACC.0,GETIT
LJMP WAIT
;---------------------确定按键位置,并输出-----------------------------------
;HAVEONE0:
GETIT: LCALL DELAY10MS
MOV A,P0
ANL A,#0FH
;CJNE A,#07H,WAIT ;确定是第一行有键按下? 没有则返回扫描主程序
;LCALL GETCOLUMN ;确定哪列,值放在R4中C2~C5对应为0~3
;MOV DPTR,#TABLE
;MOV A,R2 ;FAULT
JNB ACC.3,HAVEONE0
JNB ACC.2,HAVEONE1
JNB ACC.1,HAVEONE2
JNB ACC.0,HAVEONE3
LJMP WAIT
;ADD R4,#0
HAVEONE0: LCALL GETCOLUMN ;确定哪列,值放在R4中C2~C5对应为0~3
MOV DPTR,#TABLE
MOV A,R4
ADD A,#0
MOVC A,@A+DPTR ;读通码到A中
MOV R5,A
MOV R6,A ;暂存于R6中,备断码显示时候调用
GOTO TOSHOW ;---------调试时候考虑调用子程序
HAVEONE1: LCALL GETCOLUMN ;确定哪列,值放在R4中C2~C5对应为0~3
MOV DPTR,#TABLE
MOV A,R4
ADD A,#4
MOVC A,@A+DPTR ;读通码到A中
MOV R5,A
MOV R6,A
GOTO TOSHOW
HAVEONE2: LCALL GETCOLUMN ;确定哪列,值放在R4中C2~C5对应为0~3
MOV DPTR,#TABLE
MOV A,R4
ADD A,#8
MOVC A,@A+DPTR ;读通码到A中
MOV R5,A
MOV R6,A
GOTO TOSHOW
HAVEONE3: LCALL GETCOLUMN ;确定哪列,值放在R4中C2~C5对应为0~3
MOV DPTR,#TABLE
MOV A,R4
ADD A,#12
MOVC A,@A+DPTR ;读通码到A中
MOV R5,A
MOV R6,A
TOSHOW: LCALL DISPLAY ;发送通码+断码
WAITING: MOV A,P0 ;查询按键弹起,并发出断码
ANL A,#0FH
CJNE A,#0FH,WAITING
MOV R5,#0F0H
MOV A,R5
LCALL DISPLAY ;发送断码F0
MOV A,R6
MOV R5,A
LCALL DISPLAY ;发送断码的第2部分
NOP
LJMP WAIT
;BACK: LJMP WAIT
;--------------------查询C2~C4,以确定哪列有键被按下------------------------------
GETCOLUMN: ;确定哪列为低
;MOV A,R0
;MOV R2,A
MOV P2,#0F7H
MOV A,P0
ANL A,#0FH
CLR C
SUBB A,#0FH
JZ NEXT ;第一列?
MOV R4,#0 ;是
SJMP GETOUT
NEXT: MOV P2,#0FBH
MOV A,P0
ANL A,#0FH
CLR C
SUBB A,#0FH
JZ NEXT1 ;第二列?
MOV R4,#1 ;是
SJMP GETOUT
NEXT1: MOV P2,#0FDH
MOV A,P0
ANL A,#0FH
CLR C
SUBB A,#0FH
JZ NEXT2 ;第三列?
MOV R4,#2 ;是
NEXT2: MOV P2,#0FEH
MOV A,P0
ANL A,#0FH
CLR C
SUBB A,#0FH
JZ GETOUT ;第四列?都否,则退出子程序
MOV R4,#3 ;是
GETOUT: ;MOV A,R2
;MOV R0,A
RET
;-------------------延时10MS------------------------------------------
DELAY10MS: ;延时10MS程序,数字还需要再确定下?????????
MOV R6,#10
D1: MOV R7,#248
D2: DJNZ R7,D2
DJNZ R6,D1
RET
;------------------输出显示程序---------------------------------------
DISPLAY: ;通码已经在R5和A中----------------------
MOV C,P3.2 ;查询时钟线是否为高,若为低,PC主机禁止通
JNC GOOUT ;信,跳出
CLR P3.1 ;通信起始位0送出
MOV R0,8
;MOV R6,A ;因为后面直接使用R5中的数据,空出寄存器R6
CLR P3.0 ;清零位P3.0,准备停止位输出的条件
PS2SET: MOV TMOD,#10H ;T1模式1,定时
SETB TR1 ;启动T1
LOOP: MOV TH1,#0FFH ;T1计数初值
MOV TL1, #0D6H
LOOP1: JNB TF1, LOOP1 ;等待T1溢出
CLR TF1 ;产生溢出清标志位
CPL P3.2 ;取反输出
JNB P3.2,LOOP ;判断是否为上升沿;否,则不输出新数据
JB P3.0, OUTSTOP ;输出奇校验后的下一时钟输出停止位
RRC A ;假定已经将要传送的数据放入A,带进位移位
MOV P3.1,C ;输出新1位数据
MOV R1,A ;保存移位后的数据
;DEC R0 ;准备判断8位数据是否全部输出
DJNZ R0, LOOP ;8位数据未输出完;若完,准备输出奇校验位
SETB P3.0 ;--------调试时候需要斟酌
MOV A,R5 ;通过PSW.0判断输出数据的奇偶,1为奇
MOV C,PSW.0
MOV P3.1, C ;输出奇校验位
SJMP LOOP
OUTSTOP: SETB P3.1 ;输出停止位1
GOOUT: RET
TABLE: DB 45H,16H,1EH,26H,25H,2EH,36H,3DH ;通码表
DB 3EH,46H,1CH,32H,21H,23H,24H,2BH
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -