📄 keyboardhost.asm
字号:
;常量区
BAT_OK equ 0x0aa
BAT_ER equ 0x0fc
SSedBuffLen equ 0x10
SRevBuffLen equ 0x10
;命令常量
CMD_Reset equ 0xFF ;(Reset)
CMD_Resend equ 0xFE ;(Resend)
;CMD_Set_MkBk equ 0xFC ;不发机打
;CMD_Set_MkTy equ 0xFB ;(Set Key Type Typematic)
CMD_Set_AllMkbkTy equ 0xFA ;
CMD_Set_AllMk equ 0xF9 ;(Set All Keys Make)
CMD_Set_AllMkBk equ 0xF8 ;0xF8 (Set All Keys Make/Break)
CMD_Set_AllTy equ 0xF7 ;(Set All Keys Typematic)
CMD_Set_Default equ 0xF6 ;(Set Default) 载入缺省的机打速率/延时10.9cps/500ms 按键类型(所有按键都使能机打/通
; 码/断码) 以及第二套扫描码集
CMD_Dis equ 0xF5 ;(Disable)
CMD_Ena equ 0xF4 ;(Enable)
CMD_Set_TyRtDe equ 0xF3 ;(Set Typematic Rate/Delay)
CMD_Read_ID equ 0xF2 ;(Read ID)0xAB 0x83
CMD_Set_Code equ 0xF0 ;(Set Scan Code Set)
CMD_Echo equ 0xEE ;(Echo)
CMD_SET_CapsNum equ 0xED ;Caps Num Scroll
;
KB_CLK bit T0
KB_DATA bit T1
Caps bit p3.6
Numb bit p3.7
Flag_Disable bit 0x20.0
Flag_All_Mk bit 0x20.1
Flag_All_Ty bit 0x20.2
Flag_All_Bk bit 0x20.3
BusFree bit 0x22.0
NeedResp bit 0x22.1
r0_addr equ 0x18
r1_addr equ 0x19
r2_addr equ 0x1A
SSBuff equ 0x30
SRBuff equ 0x40
KeyBuff equ 0x50 ;长度为16字节
SSCount equ 0x60
SRCount equ 0x61
KBWHead equ 0x62
KBSHead equ 0x63
KBSCount equ 0x64
TmpBy1 equ 0x65
TmpBy2 equ 0x66
CMD equ 0x70
org 0x0000
jmp StartP
org 0x000b
jmp timer0_handle
ORG 0023H
JMP Serier_interrupt
;**********************************************************
;主程式
;
;**********************************************************
StartP :
clr EA
mov sp ,#00h
mov psw ,#0x18
MOV PSW ,#19H ;
MOV DPTR ,#0H;
;初始化中断
MOV IP ,#0H
MOV IE ,#0
setb ET0
clr Ex0
;初始化定时器
MOV TMOD ,#01h;
mov th0 ,#0x000
mov tl0 ,#0x000
setb et0
; setb TR0
clr TR0
; clr et0
;初始化串口,
SETB ES
CLR ET1
MOV SCON ,#50H ;SM0 SM1 SM2 REN TB8 RB8 TI RI
MOV A ,TMOD
ANL A ,#0FH
ORL A ,#020H
mov TMOD ,a
MOV A ,PCON
orl A ,#080H
MOV PCON ,A
MOV TH1 ,#256-13
MOV TL1 ,#256-13
SETB TR1
;初始化状态
mov KBWHead ,#KeyBuff
mov KBSHead ,#KeyBuff
mov KBSCount,#0
mov p3 ,#0xff
setb EA
mov r6 ,#01
mov TmpBy1 ,#0
;call Do_bat
;mov b ,#2
;call delay10ms
mov r4 ,#0
mov r5 ,#0
mov CMD ,#CMD_Read_ID
;主Loop
MainLoop :
; cpl p0.0
nop
;>Test for receive from device
; call Rev_from_Device
;<Test for receive from device
;>Test for Send Data at where to Host
;inc r7
;mov r1 ,#KeyBuff
;mov a ,r7
;mov @r1 ,a
;mov a ,#1
;call Send_Byte_To_Host_with
;<Test for Send Data at where to Host
;>Test for Send Data in KeyBuff to Host
call Rev_from_Device
inc r4
cjne r4 ,#255 ,m_Ok
mov r4 ,#0
inc r5
mov r0 ,#KeyBuff
mov a ,r5
mov @r0 ,CMD;#CMD_ECHO
mov a ,#1
;mov sbuf ,CMD
;call SendDataToDevice
mov b ,#1
call delay10us
; mov a ,r5
; cjne a ,#6 ,m_OK
; jmp
m_Ok :
jmp MainLoop
nop
;**********************************************************
;延时10us
;b : 延时的时间参数0.5us
;**********************************************************
Delay10us :
push r0_addr
d_lbl0 :
mov r0 ,#8 ;1 * 0.5
djnz r0 ,$ ;2 * 0.5
nop
djnz b ,d_lbl0 ;2 * 0.5
pop r0_addr
ret
;**********************************************************
;延时20us
;A : 延时的时间参数0.5us
;**********************************************************
Delay20us :
push r0_addr
mov a ,#17
d_lb20 :
mov r0 ,#8 ;1 * 0.5
djnz r0 ,$ ;2 * 0.5
nop
djnz acc ,d_lb20 ;2 * 0.5
pop r0_addr
ret
;**********************************************************
;延时10ms
;b : 延时的时间参10mus
;**********************************************************
Delay10ms :
push r0_addr
push r1_addr
dm_lbl0 :
mov r1 ,#100 ;0.5
dm_lbl1 : ;100us
mov r0 ,#98 ;0.5 200 * 0.5=100us
djnz r0 ,$ ;98us
nop ;0.5us
djnz r1 ,dm_lbl1;1us
djnz b ,dm_lbl0;1
pop r1_addr
pop r0_addr
ret
;*************************************************************************
;串口接收与传送
;***************************************************************************
timer0_handle :
clr tr0
call Check_Data_From_PC
push r0_addr
push acc
mov th0 ,#0x000
mov tl0 ,#0x00
mov r0 ,#KeyBuff
mov a ,#1
mov @r0 ,#0x0ed
inc r0
mov a ,r6
rr a
mov r6 ,a
mov @r0 ,a
mov a ,#2
mov r0 ,#KeyBuff
;call SendDataToDevice
;
setb TR0
; cpl p3.6
;
pop acc
pop r0_addr
reti
;*************************************************************************
;串口接收与传送
;***************************************************************************
Serier_interrupt :
clr ES
push acc
push r0_addr
JNB RI ,REC_OK
clr RI
mov CMD ,sbuf
mov sbuf ,CMD
;mov a ,SRCount
;add a ,#SRBUff
;mov r0 ,a
;mov @r0 ,Sbuf
;inc a
;anl a ,#0x0f ;16个字节的取模
;mov SRCount ,a
; mov r0 ,#SRBUFF
; mov a ,SBUF
;mov SBUF ,a
; mov @r0 ,a
; mov a ,#1
; call SendDataToDevice
REC_OK :
JNB TI ,ALL_OK
clr TI
setb KB_DATA
setb KB_CLK
mov a ,SSCount
jz _Sed_over
dec a
mov SSCount ,a
mov r0 ,#SSBuff
add a ,r0
mov r0 ,a
; mov SBUF ,@r0
jmp ALL_OK
_Sed_over :
ALL_OK :
pop r0_addr
pop acc
setb ES
RETI
;*************************************************************************
;发送数据到主机指定地址与个数
;R1 : 要发送的数据地址
;a : 要送的数据个数
;***************************************************************************
Send_Byte_To_Host_with :
push acc
push r1_addr
push r2_addr
; mov a ,KeyBuff
jz sbth_Over
mov r2 ,a
;准备发送的数据
Ready_To_Send :
setb KB_CLK
mov a ,@r1
mov c ,p
cpl c
;检测总线是否空闲
mov b ,#25
sbth_check_Data_is_Free :
jnb KB_CLK ,sbth_Err ;CLK=1? 如果不是错误 1us
;mov b ,#5 ;如果是等待50us
;call Delay10us
djnz b ,sbth_check_Data_is_Free ;1us
jnb KB_CLK ,sbth_Err ;确认CLK 仍为高
jnb KB_DATA ,sbth_Err ;如果DATA为低则为主机请求发送
;发START 柆
clr KB_DATA
mov b ,#1
call delay10us
clr KB_CLK
mov b ,#2
call delay10us
;发送8位数据和奇校验位。
mov r0 ,#9
sbth_Send_Data :
setb KB_CLK
mov b ,#1
call delay10us
;主机抑制检测
mov b ,#45
sbth_Waite_CLK_Raise :
jb KB_CLK ,sbth_CLK_OK
nop
djnz b ,sbth_Waite_Clk_Raise
jmp sbth_Err
sbth_CLK_OK :
rrc a
mov KB_DATA ,c
mov b ,#1
call delay10us
clr KB_CLK
;等待数据被读取
mov b ,#2
call delay10us
djnz r0 ,sbth_Send_Data
;发送STOP位
setb KB_CLK
mov b ,#1
call delay10us
mov b ,#45
sbth_Waite_Stop_Clk_Raise :
jb KB_CLK ,sbth_CLK_OK_1
nop
djnz b ,sbth_waite_Stop_clk_raise
nop
jmp sbth_Err
nop
sbth_CLK_OK_1 :
setb KB_DATA
mov b ,#1
call delay10us
clr KB_CLK
mov b ,#2
call delay10us
setb KB_CLK
;发送完成
inc r1
djnz r2_addr ,Ready_To_Send
sbth_Over :
sbth_Err :
pop r2_addr
pop r1_addr
pop acc
ret
;*************************************************************************
;发送KBUFF的数据
;KBuff 有多少个数据从头依次发送出去
;
;***************************************************************************
Send_Key_Buff :
push acc
push b
push r0_addr
push r1_addr
push r2_addr
; mov a ,KeyBuff
mov a ,KBSCount
jz skb_To_Over
jmp skb_not_over
skb_To_Over :
jmp skb_Over
skb_not_over :
mov a ,KBSHead ;KeyBuff的地址
;add a ,#KeyBuff
mov r0 ,a
;准备发送的数据
skb_Ready_To_Send :
setb KB_CLK ;试图将本地时钟拉高
mov a ,@r0
mov c ,p
cpl c
;检测总线是否空闲
jnb KB_CLK ,skb_Err ;CLK=1? 如果不是错误
mov b ,#5 ;如果是等待50us
call Delay10us
jnb KB_CLK ,skb_Err ;确认CLK 仍为高
jnb KB_DATA ,skb_Err ;如果DATA为低则为主机请求发送
;发START 位
clr KB_DATA
mov b ,#1
call delay10us
clr KB_CLK
mov b ,#2
call delay10us
;发送8位数据和奇校验位。
mov r1 ,#9
skb_Send_Data :
setb KB_CLK
mov b ,#1
call delay10us
;主机抑制检测
mov b ,#45
skb_Waite_CLK_Raise :
jb KB_CLK ,skb_CLK_OK
nop
djnz b ,skb_Waite_Clk_Raise
jmp skb_Err
skb_CLK_OK :
rrc a
mov KB_DATA ,c
mov b ,#1
call delay10us
clr KB_CLK
;等待数据被读取
mov b ,#2
call delay10us
djnz r1 ,skb_Send_Data
;发送STOP位
setb KB_CLK
mov b ,#1
call delay10us
mov b ,#45
skb_Waite_Stop_Clk_Raise :
jb KB_CLK ,skb_CLK_OK_1
nop
djnz b ,skb_waite_Stop_clk_raise
nop
jmp skb_Err
skb_CLK_OK_1 :
setb KB_DATA
mov b ,#1
call delay10us
clr KB_CLK
mov b ,#2
call delay10us
setb KB_CLK
;发送完成
;调整指针
mov a ,#KeyBuff
add a ,#15
cjne a ,KBSHead ,skb_not_full
mov r0 ,#KeyBuff
jmp skb_point_Ok
skb_not_full :
inc r0
skb_point_Ok :
; mov b ,#10
; call delay10us
mov KBSHead ,r0
djnz KBSCount ,skb_Ready_To_Send
skb_Over :
skb_Err :
pop r2_addr
pop r1_addr
pop r0_addr
pop b
pop acc
ret
;*************************************************************************
;执行BAT
;***************************************************************************
Do_bat :
push acc
push r0_addr
setb Caps
setb Numb
mov DPTR ,#Code_Set2 ;设定为第二编码集
mov a ,#TmpBy1
mov r1 ,a
mov @r1 ,#BAT_OK
mov a ,#1
call Send_Byte_To_Host_with
clr Caps
clr Numb
pop r0_addr
pop acc
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -