找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2186|回复: 15
收起左侧

关于单片机矩阵按键读取的程序理解

[复制链接]
ID:450037 发表于 2021-10-14 11:26 | 显示全部楼层 |阅读模式
这个是某设备上的程序,我有一些不明白的地方把它复制过来了,就是按键值的范围我不太理解

单片机源程序如下:
#include <c8051F020.H>
#include <intrins.H>
#define Keybus  P0
unsigned char R_Keyno;

unsigned char Get_Keyno(void)
{
     unsigned char Key_h,Key_l,Key_no;
   _nop_();_nop_();_nop_();
   Key_h=Keybus;           //我的理解:此时Key_h=P0,应该是P0口的实际状态。
   _nop_();_nop_();_nop_();_nop_();_nop_();
  Keybus=0x0f;               
  _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
  Key_l=Keybus;                  //我的理解:此时Key_l=0x0f
   _nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();
  Keybus=0xf1;
   Key_no=Key_h | Key_l;        //我的理解:如果按位或的话那么 Key_no的值低四位永远是F
   _nop_();
   return Key_no;
}
这是矩阵键盘按键读取的子程序,




void keyin_work(void)
{
    switch (R_Keyno)                 //这是其他引用按键的程序,它的后四位并不是F,请问大神们这个怎么得出来的
         case     0xbc:
         case     0xec:
         case     0xea:
         case     0xba:
         case     0xda:
         case     0xd6:
         case     0xb6:
}
这是应用键盘值判断是哪个按键被按下的应用程序。
51hei图片_20211014105813.jpg
回复

使用道具 举报

ID:123289 发表于 2021-10-14 13:09 | 显示全部楼层
结合硬件接线图,就一目了然了。
回复

使用道具 举报

ID:624769 发表于 2021-10-14 14:22 | 显示全部楼层
基于, #define Keybus  P0   , 所以,Keybus 就是  P0 的意思,是任何时候,而不是仅仅“此时”

所以:   Key_h=Keybus;  就是把  P0 的 值 赋值给 Key_h

所以: Key_no=Key_h | Key_l;    只要有按键按下, 就不会等于 0xff

从你: Keybus=0x0f;  Keybus=0xf1;  这两句看, 如果不是写错了。
那么,你的矩阵键盘就是   3x4  = 12 的矩阵。

所以,switch (R_Keyno)     里面的 Case, 随便找一个,转换成 二进制:
比如: 0xbc  =>   1011 1100      居然 三个0??  

看不懂了………… 你自己捉摸吧……
回复

使用道具 举报

ID:450037 发表于 2021-10-14 14:52 | 显示全部楼层
188610329 发表于 2021-10-14 14:22
基于, #define Keybus  P0   , 所以,Keybus 就是  P0 的意思,是任何时候,而不是仅仅“此时”

所以 ...

keybus 在任何时候都是P0,那么keybus=0x0f;然后给key_l 这个结果是0x0f,还是P0啊?
然后它按位或的时候?低四位结果不是全是1吗?
回复

使用道具 举报

ID:959346 发表于 2021-10-14 15:04 | 显示全部楼层
Key_l=Keybus;                  //我的理解:此时Key_l=0x0f   
回复

使用道具 举报

ID:959346 发表于 2021-10-14 15:07 | 显示全部楼层
上一句没回复完,按错发送了。
Key_l=Keybus;                  //我的理解:此时Key_l=0x0f
这一句,输出“1”的位就是输入了,如果有按键按下,读回来的就不是“1”了。
回复

使用道具 举报

ID:624769 发表于 2021-10-14 15:07 | 显示全部楼层
zhangzhao2423 发表于 2021-10-14 14:52
keybus 在任何时候都是P0,那么keybus=0x0f;然后给key_l 这个结果是0x0f,还是P0啊?
然后它按位或的时 ...

没有键按下,就是0x0f, 有键按下就是 0x07,0x0b 之类的
回复

使用道具 举报

ID:959346 发表于 2021-10-14 15:15 | 显示全部楼层
估计楼主用直接设置IO输入输出方向的MCU比较多,用传统51比较少,对这种转换输入方式不太理解。或者是一下没反应过来?
回复

使用道具 举报

ID:624769 发表于 2021-10-14 15:31 | 显示全部楼层
Jiang_YY 发表于 2021-10-14 15:15
估计楼主用直接设置IO输入输出方向的MCU比较多,用传统51比较少,对这种转换输入方式不太理解。或者是一下 ...

看看我之前的回复。

所以,switch (R_Keyno)     里面的 Case, 随便找一个,转换成 二进制:
比如: 0xbc  =>   1011 1100      居然 三个0??   

这里,我是晕了, 你帮忙分析分析啥情况,为啥3个0???  
回复

使用道具 举报

ID:450037 发表于 2021-10-14 15:31 | 显示全部楼层
188610329 发表于 2021-10-14 15:07
没有键按下,就是0x0f, 有键按下就是 0x07,0x0b 之类的

不能理解,在3x4的矩阵里,假设P0^0是0,我随便按下哪个按钮,也是其中的另外两个位为0,应该不会有0X07的情况吧
回复

使用道具 举报

ID:624769 发表于 2021-10-14 15:42 | 显示全部楼层
zhangzhao2423 发表于 2021-10-14 15:31
不能理解,在3x4的矩阵里,假设P0^0是0,我随便按下哪个按钮,也是其中的另外两个位为0,应该不会有0X07 ...

所以,这个时候,就需要电路图了, 你设置的  P0 = 0x0f;  谁会知道你的 P0^0 会被拉低呢? 而且如果你的 P0^0 会被拉低, 那么 即使你没有按任何按键, 你的
Key_l=Keybus;                  //我的理解:此时Key_l=0x0f
这个推测是不会成立的,  这个时候也应该是:   Key_l=0x0e
回复

使用道具 举报

ID:450037 发表于 2021-10-14 16:06 | 显示全部楼层
188610329 发表于 2021-10-14 15:42
所以,这个时候,就需要电路图了, 你设置的  P0 = 0x0f;  谁会知道你的 P0^0 会被拉低呢? 而且如果你的 ...

假设0.0到0.3是行,0.4到0.7是列,那么按理说可以区分16个按键的值。因为P0^0一直拉低,所以也可以区分12个按键,任何一个按键按下去,应该会有三个位是0,因为P0^0始终是零。
回复

使用道具 举报

ID:624769 发表于 2021-10-14 16:17 来自手机 | 显示全部楼层
zhangzhao2423 发表于 2021-10-14 16:06
假设0.0到0.3是行,0.4到0.7是列,那么按理说可以区分16个按键的值。因为P0^0一直拉低,所以也可以区分12 ...

这样的话,你两次对p0的设置,应该分别是 0x0e和0xf0,确保p0.0始终为低,而不是你代码里的0x0f和0xf1。因为1有不确定性,0有稳定性。
回复

使用道具 举报

ID:213173 发表于 2021-10-14 17:21 | 显示全部楼层
从楼主给的现有条件来看,这个矩阵键盘用了6个端口组成3*3,只使用了7个按键。并且P0.0是被接地,P0.7空。否则不可能得到上述7个键码。
给你把按键代码顺序调整了一下,便于你理解键码是怎么产生的。这是验证程序:
  1. #include <reg51.H>
  2. #define Keybus  P0
  3. unsigned char Get_Keyno(void)
  4. {
  5.         unsigned char Key_h,Key_l,Key_no;
  6.         Keybus=0xf1;
  7.         Key_h=Keybus;           //获取高4位状态
  8.         Keybus=0x0f;               
  9.         Key_l=Keybus;           //获取低4位状态
  10.         Key_no=Key_h | Key_l;   //高低4位相加
  11.         return Key_no;   
  12. }
  13. void keyin_work(void)
  14. {
  15.         switch (Get_Keyno())
  16.         {
  17.                 case 0xbc:P2=~0x01;break;//1011 1100
  18.                 case 0xec:P2=~0x02;break;//1110 1100
  19.                 case 0xea:P2=~0x03;break;//1110 1010
  20.                 case 0xba:P2=~0x04;break;//1011 1010
  21.                 case 0xda:P2=~0x05;break;//1101 1010
  22.                 case 0xd6:P2=~0x06;break;//1101 0110
  23.                 case 0xb6:P2=~0x07;break;//1011 0110
  24.         }
  25. }
  26. void main()
  27. {
  28.         while(1)
  29.         {
  30.                 keyin_work();
  31.         }
  32. }
复制代码

回复

使用道具 举报

ID:450037 发表于 2021-10-15 08:11 | 显示全部楼层
wulin 发表于 2021-10-14 17:21
从楼主给的现有条件来看,这个矩阵键盘用了6个端口组成3*3,只使用了7个按键。并且P0.0是被接地,P0.7空。 ...

厉害,原程序就是使用了7个按键。并且P0.0接地,但是P0.7是不是空的我就不太清楚了。
回复

使用道具 举报

ID:213173 发表于 2021-10-15 13:25 | 显示全部楼层
zhangzhao2423 发表于 2021-10-15 08:11
厉害,原程序就是使用了7个按键。并且P0.0接地,但是P0.7是不是空的我就不太清楚了。

P0.7就算不是悬空,其所接电路也必须在扫描按键时保持高电平。
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表