- UID
- 1062083
- 性别
- 男
|
本帖最后由 yuchengze 于 2016-12-27 09:56 编辑
说到按键,我还是有不少研究的,其实按键没我们想的那么简单,要把按键程序写好也不是一件容易的事,功能要求:单击、双击、长按及组合,按下不动,返回有效值速度越来越快,多用在参数调节,这些都是值得大家去研究的,还有8个IO口,让16个独立按键与8个独立按键共同使用这是没有问题的。
扯远了,今天只讨论如何做松手检测,松手检测意义,很简单,就是按下按键只对应一次操作,不会因为按着不动就不停的返回按键值,我们大多时候见到的松手检测程序就是 “while(!k1)”,一种等待式写法,打个比方,这就如同你插上热得快烧水,你坐在旁边看着,等着水热,拜拜浪费时间。这种写法根本不适应实际应用,拜拜浪费CPU时间。看一下代码:
功能:按键检测子函数,四个独立按键接在P2口高四位,调用时返回按键值1,2,3,4,没有按键按下返回0.
char ReadKey(void)
{
static Key_on_off = 0;
unsigned char num,temp = 0;
num = P2; // 读取P2口状态
num&= 0xf0; // 屏蔽第四位
if(num != 0xf0) // 判断是否有按键按下
{
if(Key_on_off == 0) // 自锁变量
{
/*********** 相对高级的松手检测 ****************/
Key_on_off = 1; // 如果屏蔽这句话,将没有松手检测,数字将加的很快
switch(num) // 读取按键信息
{
case 0xe0: temp=1;break;
case 0xd0: temp=2;break;
case 0xb0: temp=3;break;
case 0x70: temp=4;break;
}
/*********** 最笨的松手检测 ****************/
/* while(num != 0xf0) // 判断是否有按键按下
{
num = P2; // 读取P2口状态
num&= 0xf0; // 屏蔽第四位
} */
}
}
else
{
Key_on_off = 0; // 当没有任何按键按下时 解锁
}
return temp;
}
利用一个静态变量Key_on_off,记住一定要是静态的或者全局的,初始化为零,当检测到按键按下的时候,同时要满足Key_on_off等于0,才进入里面判断是哪个按键,同时将Key_on_off置1,那么当按键还没有松开,函数又被第二次及以上调用时,由于Key_on_off等于1,就不按键值解析里面去,按键值返回的是默认的0,属于无效值,着就相当于上了一把锁,那么什么时候解锁了,看下面当检测到没有按键按下的时候,Key_on_off = 0 , 一担松手就解锁,当再次按下的时候出一次有效按键值,再次上锁。如此往返。。。
更过关于按键的设计,请持续关注帖子。。。
代码+protues仿真在附件。
本人是“WS”,对你有用,请点个赞。。。
今天有人提到了我的程序中没有去抖动检测,关于按键的抖动,别人教你的一半都是延时5~10MS再次检测, 想说的是,延时去抖动会拖慢的系统,5MS在我看着这么多么的奢侈,5MS单片机可以执行完成太多的任务,就这么浪费了, 痛心、痛心。
本函数调用要求为:20~50ms调用一次,就能得到很好的消抖动效果,你可以想象一下,在时间轴上,0时刻检测到按键按下,到10ms时刻再次检测到按键按下,就确定按键按下。首先大家要明白一点,只有按键按下的时候才有电平抖动,没有按按键是没有按键抖动的,去按键抖动是为了防止一次按下按键而而检测到几次按下。在看看我的设计,0时刻检测到按键按下,那么按键肯定按下了,我已经返回了有效值,20MS后抖动已经过去,低电平已经稳定,不会再返回按键有效值,达到去抖动目的。。。 |
|