void main(void)
{
while(1)
{
if(P3_7==0)//判断是否有按下,为0则按下
{
delay10ms();//延时10MS,去抖动
if(P3_7==0)//再次判断,如果还为0则真的按下了。
{
count++;//每按下一次就加1
if(count==16)//加到16返回0
{
count=0;
}
P1=~count;//P1口把按下的次数输出,如第一次就是11111110,第二次就是11111101:十六进制转成IO口的二进制
while(P3_7==0);//直到按键放开才判断下一次按键
}
}
}
当键盘中按键数量较多时,为了减少对 I/O 口的占用,通常将按键排列成矩阵形式,也称为行列键盘,这是一种常见的连接方式。矩阵式键盘接口见图 9-7 所示,它由行线和列线组成,按键位于行、列的交叉点上。当键被按下时,其交点的行线和列线接通,相应的行线或列线上的电平发生变化,MCU 通过检测行或列线上的电平变化可以确定哪个按键被按下。
图 9-7 为一个 4 x 3 的行列结构,可以构成 12 个键的键盘。如果使用 4 x 4 的行列结构,就能组成一个 16 键的键盘。很明显,在按键数量多的场合,矩阵键盘与独立式按键键盘相比可以节省很多的 I/O 口线。
矩阵键盘不仅在连接上比单独式按键复杂,它的按键识别方法也比单独式按键复杂。在矩阵键盘的软件接口程序中,常使用的按键识别方法有行扫描法和线反转法。这两种方法的基本思路是采用循环查循的方法,反复查询按键的状态,因此会大量占用 MCU 的时间,所以较好的方式也是采用状态机的方法来设计,尽量减少键盘查询过程对 MCU 的占用时间。
增加这两句的目的是当按键所在端口发生状态改变后执行,以提高读键的效率。另外,有些场合是闭合按键执行,而在松开按键执行时你提到的多余语句显得更妙。
比如可以设计这样的功能:
1、按下K1——执行功能1,举例:建立一个标志。在定时器中断中调整初值,输出频率不断增加。
2、松开K1——执行功能2,举例:清除该标志,定时器中断中锁定初值。
同样实现上述功能,用问题中给出的程序,只需要扫描一遍P3判断,2个功能实际只需各执行1次条件语句。而按照您的思路,没有这句话,那么需要主程序反复遍历K1按键的按下和松开,并且还需另外设个标志,以防止按键功能被重复执行。这样一来,条件语句中的内容将会反复执行,效率降低。
当然这个参考程序也有去抖动的设计缺陷。比如,扩展这两句可以改善:
if(P3!=key_val){ i++;i%=10;if(i==0){key_val=P3;……}}
综上,该做法可以提高读键效率,更容易识别按键的按下和松开时刻。
void main(void){while(1){if(P3_7==0)//判断是否有按下,为0则按下{delay10ms();//延时10MS,去抖动if(P3_7==0)//再次判断,如果还为0则真的按下了。
{count++;//每按下一次就加1if(count==16)//加到16返回0{count=0;}P1=~count;//P1口把按下的次数输出,如第一次就是11111110,第二次就是11111101:十六进制转成IO口的二进制while(P3_7==0);//直到按键放开才判断下一次按键}}}。
声明:本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
蜀ICP备2020033479号-4 Copyright © 2016 学习鸟. 页面生成时间:3.074秒