打印
[51单片机]

大神们。给指点一二。4X4矩阵键盘扫描!多谢

[复制链接]
1106|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

uchar KEYIN;

void DelayMs(uint ms);
uchar KeyPress(void);
uchar KeyScan(void);

void main(void)
{
        while (1)
        {
                if (KeyPress())
                {
                        P0 = KeyScan();
                    while (KeyPress());
                }
        }
}

void DelayMs(uint ms)
{
        uint x,y;
        for(x=ms;x>0;x--)
        {
                for(y=113;y>0;y--);
        }
}

uchar KeyPress(void)
{
        uchar keypress;
        P1 = 0xFF;
        keypress = P1 & 0xF0;
        if (keypress != 0xF0)
        {
                KEYIN = keypress;
                return 1;
        }
        else
        {
                return 0;
        }
}

uchar KeyScan(void)
{
        uchar keyout,index,keycode,keyvalue;
        DelayMs(20);
        P1 = 0xF7;
        index = 0;
        if (KeyPress())
        {
                //while (1)
                //{
                        P1 = (0xF7 >> index) | 0xF0;                  
                        index++;
                        index = index & 0x03;
                        keyout = P1 & 0x0F;
                        keycode = KEYIN + keyout;

        //        }
                switch (keycode)
                {
                        case 0x77 : keyvalue = 0xC0;     break;
                        case 0x7B : keyvalue = 0xF9;     break;
                        case 0x7D : keyvalue = 0xA4;     break;
                        case 0x7E : keyvalue = 0xB0;     break;
                       
                        case 0xD7 : keyvalue = 0x99;     break;
                        case 0xDB : keyvalue = 0x92;     break;
                        case 0xDD : keyvalue = 0x82;     break;
                        case 0xDE : keyvalue = 0xF8;     break;
                       
                        case 0xB7 : keyvalue = 0x80;     break;
                        case 0xBB : keyvalue = 0x90;     break;
                        case 0xBD : keyvalue = 0x88;     break;
                        case 0xBE : keyvalue = 0x83;     break;
                       
                        case 0xE7 : keyvalue = 0xC6;     break;
                        case 0xEB : keyvalue = 0xA1;     break;
                        case 0xED : keyvalue = 0x86;     break;
                        case 0xEE : keyvalue = 0x8E;     break;
                        default : keyvalue = 0xFF;
                }
        }
        else
        {
                keyvalue = 0xFF;
        }
        return keyvalue;
}


相关帖子

沙发
冰零分子| | 2016-8-8 10:14 | 只看该作者
有按键按下,把键值送给P0,你想表达啥,P0接的东西没反应么?

使用特权

评论回复
板凳
小分子|  楼主 | 2016-8-8 11:45 | 只看该作者
冰零分子 发表于 2016-8-8 10:14
有按键按下,把键值送给P0,你想表达啥,P0接的东西没反应么?

对的。没有反应。我也是在找原因。可能是逻辑上出错了。

使用特权

评论回复
地板
冰零分子| | 2016-8-8 12:43 | 只看该作者
小分子 发表于 2016-8-8 11:45
对的。没有反应。我也是在找原因。可能是逻辑上出错了。

暂时没发现问题,,,,

好久没玩51了,记得51 P0口好像没有内部上拉电阻

做输出时要外加上拉电阻,不知道你有没有加

使用特权

评论回复
5
冰零分子| | 2016-8-8 13:07 | 只看该作者
本帖最后由 冰零分子 于 2016-8-8 13:50 编辑
小分子 发表于 2016-8-8 11:45
对的。没有反应。我也是在找原因。可能是逻辑上出错了。

KeyPress里P1全部置1了什么意思 , 不应该是先置0xF0么
KeyScan里DelayMs(20);应该是消抖用的,不过下面P1 = 0xF7;又是什么意思?


好吧我承认我蒙圈了。。。


KeyScan里的while还是有用的
  • while (1)
  •   {
  •      P1 = (0xF7 >> index) | 0xF0;
  •      index++;
  •      index = index & 0x03;
  •      keyout = P1 & 0x0F;
  •      if( (P1&0xF0) != 0xF0)
  •         {
  •            keycode = KEYIN + keyout;
  •            break;
  •         }
  •    }

使用特权

评论回复
评分
参与人数 1威望 +2 收起 理由
小分子 + 2 很给力!
6
小分子|  楼主 | 2016-8-8 14:30 | 只看该作者
冰零分子 发表于 2016-8-8 13:07
KeyPress里P1全部置1了什么意思 , 不应该是先置0xF0么
KeyScan里DelayMs(20);应该是消抖用的,不过下面P1 ...

哥们,还是你牛。多谢你的指点。

使用特权

评论回复
7
小分子|  楼主 | 2016-8-8 14:35 | 只看该作者
小分子 发表于 2016-8-8 14:30
哥们,还是你牛。多谢你的指点。

P1口,如果要从外面读数据,你得先让它输出1.51是准双向的。不像AVR,STM32

使用特权

评论回复
8
冰零分子| | 2016-8-8 15:48 | 只看该作者
小分子 发表于 2016-8-8 14:35
P1口,如果要从外面读数据,你得先让它输出1.51是准双向的。不像AVR,STM32

好吧,这样就对了

使用特权

评论回复
9
guojihongwhpu1| | 2016-8-8 20:53 | 只看该作者
冰零分子 发表于 2016-8-8 15:48
好吧,这样就对了

  P1 = (0xF7 >> index) | 0xF0;

请教下这个语句里面的竖线表示什么意思?

使用特权

评论回复
10
冰零分子| | 2016-8-8 21:14 | 只看该作者
本帖最后由 冰零分子 于 2016-8-8 21:16 编辑
guojihongwhpu1 发表于 2016-8-8 20:53
P1 = (0xF7 >> index) | 0xF0;

请教下这个语句里面的竖线表示什么意思?

或的意思,右移的时候高位会补零,

与0xF0相或从而保证高位为1

使用特权

评论回复
11
小分子|  楼主 | 2016-8-8 21:39 | 只看该作者
冰零分子 发表于 2016-8-8 15:48
好吧,这样就对了

哥们,你的技术很精湛啊。

使用特权

评论回复
12
小分子|  楼主 | 2016-8-9 07:35 | 只看该作者
冰零分子 发表于 2016-8-8 15:48
好吧,这样就对了

哥们。这样不行。得换成P1 = 0xF0;

使用特权

评论回复
13
冰零分子| | 2016-8-9 09:51 | 只看该作者
小分子 发表于 2016-8-9 07:35
哥们。这样不行。得换成P1 = 0xF0;


我意思是IO口输入前置1那就对了
要判断是否有按键按下,低四位当然要全部输出0啦

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

18

主题

68

帖子

1

粉丝