矩阵按键扫描的疑惑与解答

举报
ReCclay 发表于 2022/02/22 01:57:12 2022/02/22
【摘要】 最近在学习金沙滩宋老师的单片机,说实话学着是比较吃力,但是不后悔!老师交给的绝不是仅仅只是“鱼”。发现自己的学习态度以及严谨程度,真的和一些前辈比起相差甚远。 下面摘自一位名为“商道”的群友的...

最近在学习金沙滩宋老师的单片机,说实话学着是比较吃力,但是不后悔!老师交给的绝不是仅仅只是“鱼”。发现自己的学习态度以及严谨程度,真的和一些前辈比起相差甚远。

下面摘自一位名为“商道”的群友的学习总结,共勉~

一、问题复现

关于矩阵按键扫描消抖的解释-教材第8章-矩阵按键扫描例题8.4.5

教材116页第8章-矩阵按键扫描例题8.4.5中,中断函数void interrupttime0() interrupt 1的扫描及消抖部分代码截取如下:

截取函数代码如下:

//将一行的4个按键值移入缓冲区
    keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_1;
    keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_2;
    keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_3;
    keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_4;
    //消抖后更新按键状态
    for (i=0; i<4; i++)  //每行4个按键,所以循环4次
    {
        if ((keybuf[keyout][i] & 0x0F) == 0x00)
        {   //连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下
            KeySta[keyout][i] = 0;
        }
        else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
        {   //连续4次扫描值为1,即4*4ms内都是弹起状态时,可认为按键已稳定的弹起
            KeySta[keyout][i] = 1;
        }
    }
    //执行下一次的扫描输出
    keyout++;                //输出索引递增
    keyout = keyout & 0x03;  //索引值加到4即归零

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

疑问如下:

for循环语句的解释部分是“每行4个按键,所以循环4次”;

if条件语句的解释部分是“//连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下”;

  • 1、那么for语句的“每行4个按键,所以循环4次”与if语句的“4*4ms”是不是一回事呢?
  • 2、“连续4次扫描值为0,即4*4ms内都是按下状态时,可认为按键已稳定的按下”。这4行4次扫描时间即4*4ms,是在同一次中断中发生的吗?

二、解答

2.1、我们先了解一下这个中断函数的运行过程

简单地说就是,函数每隔1ms中断一次,并扫描按键中的1行,扫描完成后返回主函数; 第1次中断时,扫描的是第1行的4个按键1位; 第二次中断时扫描的是第2行的4个按键1位; 依次类推,完成全部按键扫描需要中断4次,共扫描4行16个按键,用时4ms;这是一次(一位)全部按键的扫描循环。 这样的循环要进行4次,才能完成按键的扫描处理(不能称为消抖,感觉不太恰当),用时4*4=16ms。

2.2、这样的话,就不难理解以上两条疑问了。

关于第1条疑问的回答:他们不是同一回事。for语句中“每行4个按键,所以循环4次”, 只是一次中断,扫描的是一行按键(共4个按键),用时1ms; 而if语句中的“4*4ms”是4次循环,共用16次中断来完成。

2.3、举例说明:

假如第4行第4个按键有动作,即keyout=3,i=3,keybuf[keyout][i]=keybuf[3][3], 此时的KEY_IN_4=0,中断函数需要进入第3次中断时才能发现KEY_IN_4的值为0(第一次中断只扫描第一行,第二次中断扫描第二行,第三次中断扫描第三行,第四次中断扫描第四行,这时才能发现第四行的第四个按键有动作), 于是将keybuf[3][3]的最右边的位由1变为0,然后继续扫描下一行(返回第一行,于此完成所有按键的第一位扫描); 在第8次中断扫描时,发现KEY_IN_4的值仍然为0,于是将keybuf[3][3]的右边的第2位由1变为0(此时右边共有2个0了), 然后继续扫描下一行; 在第12次中断扫描时,发现KEY_IN_4的值仍然为0,于是将keybuf[3][3]的右边的第3位由1变为0(此时右边共有3个0了), 然后继续扫描下一行; 在第16次中断扫描时,发现KEY_IN_4的值仍然为0,于是将keybuf[3][3]的右边的第4位由1变为0(此时右边共有4个0了), 此刻就完成了4行4次全部按键扫描的循环了,共用时16ms。 此时的keybuf[3][3]右边四位全部是0,所以判定是按下状态。其他的以此类推。

文章来源: recclay.blog.csdn.net,作者:ReCclay,版权归原作者所有,如需转载,请联系作者。

原文链接:recclay.blog.csdn.net/article/details/75453278

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。