菜鸟高分求助———矩阵键盘扫描

[复制链接]
2363|4
 楼主| 思宁 发表于 2013-1-23 19:48 | 显示全部楼层 |阅读模式
下面的程序是想实现 顺序按下矩阵键盘后,在数码管上依次显示0~F,不按显示 —  但是现在不管按什么键都只显示—  电路原理图如下

程序如下
  1. #include <reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. unsigned char code smgDx[17]={0xc0,0xf9,0xa4,0xb0,
  5.                                         0x99,0x92,0x82,0xf8,0x80,0x90,
  6.                                         0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf};//0~F - 段码

  7. void DelayMs(uint xms);
  8. uchar ScanKey(void);

  9. void main()
  10. {
  11.         P2 = 0x00;
  12.         while(1)
  13.         {
  14.         P0 = smgDx[ScanKey()];
  15.         }
  16. }
  17. uchar ScanKey(void)
  18. {
  19.         uchar i, temp, m, n;//m为列号,n为行号
  20.         bit find = 0;//有键按下标志
  21.         P1 = 0xff;

  22.         for(i=0; i<4; i++)
  23.         {
  24.                 P1 = 0xef<<i;//逐列送低电平
  25.                 temp = ~P1;
  26.                 temp &= 0x0f;//屏蔽高四位,得出行值
  27.                 while(temp!=0x00)//判断有无按键按下,为0则无键按下
  28.                 {
  29.                         DelayMs(10);//消抖
  30.                         temp = ~P1;
  31.                         temp &= 0x0f;//屏蔽高四位,得出行值

  32.                         while(temp!=0x00)
  33.                         {
  34.                                 find = 1;//有键按下
  35.                                 m = i;//列值
  36.                                 switch(temp)
  37.                                 {
  38.                                         case 0x01: n=0; break; //第0行
  39.                                         case 0x02: n=1; break; //第1行
  40.                                         case 0x04: n=2; break; //2
  41.                                         case 0x08: n=3; break; //3
  42.                                         default: break;
  43.                                 }
  44.                         }
  45.                 }
  46.         if(!find) return 16;
  47.          return (n*4+m);                  
  48.         }

  49. }
  50. void DelayMs(uint xms)
  51. {
  52.         uint i,j;
  53.         for(i=0;i<xms;i++)
  54.                 for(j=0;j<110;j++);
  55. }
请大家帮我看看哪里出了问题,先谢谢各位了。

本帖子中包含更多资源

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

×
dong_abc 发表于 2013-1-23 20:19 | 显示全部楼层
dirtwillfly 发表于 2013-1-23 23:18 | 显示全部楼层
你的程序有问题。
函数的返回值:
        if(!find) return 16;
         return (n*4+m);
这两句位置有问题。你放到 for(i=0; i<4; i++)的循环里面了,应该放在for循环外面。
其他的还有没问题我没仔细看,你再检查一下看看。
ayb_ice 发表于 2013-1-24 09:22 | 显示全部楼层
本帖最后由 ayb_ice 于 2013-1-25 13:50 编辑


enum{
        BIT0 = 0x01,
        BIT1 = 0x02,
        BIT2 = 0x04,
        BIT3 = 0x08,
        BIT4 = 0x10,
        BIT5 = 0x20,
        BIT6 = 0x40,
        BIT7 = 0x80,
};

enum{
        KEY_S0 = 1,
        KEY_S1 = 2,
        .......
};

typedef U8 unsigned char;




U8 scan_key(void)
{
        U8 k,x;
        U8 key;

        P1 = 0x0f;
        k = P1;
        if(k == 0x0f){
                return 0;
        }
        
        delay_10ms();
        
        P1 = 0x0f;
        k = P1;
        k = ~k & 0x0f;

        
        P1 = 0xf0;
        x = P1;
        x = ~x & 0xf0;

        k |= x;
        
        key = 0;
        switch(k){
        case BIT0+BIT4:
                k = KEY_S0;
                break;
        case BIT0+BIT5:
                k = KEY_S1;
                break;
        ......
        case BIT3+BIT7:
                k = KEY_SF;
                break;
        }
        
        return key;
}
















 楼主| 思宁 发表于 2013-1-26 08:47 | 显示全部楼层
多谢各位
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:行李再重我自己搬 脚步再沉我移的开 心情再黑我看的淡

5

主题

344

帖子

3

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