关于扫描键盘的问题

bird1 2004-06-17 12:47:10
请问各位,如何扫描键盘同时按下两个键的情况?(不是 ctrl+*).比如同时按下 "W"和"D"的情况?多谢!
...全文
324 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
bird1 2004-07-16
  • 打赏
  • 举报
回复
多谢了
showlie 2004-06-27
  • 打赏
  • 举报
回复
收藏先~~~
Aluo1979 2004-06-27
  • 打赏
  • 举报
回复
我只有睁大眼睛看的份。顶
sten 2004-06-26
  • 打赏
  • 举报
回复
小弟只有学习的份!
好精彩!
programfanny 2004-06-24
  • 打赏
  • 举报
回复
而是丢弃了。
programfanny 2004-06-24
  • 打赏
  • 举报
回复
键盘CPU在按下或释放一个键时都准备好一个8位键扫描码向主机发送,主机CPU也读了这两个码值进来处理,其中低7位是键位扫描码,bit7=1释放时产生,bit7=0按下时产生的值。但是KB INT中断在处理按健信息时只处理了少数几个特殊键(Ins/Caps/Num/Scrool/Alt/Ctrl/left_Shift/right_Shift)的释放信息,而丢弃了其它键的释放信息,只取它们的按下编码信息作处理.因此我们可以通过修改或扩充 KB INT 得到识别并处理多键按下的目的。如
你同时按下了AS或SA,键盘CPU会识别你按键的先后顺序,若你确实是同时按下了这两个键,则键盘CPU会根据内部的扫描顺序确定为A先S后,向键盘单片机的缓存依次发送代码 : 1EH 1FH,KB 硬件中断(KB INT, DOS下是INT 9) 发生时,主机CPU读到这两个代码并分别作出处理(存入主机内存中的键盘缓冲区内,DOS下是在 0000:001E处);释放时同上,只时主机CPU在读到代码9EH 9FH后将他们没有放进KB_Buffer中。
W32API 2004-06-24
  • 打赏
  • 举报
回复
TO: wangziz(梓)

哎,我在你眼中就这形象?
声明:本人很少激动。。。

第一,为区别第一次按下按键产生的信息,我习惯于把后面的称为 REPEAT CODE。
第二,硬件上还是无法同时扫描两个按键,虽然软件上可以识别出来。

不知道你有没看完我贴的内容,但也请你看完 csdsjkk() 的内容。软件只是识别而不是扫描。
wangziz 2004-06-23
  • 打赏
  • 举报
回复
老大说的对,李诚不要激动
programfanny 2004-06-23
  • 打赏
  • 举报
回复
键盘CPU在按下或释放一个键时都准备好一个8位键扫描码向主机发送,主机CPU也读了这两个码值进来处理,其中低7位是键位扫描码,bit7=1释放时产生,bit7=0按下时产生的值。但是KB INT中断在处理按健信息时只处理了少数几个特殊键(Ins/Caps/Num/Scrool/Alt/Ctrl/left_Shift/right_Shift)的释放信息.因此我们可以修改或扩充KB INT得到识别处理多键按下的目的。
csdsjkk 2004-06-23
  • 打赏
  • 举报
回复
cseg segment
assume cs:cseg,ds:cseg
org 100h
start:
jmp begin

oldint9 dw ?,?

key db 11h ;w
db 20h ;d
;最多可以定义8个键
key_size = $ - key

flag db 0

disp db 'press w + d',0


int9:
push ds
push es
push ax
push cx
push si
push di

push cs
pop ds

in al,60h
test al,80h
jz @f
mov flag,0
jmp i9
@@:

cld
push cs
pop es
mov di,offset key
mov cx,key_size
repne scasb
je @f
mov flag,0
jmp i9
@@:
mov ax,key_size
sub ax,cx
dec ax
mov cl,al
mov al,1
shl al,cl
or flag,al
mov al,flag
mov cl,8
mov ah,0
@@:
shl al,1
adc ah,0
loop @b
cmp ah,key_size
jne i9
mov ax,0b800h
mov es,ax
mov di,5*160 + 70
mov si,offset disp
mov ah,71h
@@:
lodsb
cmp al,0
je @f
stosw
jmp @b
@@:
mov flag,0

i9:
pop di
pop si
pop cx
pop ax
pop es
pop ds
jmp dword ptr cs:oldint9

begin:
push cs
pop ds
push es

mov ah,0fh
int 10h

mov ax,3509h
int 21h
mov oldint9,bx
mov oldint9+2,es
mov dx,offset int9
mov ax,2509h
int 21h

pop ax
mov dx,cs
sub dx,ax
mov ax,offset begin
mov cl,4
shr ax,cl
inc ax
add dx,ax
mov ah,31h
int 21h

cseg ends
end start


W32API 2004-06-23
  • 打赏
  • 举报
回复
哎,我知道楼上说的这些。

想问的是,你怎么处理同时按下 W 和 D 的情况。
lsr66 2004-06-23
  • 打赏
  • 举报
回复
同意上面的,发送的是该键的通码.
csdsjkk 2004-06-23
  • 打赏
  • 举报
回复
硬件定死了我们是没有办法的,
不过我们的程序可以通过巧妙的设计识别多个键同时按下,
注意是识别不是扫描,
pc键盘矩阵 谁也没法子扫描得到,
不过我们扫描的目的不也正是为了识别它们吗?


另外:没有什么repeat code,
8042可以编程设置按键重复速度和延迟时间,
如果持续按下一个键超过设置的延迟时间,8042将按照设置的重复速度连续发送该键码,
直到该键放开,
而不是什么repeat  code
W32API 2004-06-23
  • 打赏
  • 举报
回复

请注意,虽然确实是可以实现对同时按下多个按键的识别,但就目前而言,任何时候,键盘都只发送一个按键的值,而不是按顺序发送。

首先,键盘会传送 3 种按键码给 CPU: Make code、Break code 和 Repeat Code

任何时候,CPU 得到的只有可能是其中之一,
当‘XX’被按下时,发送‘XX’的 Make code,放开时,发送‘XX’的 Break code,如果按键一直处于按下的状态,定时发送‘XX’的 Repeat Code。
这里,Make code 和 Break code 是在每个按键的状态发生改变时肯定会被发送的,而 Repeat Code 只有最后一个按下的按键会被发送。

这是硬件,

计算机软件在处理这里时,正是使用了这个原则,
当收到 CTRL 的 Make code,记录 CTRL 的状态为 KEEP DOWN,当收到 CTRL 的 Break code,记录为 KEEP UP,从而实现 CTRL+XX 的按键识别。
其它的功能按键也一样。当然你也可以把 ‘D’按键设定为功能键,原理一样。


话说回来,这仅是软件在处理的时候的技巧,

这并不表示可以同时“扫描键盘同时按下两个键的情况”。

csdsjkk 2004-06-22
  • 打赏
  • 举报
回复
键盘没问题,完全支持楼主的要求,
不过得重写键盘中断处理程序
W32API 2004-06-22
  • 打赏
  • 举报
回复
楼上,这样没用,除非你自己设计键盘
wangziz 2004-06-22
  • 打赏
  • 举报
回复
替换int16H中断,然后自己判断是否按下那两个键。
csdsjkk 2004-06-22
  • 打赏
  • 举报
回复
首先要理解ibm pc键盘的工作原理,
pc键盘自身带有cpu,按下或放开键的识别均由键盘cpu处理,
也就是说,键码的取得,不是由主机cpu(即x86)扫描键盘矩阵得到,
而是由键盘cpu扫描处理后得到键码,然后通过发出键盘中断传送给主cpu,
换句话说,主cpu不会也不能通过扫描键盘矩阵得到键码,
我影响中只有appleii和laser310等这些古董机才是由主cpu自己扫描键盘矩阵得到键码,

如果同时按下多键,键盘cpu将扫描到的多个键按照扫描的顺序依次发送各个键的键码给主cpu,
而不是把多个键合成一个键码给主cpu,
我们可以看出这两种键盘处理方式在效率上pc明显高的多,
但是,在处理识别多键按下的灵活性方面pc要差些,
实际上,缺省的pc键盘中断例程根本就不能识别多键,
它只是按收到键码的先后顺序依次将各个键的键码放在键盘缓冲区,
因此,要想在自己的程序里处理多键同时按下必须自己写键盘中断程序,
由于按键个数的不确定性,不可能写一个通用的多键处理程序,
必须针对用户程序要求的特定按键组合编写特定的处理程序。


wangziz 2004-06-22
  • 打赏
  • 举报
回复
csdsjkk说的没错
W32API 2004-06-22
  • 打赏
  • 举报
回复
楼上干嘛不直接把你的程序贴出来,
让人家知道你是怎么处理 Make code 和 Break code 的,以及你是怎么产生 Repeat Code 的。
加载更多回复(5)

21,458

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧