一般的具有人机对话的单片机系统少不了会有键盘。键盘接口的原理与应用许多的教材都有介绍,但通常各有各的方法,各有各的优劣。下面就我现有的对单片机键盘接口的了解和应用将众家的单片机直接驱动键盘的接口原理及应用作一个总结,并附加相应键盘的汇编子程序和C 语言子函数。希望大家可以
从中受益。

      本文我们以键盘的数目来选择键盘最适合的接法和最佳的编程方法,对各键盘接口的方法的优缺点加以说明。本文旨在让大家掌握一种方法,而不要读死书,举一反三创造更新更好的接口方式才是学习的极致。我最喜欢爱因斯坦的一句话:“想象力比知识更重要,想象力可以创造知识,而知识却只是别人的想象”。

1~4 按键的单片机键盘接口:
      当键盘的数目最多为4个时,我们最佳的接口方案当然是独立式接法了,即每一个I/O 口上只接一个按键,按键的另一端接电源或接地(一般接地)。占用的I/O 口数最大为4 条。(注意:1~4 按键的键盘的接法许多,如果接成扫描式可以占用更少的I/O口,但从程序复杂性和系统稳定性的综合考虑的话,独立式键盘接法应该是首选)
     独立式键盘的实现方法是利用单片机I/O口读取口的电平高低来判断是否有键按下。例如,我们将常开按键的一端接地,另一端接一个I/O 口,程序开始时将此I/O口置于高电平,平时无键按下时I/O口保护高电平。当有键按下时,此I/O 口与地短路迫使I/O 口为低电平。按键释放后,单片机内部的上拉电阻使I/O口仍然保持高电平。我们所要做的就是在程序中查寻此I/O口的电平状态就可以了解我们是否有按键动作了。
     值得注意的事,我们在用单片机对键盘处理的时候涉及到了一个重要的过程,那就是键盘的去抖动。这里说的抖动是机械的抖动,是当键盘在未按到按下的临界区产生的电平不稳定正常现象,并不是我们在按键时通过注意可以避免的。这种抖动一般在10~200毫秒之间,这种不稳定电平的抖动时间对于人来
说太快了,而对于时钟是微秒级的单片机而言则是慢长的。为了提高系统的稳定,我们必须去除或避开它。目前的技术有硬件去抖动和软件去抖动,硬件去抖动就是用部分电路对抖动部分加之处理,但是实现的难度较大又会提高了成本。软件去抖动不是去掉抖动,而是避开抖动部分的时间,等键盘稳定了再对
其处理。这里我们只研究软件去抖动,实现方法是先查寻按键当有低电平出现时立即延时10~200毫秒以避开抖动(经典值为20毫秒),延时结束后再读一次I/O 口的值,这一次的值如果为1 表示低电平的时间不到10~200 毫秒,视为干扰信号。当读出的值是0时则表示有按键按下,调用相应的处理程序。

4~16 按键的单片机键盘接口:
     当键盘数为4~16键时再用独立方法实现就得占用4~16的I/O口,显然是一种浪费。这时我们就用行列扫描式方案,行数加上列数就等于我们的按键总数,这样我们要16个按键时只要8个I/O 口,也就是占用了一个字节I/O口,这种16 键行列扫描是最常用的一种了。下面就16个按键的键盘为例,说一下行列键盘的扫描方法。

逐点扫描法:
     设P1口的低4 位置为0,高4位置为1,当无按键时P1口的数据始终保持F0H 不变。当有按键时,高位中的高电平会和低位中的低电平短路。此时高位中的高电平就会被拉低(任何高电平遇到低电平都为低),即高4 位中有0出现。

      当单片机读P1 口的值不为F0H 时则表示有键按下,经过去抖处理后就开始扫描这一个键的位置了。先把P1 的高4 位置0,低4 位置1,下面置低第1 列线并置高第1 行,之后再读第1 行的电平,为高说明不是第1 行第1 列的键被按下,跳到下一个点的扫描(第1列第2 列)。当其为0时表示第1 行第1列的键
被按下,调用相应处理程序。
     逐点扫描的优点是它的编程简单,易于理解,可以作同时按多个键的识别。缺点是它的速度慢,处理程序代码较长。

逐行扫描法:

      和逐点扫描的方法相似,只是数据的处理是以一行的4 位数据直接处理,也就是先使能第1 行(置低电平),然后看哪一列的数据变成低电平了,如果高4 位数据没有变为低电平则使能下一行。找到了按键所在的行并测出列数据就可以调用相应处理程序。
     逐行扫描的照逐点扫描要好的多,程序相对简单,速度快,也支持同时多按键处理。一般的扫描键盘多用此法。

全局扫描法:
     全局扫描是只先设P1的高4位为1,低4位为0,即F0H,然后读取P1 口的数据如果不为F0H 说明有键按下,经过延时去抖处理后读出P1 口的值,因为低4 位是0 无论按键如果都不会影响它,只有高4 位被改变。将数据寄存起来后再把P1 的状态反过来,将P1的高4 位置0,低4位置1,即0FH,再读一
次数据。这时高4 位的值是0 依然不变。这样两次读取我们就得到了2 个字节的数据(XXXX0000和0000XXXX,X为读到的数据),最后我们将这两个数相或(将两个半字节数据溶合为一个字节),就得到了一个新的字节,用这个字节和我们的设定的数据比较来决定键值。
     全局扫描只用两次扫描,速度快,易学易用,程序简单,可是它不支持同时多键处理,最佳适用4*4扫描键盘,可以用在一般的用途。

大于16按键的单片机键盘接口:
     当按键数目大于16 时用行列扫描方式驱动是比较常用的,增加I/O 口来达到行列扫描的键盘数,扫描方法多为逐行扫描,这里不多介绍。下面来了解一个用8个I/O口接36个按键的方法(参考《电子制作》杂志139期的“扩展单片机输入键的另一种方法”)。
     它采用了独特的硬件接法和逐点扫描的方法完成对36 个按键的扫描,是一种很好的节省硬件资源的方法。8个I/O 口的任意两个都有一个按键的同时,其各I/O口对地也都有一个按键,可以说是一个非常有新意的方法。(详见原文)

 

Advertisements