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:}再做研究吧,好像不单纯是普通的矩阵键盘 这个程序里有一些没用到的代码,是因为自己想拓展着做一些其他的功能,结果没想到卡死在这一步了{:1_924:} P2=0xFB 即11111011 即P2.2为0这个又再次进入中断了,然后有键盘扫描,又进中断,不停往复。进入键盘扫描时,你先把中断关闭了,扫描完了,在开中断 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
外部中断内,居然有死循环延时,,,
这样真的好吗,。。。。。
{:1_896:}那个确实不需要,我这段代码是研究 keypad-phone 这个模块的时候,顺便从网上摘下来的,就没改,他这个做了抬手判断,其实没必要
页:
[1]