/**=============发送==================**/
KEYB EQU 20H.0 ;按键标致(为1时有键按下)
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN:
/* MOV SP,#60H
MOV TMOD,#20H
MOV TL1,#0E6H
MOV TH1,#0E6H
MOV SCON,#50H
MOV PCON,#80H ;
SETB TR1
*/
BEGIN: ACALL KEY ;调用键盘扫描
JB KEYB,BEGIN_ ;判断是否有键按下
JMP BEGIN
BEGIN_: CLR KEYB
MOV R0,#80H
MOV A,R4
MOV @R0,A
MOV P0,A
/*
;发送联络信号
ITX4: MOV SBUF,#33H ;发给从机1
ITX2: JBC TI,ITX1
JMP ITX2 ;等待发送
ITX1: JBC RI,ITX3 ;等待二号机回答
JMP ITX1
ITX3: MOV A,SBUF ;接收联络信号
XRL A,#33H ;异或,等于33H的话,A就为0
JNZ ITX4 ;二号机未准备好,继续联络
;串行发送
CK2: MOV R0,#80H ;开始读取,数据传送
START: MOV A,@R0
MOV SBUF,A
WAIT: JBC TI,CONT
JMP WAIT
CONT: JMP BEGIN */
SJMP BEGIN
;********键盘扫描********调用键盘扫描以后会返回一个键值存于R4中,和一个标致位KEYB
KEY: MOV A,#0FH ;查询是否有键按下
MOV P1,A
MOV A,P1
CJNE A,#0FH,KEYY
CLR KEYB
AJMP NEXT
KEYY: ACALL DEL ;去抖动
MOV A,P1
CJNE A,#0FH,GO
MOV R4,#10H ;若有抖动,则返回无效键值
CLR KEYB
AJMP NEXT
GO: SETB KEYB ;置按键标致位
MOV R2,A ;R2中存放着行信息
X1: CJNE R2,#0EH,X2 ;若为第一行
MOV A,#0F0H
MOV P1,A
MOV A,P1
MOV R3,A ;R3中存放着列信息
Y0: CJNE R3,#0E0H,Y1 ;若为第一列
MOV R4,#00H ;R4中存放要返回的键值
AJMP NEXT
Y1: CJNE R3,#0D0H,Y2 ;若为第二列,Yn表示16个键对应的操作
MOV R4,#01H
AJMP NEXT
Y2: CJNE R3,#0B0H,Y3 ;若为第三列
MOV R4,#02H
AJMP NEXT
Y3: CJNE R3,#70H,X2 ;若为第四列
MOV R4,#03H
AJMP NEXT
X2: CJNE R2,#0DH,X3 ;若为第二行
MOV A,#0F0H
MOV P1,A
MOV A,P1
MOV R3,A
Y4: CJNE R3,#0E0H,Y5 ;若为第一列
MOV R4,#04H
AJMP NEXT
Y5: CJNE R3,#0D0H,Y6 ;若为第二列
MOV R4,#05H
AJMP NEXT
Y6: CJNE R3,#0B0H,Y7
MOV R4,#06H
AJMP NEXT
Y7: CJNE R3,#70H,X3
MOV R4,#07H
AJMP NEXT
X3: CJNE R2,#0BH,X4 ;若为第三行
MOV A,#0F0H
MOV P1,A
MOV A,P1
MOV R3,A
Y8: CJNE R3,#0E0H,Y9
MOV R4,#08H
AJMP NEXT
Y9: CJNE R3,#0D0H,Y10
MOV R4,#09H
AJMP NEXT
Y10: CJNE R3,#0B0H,Y11
MOV R4,#0AH
AJMP NEXT
Y11: CJNE R3,#70H,X4
MOV R4,#0BH
AJMP NEXT
X4: CJNE R2,#07H,NEXT ;若为第四行
MOV A,#0F0H
MOV P1,A
MOV A,P1
MOV R3,A
Y12: CJNE R3,#0E0H,Y13
MOV R4,#0CH
AJMP NEXT
Y13: CJNE R3,#0D0H,Y14
MOV R4,#0DH
AJMP NEXT
Y14: CJNE R3,#0B0H,Y15
MOV R4,#0EH
AJMP NEXT
Y15: CJNE R3,#70H,NEXT
MOV R4,#0FH
NEXT: RET
DEL: MOV R7,#07H
DEL1_: MOV R6,#0FFH
DJNZ R6,$
DJNZ R7,DEL1_
RET
END
/**==============接收========================**/
;********89C51引脚定义********
RS BIT P3.6 ;数据/命令选择(H/L)
R_W BIT P2.5 ;读/写选择(H/L)
E BIT P2.6 ;使能信号
DB0_DB7 EQU P0 ;数据传送端口
;***************程序开始**************
ORG 0000H
AJMP MAIN
ORG 0030H
MAIN:
MOV R4,#80H ;第一行首地址从80H开始
MOV R1,#0C0H ;第一行首地址从C0H开始
MOV R2,#00H
MOV R3,#16
LCALL INITIAL ;显示初始化程序
LCALL CLS ;调用清屏子程序
AGAIN:
MOV A,R4
LCALL WRITE_COM ;调用写指令程序
MOV A,R2 ;取表格中的第几个字符
MOV DPTR,#LINE1 ;取表格的首地址
LCALL DISP ;调用显示子程序
INC R4
INC R2
DJNZ R3,AGAIN
MOV R2,#00H
MOV R3,#16
AGAIN1:
MOV A,R1
LCALL WRITE_COM ;调用写指令程序
MOV A,R2 ;取表格中的第几个字符
MOV DPTR,#LINE3 ;取表格的首地址
LCALL DISP ;调用显示子程序
INC R1
INC R2
DJNZ R3,AGAIN1
;*************************************************
MOV TMOD,#20H
MOV TL1,#0E6H
MOV TH1,#0E6H
MOV SCON,#50H
MOV PCON,#80H
SETB TR1
BEGIN: JBC RI,BR2
JMP BEGIN
BR2: MOV A,SBUF
XRL A,#33H
JNZ BEGIN
BT1: MOV SBUF,#33H
BS1: JBC TI,BR3
JMP BS1
BR3: MOV R0,#80H
WAIT: JBC RI,READ
JMP WAIT
READ: MOV A,SBUF
MOV @R0,A
MOV P0,A
;显示接收数据
MOV A,#0C7H
LCALL WRITE_COM ;调用写指令程序
MOV A,@R0 ;取表格中的第几个字符
MOV DPTR,#LINE2 ;取表格的首地址
LCALL DISP ;调用显示子程序
SJMP BEGIN
;****** 初始化LCM子程序******
INITIAL: MOV A,#38H
LCALL WRITE_COM
MOV A,#0EH
LCALL WRITE_COM
MOV A,#06H
LCALL WRITE_COM
RET
;*******查询忙碌标志信号子程序********
CHECK_BUSY:
PUSH ACC
BUSY_LOOP:
CLR E
SETB R_W
CLR RS
SETB E
MOV A, DB0_DB7
CLR E
JB ACC.7,BUSY_LOOP
POP ACC
LCALL DEL
RET
;****** 写指令到LCM子程序*******
WRITE_COM:
LCALL CHECK_BUSY
CLR E
CLR RS
CLR R_W
SETB E
MOV DB0_DB7,A
CLR E
RET
;****** 写数据到LCM子程序******
WRITE_DATA:
LCALL CHECK_BUSY
CLR E
SETB RS
CLR R_W
SETB E
MOV DB0_DB7,A
CLR E
RET
;*******显示1个字符到LCM子程序********
DISP:
; PUSH ACC
; CLR A
MOV C A,@A+DPTR
LCALL WRITE_DATA
; POP ACC
RET
;*******清除LCM子程序*******
CLS: MOV A,#01H
LCALL WRITE_COM
RET
;****延时子程序****
DEL:
MOV R6,#5
L1: MOV R7,#248
DJNZ R7,$
DJNZ R6,L1
RET
;******延时0.1s子程序: T=两个机器周期(2*1us)*R5(4)*R6(256)*R7(256)us=0.524288s
DELL: MOV R7,#09H
DEL1: MOV R6,#0FFH
DEL2: MOV R5,#0FFH
DJNZ R5,$
DJNZ R6,DEL2
DJNZ R7,DEL1
RET
;*****LCM第一、二行显示字符串*****
LINE1: DB "*** China OK ***",00H
LINE2: DB "0123456789ABCDEF",00H
LINE3: DB "-----( )------",00H
END