ORG 0000H
SJMP STAR
ORG 000BH
LJMP KEYS
ORG 0050H
STAR:MOV SCON,#50H ;设置串行接口方式1,允许接收
MOV TMOD,#01H ;设置T0方式一
MOV PCON,#0H ;波特率不加倍
MOV TH1,#0ECH ;5ms中断检查一次
MOV TL1,#78H
SETB EA
SETB ET0;开中断
SETB TR0
CLR ES ;禁止串行口中断
MOV SP,#5FH
ACALL DLY
MOV A,SBUF ;接收乙机数据
JNB RI,$ ;等待接收完一帧数据
CLR RI
D0: JNB ACC.0, D1
MOV 10H,A
SJMP K1
D1: JNB ACC.1,D2
MOV 10H,A
SJMP A1
D2: JNB ACC.2 ,KEYS
MOV 10H,A
SJMP B1
K1 : MOV A, #0FEH ; 从右向左流水灯显示
MOV R0,#08H
K2 : MOV P0,A
RL A
LCALL DELAY
DJNZ R0,K2
SJMP K1
A1: MOV A, #07FH ; 从左向右流水灯显示
MOV R0,#08H
A2 : MOV P0,A
RR A
LCALL DELAY
DJNZ R0,A2
SJMP A1
B1 : MOV A, #03FH ; 两个灯从下到上流水显示
MOV R0,#04H
B2 : MOV P0,A
RR A
RR A
LCALL DELAY
DJNZ R0, B2
SJMP B1
KEYS:MOV TH1,#0ECH ;5ms中断检查一次
MOV TL1,#78H
MOV R0,#4
MOV R1,#11101111B ;行显示
MOV R2,#11111111B
SNEXT:MOV A,R1 ;送出行扫描码
MOV P1,A
MOV A,P1 ;读键状态
ORL A,#0F0H
CJNE A,#0FFH,KEYIN ;判断是否按键
MOV A,R1
RL A
MOV R1,A ;保存行键扫描数
DJNZ R0,SNEXT
RETI ;没有按键按下则返回断点
MUU1:LJMP D0
KEYIN:MOV R2,A
ACALL DLY ; 除按键抖动并等待按键弹起
NOPEN:MOV A,P1
ORL A,#0F0H
CJNE A,#0FFH,NOPEN ;键未弹起,转NOPEN等待弹起
LCALL DLY
LCALL KEYV ;将扫描码换成按键码
MOV SBUF,A ;发送数据
JNB TI,$ ; 等待一帧发送完毕
CLR TI
CLR RI
RETI
DLY: MOV R7,#30
MOV R6,#0
S1: DJNZ R6,$
DJNZ R7,S1
RET
KEYV: MOV B,#0 ;B=按键码,赋初值为0
MOV A,R2 ;判断目前的列数
C1: RRC A
JNC C2
INC B ;按键不在本列,B+4,(ADD只能对A使用)
INC B
INC B
INC B
LJMP C1
C2: MOV A,R1 ;行扫描码
RR A ;右移4位,高四位到低四位,
RR A
RR A
RR A
C3 : RRC A ;判断哪一行被按下
JNC C4 ;在当前行,转c4
INC B ;非当前行,键值+1(每一行每个按键差1)
LJMP C3
C4: MOV A,B ;(A) = (B)按键码给A
RET ;键值判断子程序返回
DELAY:MOV R7,#100 ; 延时100ms
L0:MOV R6,#250
L1:NOP
NOP
DJNZ R6,L1
DJNZ R7,L0
MOV A,SBUF ;接收乙机数据
JNB RI,$ ;等待接收完一帧数据
CLR RI
CJNE A,10H,MUU1
RET
END
|