Libra_wuai 发表于 2023-5-10 11:36

51单片机矩阵键盘编程问题求解

本帖最后由 Libra_wuai 于 2023-5-10 15:07 编辑

自己做了一个外部中断触发的矩阵键盘,功能是将所按下的按键键值显示在数码管上,但神奇的是第一列按键始终无法触发,研究了一个晚上没搞明白怎么回事,第二列第三列都正常啊,程序分析也没发现有啥问题,求编程大佬指点迷津{:1_893:}


压缩包:https://wwjp.lanzoul.com/i4tRV0v500uh

顺便我把程序附在后面吧


#include <reg51.h>

unsigned char duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//共阴极数码管不带小数点
unsigned char wei[]={0x7f,0xbf,0xdf,0xef};
unsigned char key[]={'a','a','a','a'};
unsigned char flag=0,Row=0,Column=0,num_i=0;
char num=-1;
void display();
unsigned char key_phone_scan(void);

void Delay(unsigned int n)
{
      unsigned int i=0, j=0;
      for(i=0;i<n;i++)
      {
                for(j=0;j<120;j++);
      }
}


void Timer0Init()
{   
      TMOD|=0X01;//选择为定时器0模式,工作方式为1
    TH0=0XFC;//给定时器赋初始值,定时1ms
    TL0=0X18;      
    ET0=1;   //打开定时器0中断允许
    TR0=1;   //打开定时器   
      EA=1;
}

void time0() interrupt 1
{
      static char k=0;
      TH0=0XFC;
    TL0=0X18;
      if(num>=0&&num<10)
                k=1;
      else if(num>=10&&num<100)
                k=2;
      else if(num>=100&&num<1000)
                k=3;
      else
                k=4;
      if(num_i>=k)
                num_i=0;
      if(num>=0)
                display();
      num_i++;
}

void display()                        //显示
{
      P3|=0xf0;
      switch(num_i)
      {
                case 0:P0=duan;break;
                case 1:P0=duan;break;
                case 2:P0=duan;break;
                case 3:P0=duan;break;
      }
      P3&=wei;
}

void Int0_Init()
{   
      IT0=1;
      EX0=1;
      EA=1;
}

void Init0() interrupt 0
{
      num=key_phone_scan();
      P2=0x0f;
}

unsigned char key_phone_scan(void)
{
      static unsigned char key_value=0;
    char a=0;
      P2=0xFB;//给第一列赋值0,其余全为1
      if(P2!=0xFB)//判断第一列按键是否按下
      {
                Delay(10);//消抖
                switch(P2)//保存第一列按键按下后的键值      
                {
                        case 0x7B: key_value=1;return key_value;
                        case 0xBB: key_value=4;return key_value;
                        case 0xDB: key_value=7;return key_value;
                        case 0xEB: key_value=10;return key_value;
                }
      }
      while((a<50)&&(P2!=0xFB))         //按键松手检测
      {
                Delay(1);
                a++;
      }
      
      P2=0xFD;//给第二列赋值0,其余全为1
      if(P2!=0xFD)//判断第二列按键是否按下
      {
                Delay(10);//消抖
                switch(P2)//保存第二列按键按下后的键值      
                {
                        case 0x7D: key_value=2;return key_value;
                        case 0xBD: key_value=5;return key_value;
                        case 0xDD: key_value=8;return key_value;
                        case 0xED: key_value=11;return key_value;
                }
      }
      while((a<50)&&(P2!=0xFD))         //按键松手检测
      {
                Delay(1);
                a++;
      }
      
      P2=0xFE;//给第三列赋值0,其余全为1
      if(P2!=0xFE)//判断第三列按键是否按下
      {
                Delay(10);//消抖
                switch(P2)//保存第三列按键按下后的键值      
                {
                        case 0x7E: key_value=3;return key_value;
                        case 0xBE: key_value=6;return key_value;
                        case 0xDE: key_value=9;return key_value;
                        case 0xEE: key_value=12;return key_value;
                }
      }
      while((a<50)&&(P2!=0xFE))         //按键松手检测
      {
                Delay(1);
                a++;
      }
      return -1;               
}

void main()
{
      Timer0Init();
      Int0_Init();
      P2=0X0f;
      while(1);
}


最新:发现程序根本无法跳入第一列按键的判断语句,正在查找原因....

最新进展,发现原因了,程序没问题,好像是keypad-phone这个控件的问题,我自己做了个矩阵键盘,就能够实现了,其实现在还是不了解到底是我的问题还是控件的问题,反正是换了控件就解决了



最最新进展:换了其它样式的自带控件,同样是第一列不可用,看来是结构问题,我去查查他们的电路图{:1_896:}再做研究吧,好像不单纯是普通的矩阵键盘

Libra_wuai 发表于 2023-5-10 11:41

这个程序里有一些没用到的代码,是因为自己想拓展着做一些其他的功能,结果没想到卡死在这一步了{:1_924:}

wqs12345 发表于 2023-5-10 13:49

P2=0xFB 即11111011 即P2.2为0这个又再次进入中断了,然后有键盘扫描,又进中断,不停往复。进入键盘扫描时,你先把中断关闭了,扫描完了,在开中断

Libra_wuai 发表于 2023-5-10 14:20

wqs12345 发表于 2023-5-10 13:49
P2=0xFB 即11111011 即P2.2为0这个又再次进入中断了,然后有键盘扫描,又进中断,不停往复。进入键盘扫描 ...

应该不是,外部中断在 P3.2 下降沿触发,P2.2 影响不了吧,我试了一下不行的,在 debug 里看到按下第一列按键以后,num 的值是 0,不知道为啥,理解不了

vtor 发表于 2023-5-11 11:16

外部中断内,居然有死循环延时,,,
这样真的好吗,。。。。。

Libra_wuai 发表于 2023-5-11 15:55

vtor 发表于 2023-5-11 11:16
外部中断内,居然有死循环延时,,,
这样真的好吗,。。。。。

{:1_896:}那个确实不需要,我这段代码是研究 keypad-phone 这个模块的时候,顺便从网上摘下来的,就没改,他这个做了抬手判断,其实没必要
页: [1]
查看完整版本: 51单片机矩阵键盘编程问题求解