吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 811|回复: 5
收起左侧

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

[复制链接]
Libra_wuai 发表于 2023-5-10 11:36
本帖最后由 Libra_wuai 于 2023-5-10 15:07 编辑

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

第一列按键按下后无法显示对应数值

第一列按键按下后无法显示对应数值


压缩包: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[num%10];break;
                case 1:P0=duan[num%100/10];break;
                case 2:P0=duan[num%1000/100];break;
                case 3:P0=duan[num/1000];break;
        }
        P3&=wei[num_i];
}

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这个控件的问题,我自己做了个矩阵键盘,就能够实现了,其实现在还是不了解到底是我的问题还是控件的问题,反正是换了控件就解决了

截图.PNG

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

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| Libra_wuai 发表于 2023-5-10 11:41
这个程序里有一些没用到的代码,是因为自己想拓展着做一些其他的功能,结果没想到卡死在这一步了
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
外部中断内,居然有死循环延时,,,
这样真的好吗,。。。。。

那个确实不需要,我这段代码是研究 keypad-phone 这个模块的时候,顺便从网上摘下来的,就没改,他这个做了抬手判断,其实没必要
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 15:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表