📄 keyboard.asm
字号:
;常量区
BAT_OK equ 0x0aa
BAT_ER equ 0x0fc
CMD_Rev_OK equ 0xFA
CMD_Rev_Err equ 0xFC
SSedBuffLen equ 0x10
SRevBuffLen equ 0x10
Row0_7 equ p2;
Row8_15 equ p1; p3;
THV equ 0xe8;db;00;d8 ; f0;
TLV equ 0x8f;ef;;ef;7f ;
;命令常量
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; p1.6;
KB_DATA bit T1; p1.7;
Caps bit P3.6; p1.3;
Numb bit P3.7; p1.4;
Flag_Disable bit 0x20.0
Flag_All_Mk bit 0x20.1
Flag_All_Ty bit 0x20.2
Flag_All_Bk bit 0x20.3
Flag_Host_Request bit 0x20.4
BusFree bit 0x22.0
NeedResp bit 0x22.1
CMD_Waite_Data bit 0x22.2
IS_Break bit 0x22.3
r0_addr equ 0x18
r1_addr equ 0x19
r2_addr equ 0x1A
LastState equ 0x30
KeyBuff equ 0x40 ;长度为16字节
SSCount equ 0x25
SRCount equ 0x26
KBWHead equ 0x27
KBSHead equ 0x28
KBSCount equ 0x29
SendTiming equ 0x2A
CMD equ 0x2B
TmpBy1 equ 0x2C
TmpBy2 equ 0x2D
TmpBy3 equ 0x2E
TmpBy4 equ 0x2F
CurRow equ 0x50
CurCol equ 0x51;
LastKey equ 0x52 ;上次按下的键
TypicalDelayCount equ 0x53 ;机打延时计数器
TypicalDelay equ 0x54 ;机打延时设定值
TypicalIntervalCount equ 0x55 ;机打速度间隔计数
TypicalInterval equ 0x56 ;机打速度间隔设定值
org 0x0000
jmp StartP
org 0x000b
jmp timer0_handle
ORG 0023H
JMP Serier_interrupt
;**********************************************************
;主程式
;
;**********************************************************
StartP :
clr EA
mov sp ,#60h
mov psw ,#0x18
MOV PSW ,#19H ;
MOV DPTR ,#0H;
;初始化中断
MOV IP ,#0H
MOV IE ,#0
setb ET0
clr Ex0
;初始化定时器
MOV TMOD ,#01h;
mov th0 ,#THV
mov tl0 ,#TLV
setb et0
; 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
mov b ,#10
call delay10us
call Do_bat
;setb TR0
clr TR0
; mov b ,#10
; call delay10ms
mov r4 ,#4;
clr ea
;主Loop
MainLoop :
call Check_Data_From_PC
cpl Numb
mov b ,#5
call delay10us
nop
call ScanKey
;jnb Flag_Host_Request ,m_Over
call Check_Data_From_PC
m_Over :
mov b ,#5
call delay10us
; call Check_Data_From_PC
; mov b ,#20
; call delay10us
jmp MainLoop
nop
;**********************************************************
;延时10us for 24M
;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
;**********************************************************
;延时10us for 12M
;b : 延时的时间参数0.5us
;**********************************************************
;Delay10us :;进入2出去2
;
; dly_10 :
; nop
; nop
; nop
; nop
; nop
; nop
; nop
; nop
; djnz b ,dly_10
;
; ret
;**********************************************************
;延时10us for 6M
;b : 延时的时间参数0.5us
;**********************************************************
Delay10us :;进入4出去4
dly_10 :
nop
nop
nop
djnz b ,dly_10 ;4
ret
;**********************************************************
;Delay 5us for 24M
;
;**********************************************************
;Delay5us :
; push r0_addr
;
; d_lb5 :
; mov r0 ,#8 ;1 * 0.5
; djnz r0 ,$ ;2 * 0.5
;
;
; pop r0_addr
; ret
;**********************************************************
;Delay 5us for 12M
;
;**********************************************************
;Delay5us :
; nop
; nop
; nop
; nop
;
; ret
;**********************************************************
;Delay 5us for 6M
;
;**********************************************************
Delay5us :
nop
ret
;**********************************************************
;Delay 15us with 6M
;
;**********************************************************
Delay15usWith5M :
push r0_addr
mov r0 ,#2
djnz r0 ,$ ;2*2.4=4.8
pop r0_addr
ret
;**********************************************************
;Delay 15us for 24M
;
;**********************************************************
;Delay15us :
; push r0_addr
;
; mov r0 ,#12 ;1 * 0.5
; djnz r0 ,$ ;2 * 0.5
;
;;
; pop r0_addr
; ret
;**********************************************************
;Delay 15us for 12M
;
;**********************************************************
;Delay15us :
; push r0_addr
;
; mov r0 ,#6 ;1 * 1
; djnz r0 ,$ ;2 * 1
;
;
; pop r0_addr
; ret
;**********************************************************
;Delay 15us for 6M
;
;**********************************************************
Delay15us :
nop
nop
nop
nop
nop
nop
ret
;**********************************************************
;延时10ms for 24M
;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
;**********************************************************
;延时10ms for 12M
;b : 延时的时间参10mus
;**********************************************************
;Delay10ms :
; push r0_addr
; push r1_addr
; dm_lbl0 :
; mov r1 ,#40 ;0.5
; dm_lbl1 : ;250us
; mov r0 ,#123 ;1 * 1=90us
; djnz r0 ,$ ;246us
; nop
; djnz r1 ,dm_lbl1;2us
;
; djnz b ,dm_lbl0;1
;
; pop r1_addr
; pop r0_addr
; ret
;
;**********************************************************
;延时10ms for 12M
;b : 延时的时间参10mus
;**********************************************************
Delay10ms :
push r0_addr
push r1_addr
dm_lbl0 :
mov r1 ,#40 ;2
dm_lbl1 : ;250us
mov r0 ,#61 ;2 * 1=90us
djnz r0 ,$ ;4*us=244
djnz r1 ,dm_lbl1;4us
djnz b ,dm_lbl0;4
pop r1_addr
pop r0_addr
ret
;*************************************************************************
;串口接收与传送
;***************************************************************************
timer0_handle :
clr tr0
push r0_addr
push acc
call Check_Data_From_PC
mov th0 ,#THV
mov tl0 ,#TLV
setb TR0
pop acc
pop r0_addr
reti
;*************************************************************************
;串口接收与传送
;***************************************************************************
Serier_interrupt :
clr ES
push acc
push r0_addr
JNB RI ,REC_OK
clr RI
;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 ,#SBuff
add a ,r0
mov r0 ,a
jmp ALL_OK
_Sed_over :
ALL_OK :
pop r0_addr
pop acc
setb ES
RETI
;*************************************************************************
;发送数据到主机指定地址与个数
;R1 : 要发送的数据地址
;a : 要送的数据个数
;***************************************************************************
Send_Byte_To_Host_with :
clr EA ;The processing of send can't be break
push r0_addr
push r2_addr
jz sbth_To_Over
jmp sbth_not_Over
sbth_To_Over:
jmp sbth_Over
sbth_not_Over :
mov r2 ,a
;准备发送的数据
Ready_To_Send :
setb KB_CLK
setb KB_Data
mov a ,@r1
mov c ,p
cpl c
;检测总线是否空闲
;mov b ,#25 ;for 24M
;mov b ,#12 ;for 12M
mov b ,#6 ;for 6M
sbth_check_CLK_is_Free :
jnb KB_CLK ,sbth_Rec_From_PC;sbth_Err; ;CLK=1? 如果不是错误 1us
;查测连续50us内是否为高
djnz b ,sbth_check_CLK_is_Free ;1us
jnb KB_CLK ,sbth_Rec_From_PC;sbth_Err ;确认CLK 仍为高
jnb KB_DATA ,sbth_Rec_From_PC;sbth_Err ;如果DATA为低则为主机请求发送
mov b ,#100
call delay10us
; call Delay15usWith5M
;发START 柆
clr KB_DATA
; call Delay15us
mov b ,#30
call Delay10us
jnb KB_CLK ,sbth_Err ;主机抑制检测
clr KB_CLK
mov b ,#3
call delay10us
; call Delay15usWith5M
; call Delay15usWith5M
;发送8位数据和奇校验位。
mov r0 ,#9
sbth_Send_Data :
setb KB_CLK
call Delay15us
; call Delay15usWith5M
;主机抑制检测
jnb KB_CLK ,sbth_Err
sbth_CLK_OK :
rrc a
mov KB_DATA ,c
; call Delay15us
mov b ,#30
call Delay10us
clr KB_CLK
;等待数据被读取
mov b ,#1;3
call delay10us
djnz r0 ,sbth_Send_Data
;发送STOP位
setb KB_CLK
mov b ,#3
call Delay10us
; call Delay15us
;主机抑制检测 没有必要进行等待
jnb KB_CLK ,sbth_Err
sbth_CLK_OK_1 :
setb KB_DATA
mov b ,#3
call Delay10us
; call Delay15us
jnb KB_Data ,sbth_Err ;如果数据拉不高,则出错
clr KB_CLK
mov b ,#3
call delay10us
; call Delay15usWith5M
setb KB_CLK
;发送完成
inc r1
mov b ,#200
call delay10us
jnb KB_CLK ,sbth_Rec_From_PC ;如果时钟接不高,主机发送请求
djnz r2_addr ,Ready_To_Send
jmp sbth_over
sbth_Rec_From_PC :
setb Flag_Host_Request
sbth_Over :
sbth_Err :
setb KB_CLK
setb KB_DATA
pop r2_addr
pop r0_addr
setb EA
ret
;*************************************************************************
;发送KBUFF的数据
;KBuff 有多少个数据从头依次发送出去
;
;***************************************************************************
Send_Key_Buff :
clr tr0 ;The processing of send can't be break
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
;检测总线是否空闲
;mov b ,#25 ;for 24M
mov b ,#12 ;for 12m
skb_Check_CLK_Free :
jnb KB_CLK ,skb_Rec_From_Pc;skb_Err ;CLK=1? 如果不是错误
djnz b ,skb_Check_CLK_Free
jnb KB_DATA ,skb_Rec_From_Pc ;如果DATA为低则为主机请求发送
;延时20ms
mov b ,#100
call delay10us
jnb KB_CLK ,skb_Rec_From_Pc;skb_Err ;CLK=1? 如果不是错误
;发START 位
clr KB_DATA
mov b ,#3;1
call delay10us
jnb KB_CLK ,skb_Err ;主机抑制检测
clr KB_CLK
mov b ,#2
call delay10us
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -