按下键盘的时候,键盘(硬件驱动)到底做了哪些工作?相信喜欢深究电脑原理的童鞋和我一样有这个疑问,当然这个问题不是我们首先提出来的,或者这本不算个问题——那些制造键盘的显然懂键盘的原理,但我们不太可能通过制造一个键盘去理解它。幸好,我们有文字、书籍和网络,所以理论上我们可以获得任何已解决问题的答案,可就像所有技术书籍面临的问题『在解答一个技术问题的时候很难确定读者的基础』一样,在这个问题上,很多作者都假定了读者有很强的电子技术基础,但实际是很多学软件的人并没有那种基础,那么这篇文章的目的就是让只有高中物理电学基础和基础门电路知识的读者理解按下键盘后电脑的运作流程。
直接上键盘的原理图(这幅图假设的是8*8的键盘按键,并只给出了键盘必须的部件,目的就是为了降低理解的难度)
未按下键盘时的状态
时钟发生器相当于一个震荡器,通过不断的1-0变换来促使计数器不断的循环计数——从000000到111111(如果你想细致了解数字电路并理解一个时钟和计数器的构成,可以看我的这篇文章),而计数数值就通过6条输出线输出。注意看两个3-8译码器的输入线,是分别和6位计数输出线的后3位及前3位连接,所以计数器的每个计数值分别对应两个3位二进制值,即可以分别通过译码器定位键盘的列和行——最后定位唯一按键(暂时不考虑多个键一起按)。
那问题来了,既然每个计数值都已经定位了唯一按键,那按下的过程是如何确定的呢?
按下键盘的过程
书上对键盘的按下检测过程都是说通过计数器扫描来实现的,那这个扫描到底是如何完成的呢?我们前面说了时钟发生器实际上相当于一个震荡器,那么既然是震荡器就有震荡频率,不妨假设为一个单片机可能的震荡频率——10kHz,这样每次震荡就需要1/10k=0.1ms,设每震荡一次执行一次计数(通过这篇文章看实现),那么每轮循环计数就需要0.1*64=6.4ms,这么短的时间显然不够一次键盘的敲击,那么到这里你应该明白了,所谓的扫描实际上就是一次循环计数(计数的同时当然会通过输出线输出),而在键盘的每次敲击过程中循环计数已经进行多次,必然有一次计数的数值和按下按键的反译码值相同,当两个数值相同的时候就会通过图示键盘下方的单稳态电路输出一个脉冲信号(这个通过一个基础门电路就可以完成)。
脉冲信号到达时钟发生器,通过时钟发生器使计数器停止(原理?还是看这篇文章),那么此时计数器输出一个稳定的值到输出线,而这个值就作为ROM的输入地址,供CPU读取对应的值(写过汇编的应该记得取端口值的命令),这个值显然就是预先设定的对应键盘的值,一般为ASCII码。嗯,你也许发现问题了,CPU怎么知道这个时候取ROM的值呢?那就是下面的中断请求触发器的功能了,观察图示,发现单稳态电路不仅和时钟发生器连接,也和中断请求触发器连接,所以脉冲信号除了阻塞计数,也触发中断请求触发器向CPU发送了一个中断请求,CPU接受中断请求执行中断处理程序,在这里就是读取键盘中的ROM值(前期也包括设置读写位等过程),读入完成后,就通过延迟电路延迟发送信号,这个信号发送到时钟发生器重新启动计数,同时发送到中断请求触发器,使触发器清空并重新进入等待状态。
到此,一个完整的键盘敲击过程完成,似乎没有多么复杂,而且你若仔细体会,便会发现实际上输入输出设备和CPU的交互实际上就是中断加数据存取,所以这时我们完全可以改口说用门电路做一个键盘是可行的,毕竟还有些大神用门电路做了个CPU。。。