【按键】[独立按键] - 1: 单击,双击,三击以及N击
2016-03-23 18:03
288 查看
此按键程序的实现的功能是单个独立按键的[单击],[长按],[双击],[三击]以及[多击]。本文分为三个部分,
第一个部分是说[单击],[长按]的程序;
第二部分是讲[双击];
第三部分是讲[三击],[N击];
首先看一张时序图:
注:
T1:是单击的按键消抖时长,这里预设的是30ms,也可以根据需求自行定义;
T2:是单击时,按键释放的有效时间段,提前或者超过这个时间段释放的按键都再是单击了。提前释放则是无效键值,超过后释放则是长按。
T3:是长按时长,按键超过此时长,则为长按。这里的预设值是3s,同样可根据需求自行更改。
【单击】:按键按下超过消抖时长T1(30ms),并且在T2时间段内释放按键,按键一释放,马上返回有效按键值—【单击】。
注意:单击是释放后,才返回有效按键值,不释放时,是无效按键值。
【长按】:按键按下的时间超过预设的长按时长T3(3s) ,马上返回有效按键值—【长按】;
注意:长按是只要按下的时间超过预设的长按时长,马上返回有效键值。但是,如果按键一直按着不释放,则只返回一次有效按键值,不重复返回,直到释放之后,才开始重新读取键值。
第一部分:判断有无按键按下;
第二部分:按键是否有效(按键消抖);
第三部分:确定有效按键的种类(单击还是长按);
第四部分:等待按键释放。
以下是key.c 的源代码:
使用注意:
1)硬件:按键的一端接地(GND),另一端接IO口。IO为输入,一定要有上拉电阻。
2)定时器:这里为了精确的定时,所以使用了定时器,定时器的时间是10ms。
3)扫描周期:调用此函数时,一定确保”扫描周期“要小于10ms。不然按键内所涉及的时间就会不准,会偏大。所涉及的时间包括消抖时长,按键长按时长等。
扫描周期定义:从 第一次进入按键扫描程序 开始,到第二次进入按键扫描程序时 结束,之间所用的时间。
测量扫描周期的方法:可以在按键扫描程序的第一句,添加IO口取反函数,然后用示波器查看改IO口,其IO口周期的一般就是扫描周期了。
1)实例程序的功能:
单击:点亮LED1
长按:熄灭LED1
2)硬件:
按键IO:P1.0
LED1 :P2.0
以下是 main.c 源代码:
Pillar Peng
2016.3.23 18:00
其余分享链接:
第二部分:【按键】[独立按键] - 2: 双击
第三部分:【按键】[独立按键] - 3: 三击以及N击
第一个部分是说[单击],[长按]的程序;
第二部分是讲[双击];
第三部分是讲[三击],[N击];
一、 [单击]、[长按]程序
1. 简单介绍本按键程序的单击和长按
首先说一下单击,长按的响应情况,就是按多久算单击或者长按,按下按键马上返回有效键值,还是释放之后返回有效键值等等,下面说下它在什么情况下返回有效的【单击】和【长按】。首先看一张时序图:
注:
T1:是单击的按键消抖时长,这里预设的是30ms,也可以根据需求自行定义;
T2:是单击时,按键释放的有效时间段,提前或者超过这个时间段释放的按键都再是单击了。提前释放则是无效键值,超过后释放则是长按。
T3:是长按时长,按键超过此时长,则为长按。这里的预设值是3s,同样可根据需求自行更改。
【单击】:按键按下超过消抖时长T1(30ms),并且在T2时间段内释放按键,按键一释放,马上返回有效按键值—【单击】。
注意:单击是释放后,才返回有效按键值,不释放时,是无效按键值。
【长按】:按键按下的时间超过预设的长按时长T3(3s) ,马上返回有效按键值—【长按】;
注意:长按是只要按下的时间超过预设的长按时长,马上返回有效键值。但是,如果按键一直按着不释放,则只返回一次有效按键值,不重复返回,直到释放之后,才开始重新读取键值。
2. 按键程序的架构
按键程序可以分为四个部分,第一部分:判断有无按键按下;
第二部分:按键是否有效(按键消抖);
第三部分:确定有效按键的种类(单击还是长按);
第四部分:等待按键释放。
3. 按键程序的源代码以及注释
程序的注释写的很详细,应该是可以读懂的,如果有疑问可以留言讨论。以下是key.c 的源代码:
//============================ key.c =================== #define KEY_INPUT P1.0 // 按键IO #define KEY_STATE_0 0 // 按键状态 #define KEY_STATE_1 1 #define KEY_STATE_2 2 #define KEY_STATE_3 3 #define LONG_KEY_TIME 300 // LONG_KEY_TIME*10MS = 3S #define SINGLE_KEY_TIME 3 // SINGLE_KEY_TIME*10MS = 30MS #define N_KEY 0 // no click #define S_KEY 1 // single click #define L_KEY 10 // long press unsigned char key_driver(void) { static unsigned char key_state = 0; // 按键状态变量 static unsigned int key_time = 0; // 按键计时变量 unsigned char key_press, key_return; key_return = N_KEY; // 清除 返回按键值 key_press = KEY_INPUT; // 读取当前键值 switch (key_state) { case KEY_STATE_0: // 按键状态0:判断有无按键按下 if (!key_press) // 有按键按下 { key_time = 0; // 清零时间间隔计数 key_state = KEY_STATE_1; // 然后进入 按键状态1 } break; case KEY_STATE_1: // 按键状态1:软件消抖(确定按键是否有效,而不是误触)。按键有效的定义:按键持续按下超过设定的消抖时间。 if (!key_press) { key_time++; // 一次10ms if(key_time>=SINGLE_KEY_TIME) // 消抖时间为:SINGLE_KEY_TIME*10ms = 30ms; { key_state = KEY_STATE_2; // 如果按键时间超过 消抖时间,即判定为按下的按键有效。按键有效包括两种:单击或者长按,进入 按键状态2, 继续判定到底是那种有效按键 } } else key_state = KEY_STATE_0; // 如果按键时间没有超过,判定为误触,按键无效,返回 按键状态0,继续等待按键 break; case KEY_STATE_2: // 按键状态2:判定按键有效的种类:是单击,还是长按 if(key_press) // 如果按键在 设定的长按时间 内释放,则判定为单击 { key_return = S_KEY; // 返回 有效按键值:单击 key_state = KEY_STATE_0; // 返回 按键状态0,继续等待按键 } else { key_time++; if(key_time >= LONG_KEY_TIME) // 如果按键时间超过 设定的长按时间(LONG_KEY_TIME*10ms=200*10ms=2000ms), 则判定为 长按 { key_return = L_KEY; // 返回 有效键值值:长按 key_state = KEY_STATE_3; // 去状态3,等待按键释放 } } break; case KEY_STATE_3: // 等待按键释放 if (key_press) { key_state = KEY_STATE_0; // 按键释放后,进入 按键状态0 ,进行下一次按键的判定 } break; default: // 特殊情况:key_state是其他值得情况,清零key_state。这种情况一般出现在 没有初始化key_state,第一次执行这个函数的时候 key_state = KEY_STATE_0; break; } return key_return; // 返回 按键值 }
使用注意:
1)硬件:按键的一端接地(GND),另一端接IO口。IO为输入,一定要有上拉电阻。
2)定时器:这里为了精确的定时,所以使用了定时器,定时器的时间是10ms。
3)扫描周期:调用此函数时,一定确保”扫描周期“要小于10ms。不然按键内所涉及的时间就会不准,会偏大。所涉及的时间包括消抖时长,按键长按时长等。
扫描周期定义:从 第一次进入按键扫描程序 开始,到第二次进入按键扫描程序时 结束,之间所用的时间。
测量扫描周期的方法:可以在按键扫描程序的第一句,添加IO口取反函数,然后用示波器查看改IO口,其IO口周期的一般就是扫描周期了。
4. 按键程序的使用实例
这里以C51位硬件平台进行实例讲解1)实例程序的功能:
单击:点亮LED1
长按:熄灭LED1
2)硬件:
按键IO:P1.0
LED1 :P2.0
以下是 main.c 源代码:
//============================ main.c =================== #include "reg51.h" #include "key.c" sbit LED1 = P2.0; // 定义LEDIO口 unsigned char g_u8_KeyValue; // 按键值 unsigned char g_flag_10ms_key; // 10ms 计时标志 //timer0,初始化函数 ,定时时间为 10ms void T0_Init_10ms(void) { TMOD |= 0x01; TH0 = (65535 - 10000)/256; TL0 = (65535 - 10000)%256; ET0 = 1; TR0 = 1; EA = 1; } //主函数 void main(void) { P1.0 = 1; // P1.0 拉高 T0_Init_10ms(); // 定时器0,初始化,定时10ms while(1) { if(g_flag_10ms_key) // 等待10ms,定时完成 { g_flag_10ms_key = 0; // 清零10ms定时标志 g_u8_KeyValue = key_driver(); // 读取按键值 switch(g_u8_KeyValue) { case S_KEY: LED1 = 1; break; // 单击 点亮LED1 case L_KEY: LED1 = 0; break; // 长按 熄灭LED1 } } } } //timer0 中断服务程序 void IRQ_T0(void) interrupt 1 { g_flag_10ms_key = 1; // 置位 10ms 定时标志 }
Pillar Peng
2016.3.23 18:00
其余分享链接:
第二部分:【按键】[独立按键] - 2: 双击
第三部分:【按键】[独立按键] - 3: 三击以及N击
相关文章推荐
- Win7 不能运行bat
- C#控制键盘按键的常用方法
- C#实现自定义双击事件
- javascript 双击文本框编辑功能代码
- JS实现双击编辑可修改状态的方法
- javascript 响应键盘特定按键(只响应数字键)
- 单击复制文字兼容各浏览器的完美解决方案
- IE下双击checkbox反应延迟问题的解决方法
- Swift中实现点击、双击、捏、旋转、拖动、划动、长按手势的类和方法介绍
- Java List双击事件实现方法
- JS实现获取键盘按下的按键并显示在页面上的方法
- Unity3D获取当前键盘按键及Unity3D鼠标、键盘的基本操作
- JavaScript Event学习第十一章 按键的检测
- javascript实现单击和双击并存的方法
- Android双击返回键退出程序的实现方法
- JS实现双击屏幕滚动效果代码
- js获取及判断键盘按键的方法
- Python可跨平台实现获取按键的方法
- Vue.js学习系列(四十)-- 修饰符(一)
- 按键精灵脚本