📄 pckeycode.asm
字号:
;用汇编解PC键盘代码
?PR_ReadPcKey SEGMENT CODE
?PR_SendPcKey SEGMENT CODE
PUBLIC _ReadPCKey
PUBLIC _SendPcKey
;========================================================================
RSEG ?PR_SendPcKey
_SendPcKey:
CLR EA
;设置数据线为输出方向
MOV DPTR,#7F07H
MOVX A,@DPTR
ORL A,#80H
MOVX @DPTR,A
;先将CLK拉低,延时>100us
CLR P3.3
LCALL PYS2 ;延时200us
;将DAT拉低,
MOV DPTR,#7F05H
MOVX A,@DPTR
ANL A,#7FH
MOVX @DPTR,A
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
;释放CLK
SETB P3.3
MOV R1,#8
MOV A,R7
MOV R6,A
; PUSH A
MOV DPTR,#7F05H
SDD0:
LCALL PcIOHEI_ERR ;检测CLK高电平超时
CJNE R4,#160,SDD1
LJMP SEXITERR
SDD1:
MOV A,R6 ;读入要送数据
RRC A
MOV R6,A
MOVX A,@DPTR ;数据送到IO口
MOV ACC.7,C
MOVX @DPTR,A
LCALL PcIOLOW_ERR ;调用低电平超时判断 < 900us
CJNE R4,#160,SDD2
LJMP SEXITERR
SDD2:
DJNZ R1,SDD0
LCALL PcIOHEI_ERR ;检测CLK高电平超时
CJNE R4,#160,SDD6
LJMP SEXITERR
SDD6:
;发送校验位
MOV A,R7
JB P,SDD3
SETB C
LJMP SDD4
SDD3:
CLR C
SDD4:
MOVX A,@DPTR ;数据送到IO口
MOV ACC.7,C
MOVX @DPTR,A
LCALL PcIOLOW_ERR ;调用低电平超时判断 < 900us
CJNE R4,#160,SDD5
LJMP SEXITERR
SDD5:
LCALL PcIOHEI_ERR ;检测CLK高电平超时
CJNE R4,#160,SDD7
LJMP SEXITERR
SDD7:
MOVX A,@DPTR ;数据送到IO口
ORL A,#80H
MOVX @DPTR,A
LCALL PcIOLOW_ERR ;调用低电平超时判断 < 900us
CJNE R4,#160,SDD8
LJMP SEXITERR
SDD8:
LCALL PcIOHEI_ERR ;检测CLK高电平超时
CJNE R4,#160,SDD9
LJMP SEXITERR
SDD9:
MOVX A,@DPTR ;数据送到IO口 读取ACK
RLC A
JC SEXITERR
LCALL PcIOLOW_ERR ;调用低电平超时判断 < 900us
CJNE R4,#160,SDD10
LJMP SEXITERR
SDD10:
MOVX A,@DPTR ;数据送到IO口
ORL A,#80H
MOVX @DPTR,A
;设置数据线为输入方向
MOV DPTR,#7F07H
MOVX A,@DPTR
ANL A,#7FH
MOVX @DPTR,A
MOV R7,#1
SETB EA
RET
SEXITERR:
MOVX A,@DPTR ;数据送到IO口
ORL A,#80H
MOVX @DPTR,A
;设置数据线为输入方向
MOV DPTR,#7F07H
MOVX A,@DPTR
ANL A,#7FH
MOVX @DPTR,A
MOV R7,#0
SETB EA
RET
;========================================================================
RSEG ?PR_ReadPcKey
_ReadPCKey:
CLR EA
MOV R7,#9 ;读取9次,忽略超始位
MOV R6,#0 ;存放数据
PDD0:
;读取一个位
MOV A,R6
RR A
MOV R6,A
MOV DPTR,#7F01H
MOVX A,@DPTR
ANL A,#80H
ORL A,R6
MOV R6,A
LCALL PcIOLOW_ERR ;调用低电平超时判断 < 900us
CJNE R4,#160,PDD1
LJMP PEXITERR
PDD1:
LCALL PcIOHEI_ERR ;调用高电平超时判断 < 900us
CJNE R4,#160,PDD2
LJMP PEXITERR
PDD2:
DJNZ R7,PDD0
;读取校验位
MOV DPTR,#7F01H
MOVX A,@DPTR
MOV C,ACC.7
CLR A
RLC A
MOV R7,A
LCALL PcIOLOW_ERR ;调用低电平超时判断 < 900us
CJNE R4,#160,PDD4
LJMP PEXITERR
PDD4: //停止位判断
LCALL PcIOHEI_ERR ;调用高电平超时判断 < 900us
CJNE R4,#160,PDD5
LJMP PEXITERR
PDD5:
LCALL PcIOLOW_ERR ;调用低电平超时判断 < 900us
CJNE R4,#160,PDD6
LJMP PEXITERR
PDD6:
;判断奇校验
MOV A,R7
RRC A
MOV A,R6
; LJMP PDDOK
JNB P,PDD3 ;如果P为0,
JNC PDDOK ;P!=0 && CY = 0
LJMP PEXITERR
PDD3:
JC PDDOK ;如果CY为1,说明解码成功
LJMP PEXITERR
PDDOK:
SETB P1.1
; LCALL PYS1 ;延时1600us
MOV A,R6
MOV @R1,A
MOV R7,#1
CLR P1.1
SETB EA
RET
PEXITERR:
SETB P3.5
; LCALL PYS1 ;延时1600us
CLR P3.5
MOV R7,#0
SETB EA
RET
PYS1: MOV R4,#20 ;延时子程序1,精确延时1600微秒20Mhz
PD1: MOV R5,#205 ;延时503
DJNZ R5,$
DJNZ R4,PD1
RET
PYS2: MOV R4,#2 ;延时子程序1,精确延时160微秒20Mhz
PD2: MOV R5,#205 ;延时503
DJNZ R5,$
DJNZ R4,PD2
RET
//低电平超时判断
PcIOLOW_ERR:
MOV R4,#10 ;延时子程序2,精确延时900微秒
PLD1: MOV R5,#200
PLD2: DEC R5
CJNE R5,#0,PLD21
LJMP PLD3
PLD21:JNB P3.3,PLD2
LJMP PLD4 ;高电平,退出
PLD3: DEC R4
CJNE R4,#0,PLD1 ;说明超时了,直接退出
LJMP PLD5
PLD4:
MOV R4,#0AH
RET
PLD5: MOV R4,#160
RET
//高电平超时判断
PcIOHEI_ERR:
MOV R4,#10 ;延时子程序2,精确延时900微秒
PHD1: MOV R5,#200
PHD2: DEC R5
CJNE R5,#0,PHD21
LJMP PHD3
PHD21:JB P3.3,PHD2
LJMP PHD4 ;高电平,退出
PHD3: DEC R4
CJNE R4,#0,PHD1 ;说明超时了,直接退出
LJMP PHD5
PHD4:
MOV R4,#0AH
RET
PHD5: MOV R4,#160
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -