[51单片机] 大神们。给指点一二。4X4矩阵键盘扫描!多谢

[复制链接]
1383|12
 楼主| 小分子 发表于 2016-8-8 07:48 | 显示全部楼层 |阅读模式
  1. #include <reg52.h>

  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. uchar KEYIN;

  5. void DelayMs(uint ms);
  6. uchar KeyPress(void);
  7. uchar KeyScan(void);

  8. void main(void)
  9. {
  10.         while (1)
  11.         {
  12.                 if (KeyPress())
  13.                 {
  14.                         P0 = KeyScan();
  15.                     while (KeyPress());
  16.                 }
  17.         }
  18. }

  19. void DelayMs(uint ms)
  20. {
  21.         uint x,y;
  22.         for(x=ms;x>0;x--)
  23.         {
  24.                 for(y=113;y>0;y--);
  25.         }
  26. }

  27. uchar KeyPress(void)
  28. {
  29.         uchar keypress;
  30.         P1 = 0xFF;
  31.         keypress = P1 & 0xF0;
  32.         if (keypress != 0xF0)
  33.         {
  34.                 KEYIN = keypress;
  35.                 return 1;
  36.         }
  37.         else
  38.         {
  39.                 return 0;
  40.         }
  41. }

  42. uchar KeyScan(void)
  43. {
  44.         uchar keyout,index,keycode,keyvalue;
  45.         DelayMs(20);
  46.         P1 = 0xF7;
  47.         index = 0;
  48.         if (KeyPress())
  49.         {
  50.                 //while (1)
  51.                 //{
  52.                         P1 = (0xF7 >> index) | 0xF0;                  
  53.                         index++;
  54.                         index = index & 0x03;
  55.                         keyout = P1 & 0x0F;
  56.                         keycode = KEYIN + keyout;

  57.         //        }
  58.                 switch (keycode)
  59.                 {
  60.                         case 0x77 : keyvalue = 0xC0;     break;
  61.                         case 0x7B : keyvalue = 0xF9;     break;
  62.                         case 0x7D : keyvalue = 0xA4;     break;
  63.                         case 0x7E : keyvalue = 0xB0;     break;
  64.                        
  65.                         case 0xD7 : keyvalue = 0x99;     break;
  66.                         case 0xDB : keyvalue = 0x92;     break;
  67.                         case 0xDD : keyvalue = 0x82;     break;
  68.                         case 0xDE : keyvalue = 0xF8;     break;
  69.                        
  70.                         case 0xB7 : keyvalue = 0x80;     break;
  71.                         case 0xBB : keyvalue = 0x90;     break;
  72.                         case 0xBD : keyvalue = 0x88;     break;
  73.                         case 0xBE : keyvalue = 0x83;     break;
  74.                        
  75.                         case 0xE7 : keyvalue = 0xC6;     break;
  76.                         case 0xEB : keyvalue = 0xA1;     break;
  77.                         case 0xED : keyvalue = 0x86;     break;
  78.                         case 0xEE : keyvalue = 0x8E;     break;
  79.                         default : keyvalue = 0xFF;
  80.                 }
  81.         }
  82.         else
  83.         {
  84.                 keyvalue = 0xFF;
  85.         }
  86.         return keyvalue;
  87. }


冰零分子 发表于 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口好像没有内部上拉电阻

做输出时要外加上拉电阻,不知道你有没有加
冰零分子 发表于 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 很给力!

查看全部评分

 楼主| 小分子 发表于 2016-8-8 14:30 | 显示全部楼层
冰零分子 发表于 2016-8-8 13:07
KeyPress里P1全部置1了什么意思 , 不应该是先置0xF0么
KeyScan里DelayMs(20);应该是消抖用的,不过下面P1 ...

哥们,还是你牛。多谢你的指点。
 楼主| 小分子 发表于 2016-8-8 14:35 | 显示全部楼层
小分子 发表于 2016-8-8 14:30
哥们,还是你牛。多谢你的指点。

P1口,如果要从外面读数据,你得先让它输出1.51是准双向的。不像AVR,STM32
冰零分子 发表于 2016-8-8 15:48 | 显示全部楼层
小分子 发表于 2016-8-8 14:35
P1口,如果要从外面读数据,你得先让它输出1.51是准双向的。不像AVR,STM32

好吧,这样就对了
guojihongwhpu1 发表于 2016-8-8 20:53 | 显示全部楼层
冰零分子 发表于 2016-8-8 15:48
好吧,这样就对了

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

请教下这个语句里面的竖线表示什么意思?
冰零分子 发表于 2016-8-8 21:14 | 显示全部楼层
本帖最后由 冰零分子 于 2016-8-8 21:16 编辑
guojihongwhpu1 发表于 2016-8-8 20:53
P1 = (0xF7 >> index) | 0xF0;

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

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

与0xF0相或从而保证高位为1
 楼主| 小分子 发表于 2016-8-8 21:39 | 显示全部楼层
冰零分子 发表于 2016-8-8 15:48
好吧,这样就对了

哥们,你的技术很精湛啊。
 楼主| 小分子 发表于 2016-8-9 07:35 | 显示全部楼层
冰零分子 发表于 2016-8-8 15:48
好吧,这样就对了

哥们。这样不行。得换成P1 = 0xF0;
冰零分子 发表于 2016-8-9 09:51 | 显示全部楼层
小分子 发表于 2016-8-9 07:35
哥们。这样不行。得换成P1 = 0xF0;


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

本帖子中包含更多资源

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

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

本版积分规则

18

主题

68

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部