迅维网

查看: 3011|回复: 15
打印 上一主题 下一主题
[其他]

转载:一文带你详解矩阵键盘工作原理

  [复制链接]
跳转到指定楼层
1#
发表于 2021-7-31 09:20:10 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 来自: 中国 来自 中国

马上注册,获取阅读精华内容及下载权限

您需要 登录 才可以下载或查看,没有帐号?注册

x
本帖最后由 极致科技 于 2021-7-31 09:40 编辑

矩阵键盘本质:矩阵键盘本质是使用8个io口来进行16个按键的控制读取,可以减小io口的使用,用4条I/O线作为行线,4条I/O线作为列线组成的键盘。在行线和列线的每个交叉点上,设置一个按键。而这样的按键中按键的个数是4 X 4个。这样的行列式键盘结构能够有效地提高单片机系统中I/O口的利用率。节约单片机的资源,其本质和独立按键类似,就是进行逐行扫描和逐列扫描,然后判断是第几行的第几列个按键,进而进行整体按键值得确定,我们使用的矩阵键盘是接到了单片机的P1口通过读取P1口电平变换即可完成矩阵键盘的数值读取,具体原理图如下:
第一行接到p17,第二行接到p16,第三行接到p15,第4行接到p14
第一列接到p13,第二列接到p12,第三列接到p11,第四列接到p10
矩阵键盘扫描的方式有两种: 1.行列扫描,2.逐行/逐列扫描
其中行列扫描适用于8个IO口接到了单片机8个连续的IO口,则可以进行行列扫描
逐行/逐列扫描 适用于矩阵键盘接到了任意的IO口,则使用逐行,逐列扫描
接下来我们分别介绍这两种方式:
行列扫描:
原理:
先从P1口的高四位(四个行)输出高电平,低四位(四个列)输出低电平,假设有按键按下,从P1口的高四位读取键盘状态。判断高四位的四行哪一行变成了低电平,就知道是第几行,再从P1口的低四位(四个列)输出高电平,高四位(四个行)输出低电平,从P1口的低四位读取键盘状态。判断低四位的四列哪一行变成了低电平,就知道是第几列,将两次读取结果组合起来就可以得到当前按键的特征编码。使用上述方法我们得到16个键的特征编码。
红色高电平,蓝色低电平
详解:
据矩阵键盘的原理图可知,如果矩阵键盘的8个IO口连接到了连续的一个一个人P10-P17上,当没有按键按下时,将P1口的P1^0 和 P13 置高电平 P14 和 P17 置低电平 ,也就是将4个行的IO口置高,4个列的IO口置低。 也就是P1=0x0f(0000 1111);
如果这时候有按键按下那么P1^0 和P13 就有一个会变成低电平。因此P1的值就不等于0x0f,按下按键所在的行就会变成低电平,这是就可以判断有按键按下。
将对应P1口的值和0x0f(00001111)相与& 则可以得到高四位第几行变成了0
按位”&(双目运算符):仅当两个操作数都为1时,结果为1,否则为0
比方说:0&0=00&1=01&0=01&1=1
即:两个同时为1,结果为1,否则为0
比方说按下的第一行第一列1x1
例:
00001110------------- 按下1x1之后P1的值
&0000 1111------------- 0x0f
----------
00001110------------- 最后得到的结果,第一行为0
再给P1口赋值0X0f。将P1口的P1^0 和 P13 置低电平 P14 和 P17 置高电平 ,也就是将4个低的IO口置高,4个列的IO口置高然后读取低四位的电平, 此时的P1口 (1111 0000)
读取此时的P1口 和0xf0(11110000)相与& 则可以得到低四位第几列变成了低电平
比方说我们按下的是1x1 按键,也就是第一行第一列,这时在按下之后可以看到p1.0和p1.3都是低电平,将Row=P1&0x0f;(行的值) 和 Col=P1&0xf0;//列值 进行相加,就可以得到按下的是那个按键
1x1: (一行一列)
Row=P1&0x0f =  0000 1110
Col=P1&0xf0=     1110 0000
Row+Col=           1110 1110   = 0xee
低电平0表示对应的行列按下
可以看到下方的p1.0和p1.4变成了低电平
2x2: (二行二列)
Row=P1&0x0f =  0000 1101
Col=P1&0xf0=     1101 0000
Row+Col=           1101 1101   = 0xdd
3x4: (三行四列)
Row=P1&0x0f =  0000 1011
Col=P1&0xf0=     0111 0000
Row+Col=           0111 1011   = 0x7b
这样就可以得到所有的16个按键的数值,具体代码如下:
1  unsigned char keyscan(){
2     unsignedchar key,Row,Col;
3     P1=0x0f;
4     if(P1!=0x0f){
5            delay(10);//去抖
6            if(P1!=0x0f){
7                   Row=P1&0x0f;//确保端口值正确(行的值)
8                   P1=0xf0;
9                   Col=P1&0xf0;//列值
10
11          }
12          while((P1&0xf0)!=0xf0);//判断键是否抬起
13   }
14   switch(Row+Col){
15          case0xee:key=0;break;
16          case0xde:key=1;break;
17          case0xbe:key=2;break;
18          case0x7e:key=3;break;
19
20          case0xed:key=4;break;
21          case0xdd:key=5;break;
22          case0xbd:key=6;break;
23          case0x7d:key=7;break;
24
25          case0xeb:key=8;break;
26          case0xdb:key=9;break;
27          case0xbb:key=10;break;
28          case0x7b:key=11;break;
29
30          case0xe7:key=12;break;
31          case0xd7:key=13;break;
32          case0xb7:key=14;break;
33          case0x77:key=15;break;
34
35
36   }
37        return key;
38  }
运行效果图:
逐行/列扫描:
逐行,逐列扫描的本质和行列扫描比较类似,本质是给某一行/某一列,低电平,其余七个全部为高电平,这时候读取电平变换,有电平变低表示按键按下,即可读取按键数据。
比如逐行扫描:
置第1行为低电平,其余N-1行和N列为高电平,
读取列线数据,列线有低电平表示此行有按键按下,比如按下的是1行三列(1x3),那么第三列的列线IO口就为低电平。
置第2行为低电平,其余N-1行和N列为高电平,,读取列线数据,列线有低电平表示此行有按键按下。
以此类推,进行逐行扫描。
根据行线列线的电平不同可以识别是否有按键按下,哪一个按键按下,获取按键号。(N) 根据按键号跳转至对应的按键处理程序。
用我们的P1口来进行举例:
首先,给P1赋值P1=0xfe(1111 1110);,这时P1.0为低电平,P1.1~p1.7为高电平,如果这时候有按键按下那么四个列线,P1.4,P1.5,P1.6,P1.7就有一个列会变成低电平。因此P1的值就不等于0xfe,这是就可以判断有按键按下。
然后延时一段时间去抖动,然后给P1赋值0xfd(11111101),也就是P1.1为低电平,其他为高电平,这时如果有在P1.1线上的P1.4,P1.5,P1.6,P1.7有按键按下,那么就会出现低电平,从而判断哪个按键按下;如果没有那么就给P1赋值0xfb(1111 1011),也就是P1.2为低电平,其他为高电平.,相同方法判断是否有按键按下;······如此类推,一共四次检测。
比如当第1行有按键按下时P1的相应值为:
 1X1(11101110=0xee)
 1x2(11011110=0xde)
  1X3(10111110=0xbe)
  1X4(01111110=0x7e)
第2行有按键按下时P1的相应值为:
    2X1(11101101=0xed)
    2x2(11011101=0xdd)
    2X3(10111101=0xbd)
    2X4(01111101=0x7d)
将P1^2输出低电平,其他的引脚都输出高电平,即P1=0xfb,那么当第3行有按键按下时P1的相应值为:
    3X1(11101011=0xeb)
    3x2(11011011=0xdb)
    3X3(10111011=0xbb)
    3X4(01111011=0x7b)
最后可得第四行的相对应值为:
    4X1(11100111=0xe7)
    4x2(11010111=0xd7)
    4X3(10110111=0xb7)
  4X4(01110111=0x77)
那么最后我们可以得到代码:
/*****************************************************************************
** 函数名称:keyscan
** 功能描述:按键获取函数
******************************************************************************/
void keyscan(void)
{
       P1=0xfe;
  temp=P1;
  temp=temp&0xf0;
  if(temp!=0xf0)
   {
              delay(10);
     if(temp!=0xf0)
     {   
                     temp=P1;
                     switch(temp)
                     {
                            case0xee:      key=0;break;
                            case0xde:      key=1;break;
                            case0xbe:      key=2;break;
                            case0x7e:      key=3;break;
        }
        while(temp!=0xf0)
                     {
                            temp=P1;
                            temp=temp&0xf0;                     
        }           
              }
       }
       P1=0xfd;
       temp=P1;
       temp=temp&0xf0;
       if(temp!=0xf0)
       {
              delay(10);
              if(temp!=0xf0)
     {
                     temp=P1;
                     switch(temp)
                     {
                            case0xed:     key=4;break;
                            case0xdd:     key=5;break;
                            case0xbd:     key=6;break;
                            case0x7d:      key=7;break;
        }
        while(temp!=0xf0)
        {
          temp=P1;
           temp=temp&0xf0;
        }
     }
       }
       P1=0xfb;
       temp=P1;
       temp=temp&0xf0;
       if(temp!=0xf0)
       {
              delay(10);
     if(temp!=0xf0)
     {
                     temp=P1;
                     switch(temp)
                     {
                            case0xeb:      key=8;break;
                            case0xdb:     key=9;break;
                            case0xbb:     key=10;break;
                            case0x7b:      key=11;break;                           
        }
                     beep=0;delay(50);beep=1;
                     while(temp!=0xf0)
        {
                            temp=P1;
                            temp=temp&0xf0;
        }
     }
   }
       P1=0xf7;
  temp=P1;
  temp=temp&0xf0;
  if(temp!=0xf0)
   {
     delay(10);
      if(temp!=0xf0)
     {
                     temp=P1;
                     switch(temp)
                     {
                            case0xe7:      key=12;break;      
                            case0xd7:      key=13;break;      
                            case0xb7:      key=14;break;      
                            case0x77:      key=15;break;      
        }
                     while(temp!=0xf0)
        {
                            temp=P1;
                            temp=temp&0xf0;
        }
     }
       }
}
运行效果图:

版权声明:本文为CSDN博主「Z小旋」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

评分

参与人数 1下载分 +2 +2 收起 理由
virginlulu + 2 + 2

查看全部评分

推荐
发表于 2021-8-8 18:46:21 | 只看该作者 来自: 广东惠州 来自 广东惠州
学习了,感谢分享,

回复 支持 1 反对 0

使用道具 举报

推荐
发表于 2021-8-7 10:18:39 | 只看该作者 来自: 四川自贡 来自 四川自贡
了解一下,感谢楼主分享

回复 支持 1 反对 0

使用道具 举报

2#
发表于 2021-7-31 12:49:28 | 只看该作者 来自: 甘肃 来自 甘肃
8051必修课!

回复 支持 反对

使用道具 举报

3#
发表于 2021-7-31 13:50:26 | 只看该作者 来自: 四川成都 来自 四川成都
又不造键盘

回复 支持 反对

使用道具 举报

4#
发表于 2021-8-6 14:19:57 | 只看该作者 来自: 中国 来自 中国
了解一下也好

回复 支持 反对

使用道具 举报

7#
发表于 2021-8-9 08:55:13 来自迅维网APP | 只看该作者 来自: 陕西西安 来自 陕西西安
了解了感谢分享!

回复 支持 反对

使用道具 举报

8#
发表于 2021-8-9 09:29:44 来自迅维网APP | 只看该作者 来自: 四川 来自 四川
我智商低没看懂。,

回复 支持 反对

使用道具 举报

9#
发表于 2021-8-10 09:00:05 来自迅维网APP | 只看该作者 来自: 中国 来自 中国
学习了,感谢分享

回复 支持 反对

使用道具 举报

10#
发表于 2021-8-10 13:31:45 来自迅维网APP | 只看该作者 来自: 河南 来自 河南
学习了,感谢

回复 支持 反对

使用道具 举报

11#
发表于 2021-8-10 13:49:10 | 只看该作者 来自: 湖北 来自 湖北
感谢楼主分享!

回复 支持 反对

使用道具 举报

12#
发表于 2021-8-10 19:31:30 来自迅维网APP | 只看该作者 来自: 湖南 来自 湖南
好帖收藏了,值得学习。

回复 支持 反对

使用道具 举报

13#
发表于 2021-8-14 14:51:40 | 只看该作者 来自: 湖南张家界 来自 湖南张家界
谢谢分享、。。。。。。。。。。。。。。。。。。。。。。。

回复 支持 反对

使用道具 举报

14#
发表于 2021-8-15 04:58:12 来自迅维网APP | 只看该作者 来自: 上海长宁区 来自 上海长宁区
键盘都是这样的啊

回复 支持 反对

使用道具 举报

15#
发表于 2021-9-26 05:56:30 来自迅维网APP | 只看该作者 来自: 中国 来自 中国
发错版块了吧,移除

                               
登录/注册后看高清大图

回复 支持 反对

使用道具 举报

16#
发表于 2021-10-12 18:21:53 | 只看该作者 来自: 河南郑州 来自 河南郑州
学会之后是不是就会修键盘了?枯燥理论太多,如果拿个键盘演示一下,由理论过度到实践就更好了。

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长提醒 上一条 /1 下一条

快速回复 返回顶部 返回列表
附近
店铺
微信扫码查看附近店铺
维修
报价
扫码查看手机版报价
信号元
件查询
点位图


芯片搜索

快速回复