您的位置:首页 > 其它

一种基于中断的按键检测方法

2017-02-18 12:43 302 查看
slam_navigation原创:

按键检测是初学单片机的同学玩的前几个例程,按键的种类有许多(普通按钮,矩阵键盘等等),按键检测的方法也有许多。对于普通按钮当然你会说设计一个外围电路通过GPIO口读一下还不简单,或许你说通过外部中断做边沿检测,对于矩阵键盘来说,往往你会通过行列分别扫描的方法做按键检测,通常我们会加一个按键防抖(经典的方法是通过延时二次确认的方法进行按键防抖,还有就是按键释放的时候你可能会通过while语句去防抖,也就是按键如果一直按下,让程序一直死在while里),这些都是初学者常用的方法,但是如果是一个大的程序,往往是不允许你有这么多延时和死循环的。

中断是一个经常使用的按键检测方法,中断之间的时间就可以作为防抖的处理,而且这种方法适用于程序融合,因为其他传感器的数据读取通常也是通过中断的手段去做的(如摄像头)。我这里给出一个问题和一个解决办法。

问题:设计一个按键检测程序(多按键),通过中断去读取,要求只有在按键更新的时候才会在主程序里做出响应,否则不理睬,要求设计防抖动,只有两次检测为真时,才进行键值的更新,真值表如下。

IN_old_stableIN_oldIN_newIN_new_stable
0000
0010
0100
0111
1000
1011
1101
1111
IN_old_stable为旧的确定值。

IN_new_stable为新的确定值。

IN_old为上次读取的按键值。

IN_new为最新读取的按键值。

当然每次中断后都需要做一次迭代:

IN_old=IN_new;

IN_old_stable=IN_new_stable;

只有新的确定值是我们值得信赖的。

由真值表的计算规则:

IN_new_stable:     D

IN_old_stable:       A

IN_old:                    B

IN_new:                  C

有:



所以有:



解决:我以STM32F103为例,需要读取GPIO,B口的低四位。

我们首先在中断里最如下处理:

IN_old=IN_new;

IN_old_stable=IN_new_stable;  //前面两行先做迭代。
IN_new=(GPIO_ReadInputData(GPIOB))&0x00001111;//读取GPIOB的低四位。

IN_temp=(IN_old^IN_new)&IN_old_stable; //中间变量

IN_temp|=IN_old&IN_new;

IN_new_stable=IN_temp;这就得到了我们最新的键值,它是由过去旧的确定值,按键前后两次的值所决定的,所以您看,是不是至少得经历三次中断才能把一个键值更新。

好了,到了这里我们把按键的值检测出来了,我们还有一步,如何告知主函数有没有键值更新呢。

我们分析一下可以知道:如果我们比较IN_new_stable和IN_old_stable两次确定值是不是就知道了

定义temp=IN_new_stable^IN_old_stable;如果低四位上有键值更新,则IN_new_st
9143
able和IN_old_stable前后两次确定值是不是就不一样了,通过异或计算就反映在了相应的位上。

好了我们假设低四位在硬件设计时是拉高的,我们初始化一个中间变量sthchange=0x00001111;

我们把sthchange和temp进行异或就知道哪一位被置低了。

sthchange^=temp.

则把sthchange给主程序判断就行了,当没有键值更新的时候sthchange=0,有键值更新的时候sthchange>1,通过位运算不就知道哪个键值发生改变了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: