理论教育 如何读取单个按键状态

如何读取单个按键状态

更新时间:2025-01-03 理论教育 版权反馈
【摘要】:在图5-7中,单片机引脚RB0连接两个元件:电阻R9和按键S1的一端。为了读取按键S1的状态,RB0必须要置为输入状态。图5-9 单个按键状态读取实验电路图程序分析●按键SW的电路功能前文已经分析过,当RD0引脚用做输入引脚时,按键SW未按下时RD0为高电平;按键SW按下时RD0为低电平。本例子是读取单个按键的例子,这种思想可以扩展到多个按键的读取。下面给出3个按键的读取方法,读者可以照搬这种模式实现2个、4个按键的读取方法。

在控制类应用中,最简单的输入就是按键式输入,用户按一个键(钮)后,控制电路实现相应功能。这就要求单片机能够识别按键的两种不同状态:按下和未按。一般都是通过如图5-7所示的电路来实现两种状态的区别。

在图5-7中,单片机引脚RB0连接两个元件:电阻R9和按键S1的一端。为了读取按键S1的状态,RB0必须要置为输入状态。下面分析RB0的输入情况。

●当按键S1未按下时,RB0通过电阻R9与电路中的供电电源信号VCC相连,使RB0的电位也为电平,即RB0输入值为1。

●当按键S1按下时,RB0与接地信号GND相连,使RB0输入为低电平,即逻辑的0。由于有R9的存在,即使按键S1按下也不会使VCC和GND短路。

这里的R9被称为上拉电阻,对于本电路必须加,若不连接R9则RB0悬空,当按键S1未按时,RB0输入电平值不确定,这样就无法判断按键S1是否按下了。

这样通过指令读取RB0引脚的状态即可得知外部的按键按键S1是否按下。但是由于机械按键存在按键接触点的抖动问题,在按键S1按下过程中RB0不是立刻变为低电平,而是有一个抖动过程,如图5-8所示。

978-7-111-33274-9-Chapter05-26.jpg

图5-7 单片机读取机械式按键电路图

978-7-111-33274-9-Chapter05-27.jpg

图5-8 按键输入引脚电平抖动示意图

机械按键从按下到抬起过程实际上是一个连续的机械零件动作:按键S1按下去的过程中有一段时间电平忽高忽低,术语称为前沿抖动。前沿抖动过后按键才真正按下去,状态才稳定。当按键S1抬起的过程还有一段时间电平不稳定,术语称为后沿抖动。

这样在实际单片机读取按键时为了防止误判,要加入消除抖动处理,最简单的消抖方法就是软件延时。

对于普通人而言,正常的单击按键动作一般需要20ms左右。按键稳定阶段大约12ms。这里可以认为在按键从按下到松开的中间时刻按键状态是稳定的。

对于单片机而言,检测到按键有变化后,软件延时10ms(经验值)再读取按键状态方能得到正确的按键状态。

下面通过一个简单的例子来学习单个按键的读取方法。

【例5-6】硬件电路如图5-9所示。要求编程实现每按一次按键S1使数码管显示内容加1。

电路图在光盘位置:“\Example\Chapter5\S054\sch\smg4key1.dsn”。

978-7-111-33274-9-Chapter05-28.jpg(www.daowen.com)

图5-9 单个按键状态读取实验电路图

程序分析

●按键SW的电路功能前文已经分析过,当RD0引脚用做输入引脚时,按键SW未按下时RD0为高电平;按键SW按下时RD0为低电平。由于机械按键部件使用时存在机械抖动,所以在程序中要做消抖处理(消抖包括消除前沿抖动和后沿抖动)。

●对于数码管显示,由于在例5-5中已经把数码管显示代码做成了两个模块文件seg74.h和seg74.c,所以把其相关模块文件添加到当前项目中就可以直接使用数码管显示函数了(不需要重新编写函数内部代码)。

设计过程

1)用MPLAB新建项目S054,语言工具选择为“HI-TECH Universal Toolsuite”,保存在“C:\S054”文件夹下。

2)新建main.c文件并加入项目中,其内容如下所示。

978-7-111-33274-9-Chapter05-29.jpg

978-7-111-33274-9-Chapter05-30.jpg

3)本例中还需要新建delay.h、delay.c、seg74.c、seg74.h4个文件。其内容与例5-5中的4个文件完全相同,用户可以直接将其复制到本项目文件夹下并加入项目中使用。

4)所有需要的5个文件添加完毕后成功编译出目标文件,然后用调试工具Proteus VSM加载smg4key1.dsn来运行程序。运行时每按一次按键S1后观察数码管内容变化,正确的情况是每按一次按键S1,数码管显示内容加1。效果分析

●细心的读者会发现有时按了按键SW后数码管并没有加1。这是因为读者按SW的时机恰好在程序执行数码管扫描程序期间(DisplayData函数没有执行完),而在判断S1前SW就被松开了,这样程序就会出现没有正确判断SW按下的问题。解决这个问题的方法有两种:第一种方法是缩短数码管扫描函数中的延时时间;第二种方法是采用中断来处理按键事件(可参考后文中断章节相关内容)。

●有时按了一次SW后数码管会加2或者更多,这是为什么呢?读者可以实验一下,按住SW不松手,发现数码管显示内容会连续增加。这是因为此程序中仅判断了按键是否按下,如果SW被一直按住,则每次判断都认为SW按下并执行加1操作,所以按住SW时其值会不停增加。如果想避免发生这种情况,可以在代码中加入消除按键的后沿抖动判断代码。一段参考代码如下所示。

978-7-111-33274-9-Chapter05-31.jpg

978-7-111-33274-9-Chapter05-32.jpg

本例子是读取单个按键的例子,这种思想可以扩展到多个按键的读取。下面给出3个按键的读取方法,读者可以照搬这种模式实现2个、4个按键的读取方法。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈