找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4409|回复: 5
收起左侧

用单片机4X4键盘实现按键显示123456789ABCDEF

[复制链接]
ID:548138 发表于 2019-5-29 12:51 | 显示全部楼层 |阅读模式
#include <REGX51.H>
sbit weiA=P2^0;
sbit duanB=P2^1;
sbit beep=P2^7;
unsigned char wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
unsigned char duan[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,
                                          0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};

void delay_ms(unsigned int ms)
{
        unsigned char i;
        while(ms--)
        for(i=0;i<123;i++);
}
unsigned char key_scan()
{
        unsigned char key_no=16;
        P1=0xf0;
        if((P1&0xf0)!=0xf0)
        {
                switch(P1)
                {
                case 0xe0: key_no=0; break;
                case 0xd0: key_no=1; break;
                case 0xb0: key_no=2; break;
                case 0x70: key_no=3; break;
                }
        }
       
          P1=0x0f;
        if((P1&0x0f)!=0x0f)
        {
                switch(P1)
                {
                case 0x0e: key_no=key_no+0; break;
                case 0x0d: key_no=key_no+4; break;
                case 0x0b: key_no=key_no+8; break;
                case 0x07: key_no=key_no+12; break;
                }
        }
        return key_no;
       
}
void main()
{
        unsigned char key_no,i;
        while(1)
        {
        key_no=key_scan();
        for(i=0;i<8;i++)
        {
                P0=wei[i];
                weiA=1;
                weiA=0;
                P0=duan[key_no];
                duanB=1;
                duanB=0;
                delay_ms(100);
                if(key_no!=16)
                {
                beep=!beep;
                }
        }
        }
}

回复

使用道具 举报

ID:451718 发表于 2020-3-4 18:13 | 显示全部楼层
  楼主的代码测试了好久,无论键盘如何按,scan_key()函数就是没有读数,有镊子短接cpu引脚又可以有读数。 后来才发现,键盘按下后,回路竟然有50欧左右的电阻,看来是MCU执行得太快了,用示波器看到,P1=0x0f;才短短的500ns就完毕了。果断加了延迟,和P1=0x00;操作,终于有读数了。
  竟然在次得到帮助,还是把调试好的代码贴出来。
/************************************************************************
* 按键处理函数
* 返回按键值
* A: 10 ,  B: 11,  C: 12,  D: 13,  *: 14,  #:15,  *+#:16,  nul:255
*
*************************************************************************/
unsigned char  Convert_KeyVal(unsigned char key)
{
        unsigned char keyval;
        switch(key)
        {
                case 0: keyval=1 ; break;
                case 1: keyval=2 ; break;
                case 2: keyval=3 ; break;
                case 3: keyval=10 ; break;
                case 4: keyval=4 ; break;
    case 5: keyval=5 ; break;               
                case 6: keyval=6 ; break;
                case 7: keyval=11 ; break;
                case 8: keyval=7 ; break;
                case 9: keyval=8 ; break;
                case 10: keyval=9 ; break;
                case 11: keyval=12 ; break;
                case 12: keyval=14 ; break;
                case 13: keyval=0 ; break;
                case 14: keyval=15 ; break;
                case 15: keyval=13 ; break;
                case 16: keyval=255 ; break;
                case 28: keyval=16 ; break;
                default: break;       
        }
        return keyval;
}

unsigned char Key_Scan()
{
  unsigned char keynumber=16;
  P1 = 0x0f;
        DelayUs(5);
  if((P1&0x0f)!=0x0f)
  {
    switch(P1)
    {
      case 0x07: keynumber=0; break;
      case 0x0b: keynumber=1; break;
            case 0x0d: keynumber=2; break;
      case 0x0e: keynumber=3; break;
    }                                       
  }                                      
  P1 = 0xf0;
  DelayUs(5);
  if((P1&0xf0)!=0xf0)
  {
    switch(P1)
    {
      case 0x70: keynumber=keynumber+0; break;
      case 0xb0: keynumber=keynumber+4; break;
      case 0xd0: keynumber=keynumber+8; break;
      case 0xe0: keynumber=keynumber+12; break;
    }
  }                       
        P1 = 0x00;       
       
        keynumber = Convert_KeyVal(keynumber);
  return keynumber;        
}

第一个函数是序列化返回值的,可自行参考。主要是scan_key()函数,和DelayUs(5);延迟函数的位置,这个延迟函数因环境不一样,区别很大,没有贴出来。

key1.jpg
key2.jpg

评分

参与人数 1黑币 +60 收起 理由
admin + 60 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:451718 发表于 2020-2-24 11:52 | 显示全部楼层
这个代码有没有人试过啊? 运行效率怎么样?
回复

使用道具 举报

ID:446775 发表于 2020-11-18 14:44 | 显示全部楼层
robinsonlin 发表于 2020-3-4 18:13
楼主的代码测试了好久,无论键盘如何按,scan_key()函数就是没有读数,有镊子短接cpu引脚又可以有读数。  ...

您这个延时函数一般都是放在这个P1口被重新赋值之后。就似P1整个I/O口被重新赋值,赋值之后延时一下,是等待I/O的的状态稳定下来吗?
回复

使用道具 举报

ID:446775 发表于 2020-11-18 14:46 | 显示全部楼层
robinsonlin 发表于 2020-2-24 11:52
这个代码有没有人试过啊? 运行效率怎么样?

这个代码我还没有试过,不过我像试一下,还有你所说的运行效率指的是什么?是运行速度的快慢吗?
回复

使用道具 举报

ID:451718 发表于 2020-11-19 14:42 | 显示全部楼层
我最后改过的那个代码, 是支持组合按键的。 组合的键值需要自己去算,返回值也需要自己去定义。 把扫描值精确的转化为需要的输出值, 越快越准效率越高啊。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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