📄 atkeyboarda51.a51
字号:
;========================================================
;
; ATKeyboard接口函数,CPU外晶振22.1184MHz
;
;========================================================
NAME ATKEYBOARD_A51
sfr P0 = 0x80;
sfr P1 = 0x90;
sfr P2 = 0xA0;
sfr P3 = 0xB0;
sfr PSW = 0xD0;
sfr ACC = 0xE0;
;/* BIT Registers */
; PSW
sbit CY = PSW^7;
sbit AC = PSW^6;
sbit F0 = PSW^5;
sbit RS1 = PSW^4;
sbit RS0 = PSW^3;
sbit OV = PSW^2;
sbit P = PSW^0; //8052 only
;**********************************************************
Virtual_Keyboard_CLK EQU P1.1 ;虚拟键盘时钟IO
Virtual_Keyboard_Data EQU P1.2 ;虚拟键盘数据IO
;**********************************************************
KEYBOARD_OK EQU 0 ;OK
KEYBOARD_HOST_BUSY EQU 1 ;主机忙,即有数据发出来
KEYBOARD_HOST_DISABLE EQU 2 ;主机抑制发送
KEYBOARD_HOST_WITHDRAW EQU 3 ;主机取消发送
KEYBOARD_REC_PARITY EQU 4 ;接收校验错
KEYBOARD_RESENT EQU 0x0FE ;主机要求重发
;**********************************************************
;**************ATKEYBOARD_A51 function*****************************
?PR?_ATKeyboard_SendByte?ATKEYBOARD_A51 SEGMENT CODE
public _ATKeyboard_SendByte
RSEG ?PR?_ATKeyboard_SendByte?ATKEYBOARD_A51
;======从模拟键盘口发送单字节=====================
_ATKeyboard_SendByte:
MOV A,R7 ;保存参数到ACC
JNB Virtual_Keyboard_CLK,$ ;等待CLK为高电平
MOV R7,#44 ;延时50us,92T
CALL Delay
JNB Virtual_Keyboard_CLK,ERR_DISABLE
JB Virtual_Keyboard_Data,SEND_StartBit
LJMP ReceiveData;DATA为低,有数据下来,直接转去接收
SEND_StartBit:
CLR Virtual_Keyboard_Data ;起始位
CLR Virtual_Keyboard_CLK
MOV R7,#35 ;延时40us,74T
CALL Delay
SETB Virtual_Keyboard_CLK
MOV R0,#08 ;发送8位数据位,低位在前
SEND_DataBit:
JNB Virtual_Keyboard_CLK,ERR_WITHDRAW
RRC A
MOV Virtual_Keyboard_Data,C
MOV R7,#33 ;延时40us,74T,减去其它的5T
CALL Delay
CLR Virtual_Keyboard_CLK
MOV R7,#35 ;延时40us,74T
CALL Delay
SETB Virtual_Keyboard_CLK
DJNZ R0,SEND_DataBit
SEND_ParityBit:
JNB Virtual_Keyboard_CLK,ERR_WITHDRAW
RRC A
MOV C,P
CPL C
MOV Virtual_Keyboard_Data,C
MOV R7,#32 ;延时40us,74T,减去其它的7T
CALL Delay
CLR Virtual_Keyboard_CLK
MOV R7,#35 ;延时40us,74T
CALL Delay
SETB Virtual_Keyboard_CLK
SEND_StopBit:
JNB Virtual_Keyboard_CLK,ERR_WITHDRAW
SETB Virtual_Keyboard_Data
MOV R7,#33 ;延时40us,74T,减去其它的4T
CALL Delay
CLR Virtual_Keyboard_CLK
MOV R7,#35 ;延时40us,74T
CALL Delay
SETB Virtual_Keyboard_CLK
MOV R7,#35 ;延时40us,74T
CALL Delay
;接收应答,此处不去接收,直接延时2ms测试结果也没问题
LJMP ReceiveEcho
;MOV R7,#00
;RET
ERR_BUSY: MOV R7,#KEYBOARD_HOST_BUSY;主机忙
RET
ERR_DISABLE:MOV R7,#KEYBOARD_HOST_DISABLE;主机抑制发送
RET
ERR_WITHDRAW:MOV R7,#KEYBOARD_HOST_DISABLE;主机取消发送
RET
ERR_RESENT: MOV R7,#KEYBOARD_RESENT;主机要求重发
RET
;==================接收应答========================
?PR?ReceiveEcho?ATKEYBOARD_A51 SEGMENT CODE
public ReceiveEcho
RSEG ?PR?ReceiveEcho?ATKEYBOARD_A51
ReceiveEcho:
MOV R0,#150 ;等待1.5ms
MOV R1,#00 ;CLK低电平时长累计
Wait_Data: MOV R7,#07 ;延时10us,18T
CALL Delay
JB Virtual_Keyboard_CLK,CheckTime
TotalTime: INC R1 ;累计CLK低电平时长
MOV A,#10
CLR C
SUBB A,R1 ;判断CLK低电平时长
JC ReceiveData ;超过90us认为PC机有数据下来
CheckTime: DJNZ R0,Wait_Data;
CLR A
LJMP ReceiveOK;没收到应答
ReceiveData:JNB Virtual_Keyboard_CLK,$ ;等待CLK高电平
MOV R7,#02 ;延时5us,9T
CALL Delay
CLR A
JB Virtual_Keyboard_Data,ReceiveOK;DATA为高电平,说明主机放弃发送
;收到起始信号后,必须在20ms内给出时钟,这里按40us来给
;另收数据时,在低电平时,PC机交换数据,高电平时可以读数据
MOV R7,#07 ;延时10us,18T
CALL Delay
JB Virtual_Keyboard_Data,ReceiveOK;DATA为高电平,说明主机放弃发送
CLR Virtual_Keyboard_CLK
MOV R0,#09 ;接收8位数据和1位校验
ReceiveBit: MOV R7,#35 ;延时40us,74T
CALL Delay
SETB Virtual_Keyboard_CLK
MOV R7,#16 ;延时20us,36T
RRC A
MOV C,Virtual_Keyboard_Data
CALL Delay
MOV R7,#16 ;延时20us,36T
CALL Delay
CLR Virtual_Keyboard_CLK
DJNZ R0,ReceiveBit ;判断是否接收完毕
Rec_Stopbit:MOV R7,#35 ;延时40us,74T
CALL Delay
SETB Virtual_Keyboard_CLK
;之后每10us检查一次CLK,若为低,则表示PC放弃发送,则重新等待接收
JNB Virtual_Keyboard_CLK,ReceiveEcho;CLK为低电平,说明主机放弃发送
MOV R7,#07 ;延时10us,18T
CALL Delay
JNB Virtual_Keyboard_CLK,ReceiveEcho;CLK为低电平,说明主机放弃发送
JNB Virtual_Keyboard_Data,ReceiveEcho;DATA为低电平,说明主机放弃发送
MOV R7,#07 ;延时10us,18T
CALL Delay
JNB Virtual_Keyboard_CLK,ReceiveEcho;CLK为低电平,说明主机放弃发送
JNB Virtual_Keyboard_Data,ReceiveEcho;DATA为低电平,说明主机放弃发送
MOV R7,#07 ;延时10us,18T
CALL Delay
JNB Virtual_Keyboard_CLK,ReceiveEcho;CLK为低电平,说明主机放弃发送
JNB Virtual_Keyboard_Data,ReceiveEcho;DATA为低电平,说明主机放弃发送
Send_ACK: CLR Virtual_Keyboard_Data
MOV R7,#02 ;延时5us,9T
CALL Delay
CLR Virtual_Keyboard_CLK
MOV R7,#35 ;延时40us,74T
CALL Delay
SETB Virtual_Keyboard_CLK
MOV R7,#02 ;延时5us,9T
CALL Delay
SETB Virtual_Keyboard_Data
Check_Parity:
JB P,Check1
JNC ERR_Receive
SJMP ReceiveOK
Check1: JC ERR_Receive
SJMP ReceiveOK
ERR_Receive:MOV R7,KEYBOARD_REC_PARITY
RET
ReceiveOK: MOV R7,A ;接收到的值存于ACC中
RET
;=====延时函数=================
?PR?Delay?ATKEYBOARD_A51 SEGMENT CODE
public Delay
RSEG ?PR?Delay?ATKEYBOARD_A51
Delay: DJNZ R7,$
RET
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -