短按,长按,按键释放,三种模式的按键扫描程序(软件消抖动)

先来说一下这三种模式的意思:

1. 短按模式:单击按键时,返回一次有效按键值;长按时也只返回一次有效按键值。这样可以有效地排除因不小心长按带来的返回多次有效按键,进而执行多次按键处理程序。

2. 长按模式: 单击按键时,返回一次有效按键;长按时,返回多次有效按键值。这样可以很快的调节某个较大的参数,比如时间的时分秒参数。

3. 按键释放模式:这个模式与短按模式是相对的。短按模式只要按键按下去,立即返回有效键值,进而试行按键处理程序;二按键释放模式,却是要等到按下键,释放之后,才会返回有效键值,进而执行按键处理程序。

接下来说一下扫描程序: 1)采用的是轮询的方式(非中断) 2)消抖动的方式:多次扫描,来确定按键值。下面的程序的是设定了5次。主要是根据扫描周期来确定,,次数的多少。 注: 扫描周期:从进入按键扫描程序开始,直到到下一次进入按键扫描程序时 结束,之间所用的时间。

下面是整个按键扫描程序的源码,可以读一读,语句都很简单,而且每一句都有注释,一步一步看下去,应该能明白。 如果不明白,可以留言谈论。 以下是 KeyScan.c 文件的内容,

g_uiCurrKey;g_uiLastKey;g_uiKeyScanCount;g_uiKeyDown;g_uiKeyRelease;g_uiKeyContinue;Int_Key_Scan(void){LastReadKey;CurrReadKey;//当前从IO口读取的键值CurrReadKey = P0 & 0x00ff;//获取当前的键值if(CurrReadKey == LastReadKey)//如果当前读取的键值与上次从IO口读取的键值相同{if(g_uiKeyScanCount >= KEYDEBOUNCE) //首先判断是否大于等于debounce的设定值(即是,是否大于等于设定的采样次数){//按住不放,多次响应g_uiCurrKey = CurrReadKey;(g_uiPreKeyValue == g_uiCurrKey){g_uiKeyDown = 0xff;//没有键值}else{g_uiKeyDown = g_uiCurrKey;//如果不同,按键有效,(就是第一次有效值时)}//按键释放时,按键值才有效if(g_uiCurrKey == 0xff)//当有效按键值从非0到0的状态时(即是,从有按键到无按键,表示已经释放了),表示之前按键已经释放了{g_uiKeyRelease = g_uiPreKeyValue;}g_uiLastKey = g_uiCurrKey;//记录上次有效按键值}else//如果否,则debounce加一(如果否,则继续采样键值){g_uiKeyScanCount++;}}else//如果当前读取的键值与上次从IO口读取的键值不同,说明按键已经变化{g_uiKeyDown = 0xff;//放开按键后第一次进入扫描程序,清零g_uiKeyDown.作用:消除一个BUG(你猜BUG是什么?)g_uiKeyScanCount = 0;//清零之前的按键的debounce计数LastReadKey = CurrReadKey;//将当前读取的键值记录为上次读取的按键值} }

以下是KeyScan.h文件内容

g_uiCurrKey;g_uiLastKey;g_uiKeyScanCount;g_uiKeyDown;g_uiKeyRelease;g_uiKeyContinue;Int_Key_Scan(void);

使用注意: 1.作为按键使用的相应IO口,必须设置为输入模式(如果是51单片机的话,无需关心) 2.按键的硬件连接必须是一端接GND,一端接IO口。

下面介绍一下程序的使用方法: 这里以51单片机的 按键点亮和熄灭LED灯作为例子。 硬件: 1)按键使用单片机的P0端口 2)LED灯使用P1.0的IO口,低电平点亮

返回的按键值: 没有键按下, 返回键值是0xFF 如果P0.0按下,返回键值是0xFE 如果P0.1按下,返回键值是0xFD 如果P0.2按下,返回键值是0xFB 如果P0.3按下,返回键值是0xF7 … 如果P0.7按下,返回键值是0x7F

下面是例子的参考源码:

//======================================================//main.c//======================================================#include “reg51.h”#include “KeyScan.h”sbit LED = P1.0;//定义LEDIO口void main(void){P0 = 0xff;LED = 0;//点亮LEDwhile(1){Int_Key_Scan();//按键扫描程序//第一种:KeyDown的使//单按时和长按时,都只返回一次有效键值(无需等到按键释放,就可以返回有效键值)switch(g_uiKeyDown){case 0xFE://P0.0按键程序LED = !LED;break;case 0xFD://P0.1按键程序//…break;case 0xFB://P0.2按键程序//…break;case 0xF7:break;case 0xEF:break;case 0xDF:break;case 0xBF:break;case 0x7F:break;case 0xFF://没有按键程序//…break;}//第二种:KeyRelease的使用//只有当按键释放之后,才返回一次有效键值,即是按键释放后,才执行相应的函数switch(g_uiKeyRelease){case 0xFE://P0.0按键程序LED = !LED;break;case 0xFD://P0.1按键程序//…break;case 0xFB://P0.2按键程序//…break;case 0xF7:break;case 0xEF:break;case 0xDF:break;case 0xBF:break;case 0xEF:break;case 0xFF://没有按键程序//…break;}//第三种:KeyContinue的使用//1)单次按键(非长按),返回一次有效值。//2)长按,返回多次相同有效值switch(g_uiKeyContinue){case 0xFE://P0.0按键程序LED = !LED;break;case 0xFD://P0.1按键程序//…break;case 0xFB://P0.2按键程序//…break;case 0xF7:break;case 0xEF:break;case 0xDF:break;case 0xBF:break;case 0xEF:break;case 0xFF://没有按键程序//…break;}}}

pillarpeng 2015.5.25 18:23

见过旅行风景,就这样,慢慢学会了长大。

短按,长按,按键释放,三种模式的按键扫描程序(软件消抖动)

相关文章:

你感兴趣的文章:

标签云: