跳转到主内容
Knowledgebase
Home
Renesas Electronics China - Knowledgebase

微控制器的键开关输入

最新更新:2011年10月 06日

Question:

微控制器的键开关输入

Answer:

键开关是微控制器的基本输入源。本节将介绍微控制器是如何捕捉键开关信号的。

[引言]
微控制器捕捉键开关信号时,要使用微控制器的输入端口。下面是一个基本结构示例。在这个例子中,当没有按下键开关(关闭)时,输入端口P70引脚为高电 平;而当按下键开关(打开)时,该引脚为低电平。因此当程序读取P7时,如果第0位为1代表没有按键发生,而如果第0位为0则代表有按键发生。



[消抖措施]
操作原理如上所述。但上面的例子不能实际使用,因为通常的开关是机械器件,有抖动。 因此,必须按规定的时间间隔读取端口。称为采样,采样图如下所示。图中的圆圈是指读取(采样)的端口时序,表示周期性地读取该端口。采样时间应该比产生抖 动的时间长。考虑到器件的差异和老化等因素,采样时间应该更长些。通过对端口进行采样,可以很容易获得信号的变化情况,并制订消抖措施。但是,如果是在采 样时出现抖动噪声,则噪声可能被误认为信号。为了防止将噪声误认为信号,应按行多次采样信号。如果连续采样到同样状态的信号,就认为信号值是正确的。要了 解详细的程序的操作,请参阅 [消抖处理]



[按键返回中断/按键中断] (78K0/Kx2)
如上所述,通过周期性地检查端口,从键开关捕捉数据。但在实际应用中,有可能在待机状态下使用微控制器,以降低功耗,并在按下键时返回操作状态。对于这种 情况可以使用中断。对于这种应用的中断设计,除通过脉冲沿检测中断外,还有一个方法,叫做按键返回中断。
上例中显示的键开关通常情况下保持高电平,当按下键时变为低电平。通过检测低电平,按键返回中断产生一个中断。与一般的通过脉冲沿检测中断不同,该中断可以检测8个输入信号KR0 ~ KR7中的任意一个信号的低电平。
如果有键被按下,按键返回中断就进行检测,并释放微控制器的待机状态,使CPU开始操作。之后,读取端口(P7),确认按键。
78K0/Kx2的按键返回中断可以配置为,将一般按键输入的键和释放待机状态的键组合在一起,因为它具有位单元屏蔽功能。例如,在下面的配置中,使用了 8个键开关,由微控制器的内部上拉电阻上拉。按键返回中断用于#1 ~ #4,分别连接到P70 (KR0) ~ P73 (KR3),而不用于#5 ~ #8(由KRM屏蔽)。当按下#1 ~ #4中的一个键时,由按键返回中断释放待机状态。但当按下#5 ~ #8中的一个键时,则不能释放待机状态,因为没有产生按键返回中断。可以像这样以不同的用法使用键开关。



[一般中断的按键检测]
如果按键不能通过按键返回中断检测,可以使用一般的脉冲沿检测中断输入。但是由于脉冲沿中断的数目有限,必须做些处理。在下面的例子中,Px0 ~ Px7(用于扫描键)是N-ch漏极输出端口。当使用一般CMOS输出端口时,按如图所示方向连接二极管,这样电流不会从输出端口流出(参阅"其它方法")。
在这种方法中,从一个输出端口输出低电平,用于键扫描,并监控当时的INTPn引脚状态,这样就可以检测到键的状态。例如,如果按下图中所示的#2键,仅 当连接到此键的Px1为低电平时,INTPn引脚才变为低电平,而当其它输出为低电平时它将保持高电平。用这样方法可以判断是否有键按下。由于键是依次检 测的,最坏情况 下需要检测8次按键状态,才能检测到按下的是哪个键。



在这个例子中,当按下指定键时会产生中断,和按键返回中断的情况一样。例如,按下#1 ~ #3键,在Px0 ~ Px3输出低电平,可以产生INTPn。当产生中断时,再次扫描键,从Px0开始,以确定那一个键被按下。
 
其它方法
如果微控制器没有N-ch漏极输出端口,且无法连接二极管,应该怎样做?
在这种情况下,将端口的所有输出锁存设置为0,由PM寄存器将输出为低电平的端口设置为输出模式。
其它端口被设置为输入模式。用这种方法可以模拟N-ch漏极输出,还可以缩短扫描时间,因为行可以上升为高电平。

[键矩阵]
如果使用的键的数目比较少,可以将键直接连接到端口。但是如果键太多,将键连接到很多端口,并不是一个有效做法。因此可以将键矩阵和输出端口结合使用。下图所示是一个4 x 4矩阵的例子。假定由内部电阻上拉输入端口,并且输出端口为N-ch漏极端口。


 
注:
如果同时按下#1和#5,通过键开关#1和#5连接第1和第2行。如果此时的输出端口是通常的CMOS输出端口,则会输出高电平和低电平,从而引起设备损 坏,且电流比流经键开关的电流大。为避免出现类似的情况, 键扫描必须使用N-ch漏极输出端口。“其它方法”中描述的输入模式和输出模式之间可以切换的CMOS输出端口也可以作为一种选择。
如果#6和#1与#5一起被按下,会出现另一个问题。扫描第1行时,通过#1和#5,第2行也变为低电平。如果这时按下连接到第2行的#6键,I2输入也 变为低电平。换句话说,会误认为#2键也被按下, 实际上并没有被按下。这是因为流经#5的电流方向与通常的电流方向相反。解决这个问题的一种方法是连接一个二极管,这样电流仅在一个方向流动(如右下图所 示)。
尽管连接二极管可以不需要N-ch漏极输出端口,但成本提高了,因为必须将二极管连接到每个键开关。
因此在有些情况下,仅将二极管连接到一个键,该键可能和另一个键一起被按下。
这种方法也可以用于使用低导通电阻的机械开关中。如果连线的导通电阻和开关增加到一定程度,则输入电阻分割电压,而不是开/关信号。在此情况下,如果象上例中按下三个开关, 信号将流经三个开关,则该信号不会变为低电平。因此,可以避免误操作。

[扫描]
当使用键矩阵时,可以使用输出端口、顺序设置为低电平扫描线,并依次从输入端口读取,对按下的键进行识别。下面是使用上述键矩阵的扫描键的例子。
如要获取程序示例,可参阅[键扫描中的消抖处理]



如果当第1行被设置为低电平(被扫描)时输入到I1的为低电平,则表示按下的是#1。同样,如果在扫描第2行时输入到I1的为低电平,则表示按下的是#5。这样通过扫描行和输入相结合,可以识别 被按下的键。
 
2:
在使用漏极输出端口时,当扫描结束且输出信号上升为高电平时,输入端口状态不会立即变成高电平。是由上拉电阻将输入端口变为高电平。因为输入行的电容必须 通过电阻充电,所以信号上升 比较慢。如果扫描间隔很短,则当扫描第一行时按下#1键时的输入信号(低电平)将保持到第2行被扫描,则判断为没有被按下的#5是被按下的键。因此扫描和 检测键的时序如下例所示 发生移位。通过定时器中断(触发扫描)检测先前扫描的结果指之后,再开始扫描下一个键,完成中断处理过程。对于扫描间隔的信号变化给出了一个时间极限。
此外,可以通过输出低电平、检测键以及把输出变为高电平,来缩短一行的上升时间。使用一般的CMOS输出(如"其它方法"中描述的),在没有输出低电平时设置 为输入端口,是很有用的方法。 加上输入/输出,不但可以有效地控制输出数据,而且可以缩短扫描间隔。


[消抖的处理过程]
下面给出两个防噪声的程序例子。这两个程序通过使用78K0/Kx2的P7(按键输入)和在间隔定时器的周期性中断中检测8位按键输入的状态,来消除噪 声。要使用其它设备,应将P7转换成其它适合的端口。如果 所用位数小于等于8,则在读取键数据后屏蔽未使用位。在周期性的执行定时器中断处理过程中要包含并执行这些程序。

[程序举例1]
(1)程序概述
该程序比较扫描的两个结果,并根据比较结果,执行下面的处理过程。          当键显示变化时:与键相对应的位,使用前面的有效键的数据。
当该键与先前扫描的键相同时:与键相对应的位, 使用当前的扫描结果。
除非在一行中多次输入相同的值,否则无法捕捉键扫描结果。因此,可以消除采样到的噪声。考虑随机按下两个以上键的情况,通过对每位执行操作,而不是使用条件分支,来识别变化。

(2)变量
把由该程序获得的有效按键输入到KEYDATA。程序参考KEYDATA的值,用于结果输出和先前的有效按键输入。此外,OLDDATA用于保持先前的键数据。

(3)处理过程

将读取的键数据保存在变量OLDDATA中,这样数据可以用于下一次扫描,并与先前保存在OLDDATA中的扫描结果进行比较(XOR),这样可以检测键数据的变化。
2.gif通过反转XOR结果的逻辑值,将已修改的位清零,并与扫描结果进行与(AND)操作。这样已改变的位被清零,而没有改变的位表示扫描结果。
保存已获得的且没有改变的键数据,而已改变的位和保存在变量KEYDATA中的先前有效按键输入进行与操作。这样,没有改变的键数据的位被清零,已 改变的位表示先前的数据。
通过对上述操作获得的两个结果进行或(OR)操作,可以获得最终结果,并将该结果保存在变量KEYDATA中。


(4)程序举例


[程序举例2]
该程序可以获得键变化(按下的键和释放的键)的信息。这是基于第一个程序的处理结果,添加了检测变化的处理过程。当按下一个新的键(当按键输入数据变为0 时)时,设置PUSHKEY的相应位。当释放键时,设置RELKEY相应位。这样就可以获得键的变化信息。注意该信息不能保存,每次扫描键时信息 被更新。

 
3:
在两个程序的第五十行,把在第2个按键扫描数据时发生变化的位设置为1,未变化的位设置为0,然后将数据保存在寄存器A和X中。至此第一个程序程序和第二个程序都是一样的。接下来的两条指令就不同了,但获得的结果是相同的。
因为OLDDATA的1位用于未改变的位(捕捉到键),已改变的位(在A或X中值为1的位)必须清零。因此,在第1个例子中,将A寄存器中数据的补码与 OLDDATA进行与操作清零 已改变的位。在第2个例子中,通过A寄存器和OLDDATA的或(OR)操作,将OLDDATA的已修改位设置为1,并通过该位与X寄存器的异或操作将该 位清零。关于这两个操作之间的关系,可参考下面的表达式。

[键扫描中的消抖处理]
(1)程序概述
考虑之前例子中给出的16键(4 x 4)的矩阵。P7的高4位用于扫描数据,低4位用于读取数据。(P7是常用的CMOS输出端口。因此,将二极管连接到该端口, 以使电流从扫描行流向该端口,或者将二极管连接到每个键,如“注”中描述的。) 根据使用的端口结构和设备,对端口进行读取或扫描。

(2)程序操作
该程序使用了两个中断: 按键返回中断和定时器(定时器51)中断。它首先选择第1行但不扫描键,使用按键返回中断进行等待,直至#1 ~ #4的任意一个键被按下。当#1 ~ #4的任意一个键被按下并产生按键返回中断时,激活定时器并启动键扫描。启动键扫描后,每当产生定时器中断时扫描1行(大约每10 ms产生1次)。按以下循环执行。

第1行 → 第2行 → 第3行 → 第4行 → 第1行 ...

当产生4次定时器中断时,完成所有行的扫描。将扫描结果按顺序存储在KEYDATA1 ~ KEYDATA4中,并从第1行开始执行。

(3)数据区 (变量)
基本处理过程与上面描述的[消抖的处理过程]中的[程序举例1]相同。每次扫描键时使用的数据区的定义如下,初始值为0FH。由于是使用HL寄存器访问这些区域,所以无需将它们分配到SADDR区。此外,还提供一个变量(SCANLINE)指定扫描行。



(4)初始化程序
由于是周期性地执行程序的处理过程,所以使用了间隔定时器中断。因此,程序被划分为两部分,一部分为初始化过程,另一部分是实际的处理过程。在设备的初始 化例程中包含并执行该初始化处理过程。该初始化部分选择端口模式、设置定时器和按键返回中断。在默认状态下不扫描键,并当按下第1行的#1 ~ #4(对应P77)中的一个键时设置状态并产生按键返回中断。仅对定时器初始化,并停止定时器操作。




(5)键扫描的初始化处理过程
这部分对扫描端口进行设置,对变量初始化,并对按键返回和定时器功能进行初始化。按键返回和定时器功能也不启动。



(6)通过按键返回中断进行键扫描启动处理过程
当产生按键返回中断,并启动该处理过程时,启动用于键扫描的定时器。之后,禁止按键返回中断。



(7)定时器中断处理过程
键扫描处理又称为周期性产生定时器中断处理过程的子例程。



(8)键扫描处理过程
这部分由周期性定时器中断启动,并扫描键。该处理过程被划分为三个主要部分。
第1部分,计算存储扫描结果的指针。为了减少输入参数的数目,并尽可能不使用条件分支,应该通过计算获取必要的信息。
第2部分,从端口实际读取扫描数据,并实施消抖和防噪声措施。如果不需要这样具体的处理过程,而仅使用采样消抖,则从端口读取数据并保存在数据区就足够了。
第3部分,为扫描下一个键做准备工作。扫描行变为下一行,并将扫描新一行所需要的数据输出到端口。



4:
更新扫描行的处理过程中有4个扫描行,0 ~ 3,可以用2位表示。通过加1和屏蔽其它位(不是低2位),可以获取新的扫描行。
把用于指定被实际扫描的行的数据写入端口寄存器。使用的数据只需1位清零。但由于只使用了高4位,简单地将数据右移是不够的。当扫描完4行时端口数据为 1110XXX。即使数据右移,位7也不能 被清零。因此仅当第1行(扫描行)为0时该程序将进位标志清零,并在其它情况下设置进位标志。仅当扫描第1行时,带进位右移数据,将第7位清零。用这种方 法执行处理过程不需要使用条件分支指令。
Suitable Products
  • 这篇文章对您有帮助吗?