这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 请教矩阵按键扫描的单片机程序问题

共8条 1/1 1 跳转至

请教矩阵按键扫描的单片机程序问题

工程师
2021-10-14 21:26:25     打赏

大家好!以下是某设备上的单片机程序,我有一些不明白的地方把它复制过来了,就是按键值的范围我不太理解

单片机源程序如下:


#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:
}
这是应用键盘值判断是哪个按键被按下的应用程序。




关键词: 按键     扫描     矩阵     源码    

工程师
2021-10-14 23:10:07     打赏
2楼

结合硬件接线图,就一目了然了呀!


工程师
2021-10-14 23:17:25     打赏
3楼

基于, #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??  

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


工程师
2021-10-14 23:27:38     打赏
4楼

Key_l=Keybus;                  //我的理解:此时Key_l=0x0f
这一句,输出“1”的位就是输入了,如果有按键按下,读回来的就不是“1”了。


工程师
2021-10-15 10:02:21     打赏
5楼
估计楼主用直接设置IO输入输出方向的MCU比较多,用传统51比较少,对这种转换输入方式不太理解。或者是一下没反应过来?



工程师
2021-10-15 10:19:53     打赏
6楼

从楼主给的现有条件来看,这个矩阵键盘用了6个端口组成3*3,只使用了7个按键。并且P0.0是被接地,P0.7空。否则不可能得到上述7个键码。
给你把按键代码顺序调整了一下,便于你理解键码是怎么产生的。这是验证程序:

#include <reg51.H>

#define Keybus  P0

unsigned char Get_Keyno(void)

{

        unsigned char Key_h,Key_l,Key_no;

        Keybus=0xf1;

        Key_h=Keybus;           //获取高4位状态

        Keybus=0x0f;                

        Key_l=Keybus;           //获取低4位状态

        Key_no=Key_h | Key_l;   //高低4位相加

        return Key_no;   

}

void keyin_work(void)

{

        switch (Get_Keyno())

        {

                case 0xbc:P2=~0x01;break;//1011 1100 

                case 0xec:P2=~0x02;break;//1110 1100

                case 0xea:P2=~0x03;break;//1110 1010

                case 0xba:P2=~0x04;break;//1011 1010

                case 0xda:P2=~0x05;break;//1101 1010

                case 0xd6:P2=~0x06;break;//1101 0110

                case 0xb6:P2=~0x07;break;//1011 0110

        }

}

void main()

{

        while(1)

        {

                keyin_work();

        }

}




专家
2021-10-15 10:21:11     打赏
7楼

谢谢分享


工程师
2021-10-19 22:03:16     打赏
8楼

学到经验了


共8条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]