关于读取矩阵键盘输入的问题

2019-03-24 18:41发布

小弟最近一直在做一个动态电子密码锁的程序,就是密码每隔5分钟变化一次的电子锁,程序编了七七八八,理论上没有什么问题了,可是程序应用到单片机上的时候就出现了问题,一个问题就是矩阵键盘输入的时候没有显示,第二个就是矩阵键盘一旦有输入之后,密码就初始化了,不知道是为什么。可能和最近困扰我很久的一个问题有关,我就一并向大家请教请教;
我的程序中有一个定时中断用来调用密码变更程序的,然后在输入这个模块除了问题,因为我想的是在主程序中不断扫描键盘,一旦有按键按下之后就调用键盘扫描程序,相当于是电平触发,但是按下去的时间比较长,岁就会导致按一次调用多次扫描程序,就按一次得到好几个相同的数据。后来我自己想,我在探测到有键按下去到时候调用键盘扫描程序,然后知道是那个键之后,停在那边等键弹起,相当于一个下降沿,然后再回到主程序,并且我现在就是这么做的,但是问题又有了,程序停留在等待下降沿的时候定时中断好像除了问题,而且还是显示不出来,愁死我了,希望有人能够帮帮我。下面附上小弟的程序草稿
//*******************************************动态电子密码锁*********************************************//
//P1接


#include <reg51.h>
//**************************************************变量定义*******************************************//

char DelayCNT;
char a=1,b=2,c=3;//定义变量
unsigned int i,n,m=0,codenum=1,num=0 ;
unsigned int LedOut[10];
unsigned int dis_buf[4]=0;
unsigned int key,temp,keytimes=0;//keytimes 表示第几个按键




//**************************************************函数申明****************************************//
void delay(unsignedi);
void codechange(void);
void display1(void);//密码算法结果显示
void display2(void);//矩阵键盘输入显示
void keyscan(void);
void keydown(void);
void codecmp(void);
void beep(void);       

//此表为 LED 的字模, 共阴数码管 0-9  -
unsigned char code   Disp_Tab[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};  //段码控制

//此表为8个数码管位选控制, 共阴数码管 1-8个  -
unsigned char code   dispbit[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdF,0xbF,0x7F};    //位选控制   查表的方法控
//******************************************密码算法*******************************************************//
void codechange(void){
a=a+2;
b=b*3;
codenum=a*b+3;
}

//*******************************************显示程序****************************************************************//
void display1(void){
         LedOut[0]=Disp_Tab[codenum%10000/1000];   //钥匙密码的显示
     LedOut[1]=Disp_Tab[codenum%1000/100]|0x80;
     LedOut[2]=Disp_Tab[codenum%100/10];
     LedOut[3]=Disp_Tab[codenum%10];
         for( i=0; i<9; i++)
         {         
          P0 = LedOut;
          P1 = dispbit;   //使用查表法进行位选
                           
                delay(150);                 //扫描间隔时间          太长会数码管会有闪烁感
          }
         }
void display2(void){
//*******************************************输入密码显示**************************************************************、、
         LedOut[4]=Disp_Tab[dis_buf[0]];
     LedOut[5]=Disp_Tab[dis_buf[1]]|0x80;
     LedOut[6]=Disp_Tab[dis_buf[2]];
     LedOut[7]=Disp_Tab[dis_buf[3]];
         for( i=0; i<9; i++)
         {         
          P0 = LedOut;
          P1 = dispbit;   //使用查表法进行位选
                           
                delay(150);                 //扫描间隔时间          太长会数码管会有闪烁感
          }
}

//*********************************************键盘扫描*****************************************//
void  keyscan(void)
{         temp = 0;
    P1=0xF0;                 //高四位输入   列为高电平  行为低电平
    delay(2);                                 //延时
        temp=P1;                 //读P1口
    temp=temp&0xF0;                         //屏蔽低四位
    temp=~((temp>>4)|0xF0);          
    if(temp==1)          // p1.4 被拉低
        key=1;  //第1个按键键值
    else if(temp==2)   // p1.5 被拉低
        key=2;          //第2个按键键值
    else if(temp==4)   // p1.6 被拉低
        key=3;         //第3个按键键值
    else if(temp==8)   // p1.7 被拉低
         key=4;          //第4个按键键值
        else
           key = 16;
        
    P1=0x0F;             //低四位输入  行为高电平 列为低电平
    delay(1);                         //延时
        temp=P1;             //读P1口      
    temp=temp&0x0F;
    temp=~(temp|0xF0);
        if(temp==1)                                   //第一行  p1.0  被拉低
                key=key+0;
    else if(temp==2)                   //第二行  p1.1  被拉低
        key=key+4;
    else if(temp==4)   //第三行  p1.2  被拉低
        key=key+8;
    else if(temp==8)   //第四行 p1.3  被拉低
        key=key+12;
        else
          key = 16;

           
     dis_buf[keytimes] = key;            //键值入显示缓存
     dis_buf[keytimes] = dis_buf[keytimes] & 0x0f;

}


//********************************************** 判断键是否按下**********************//
void  keydown(void)
{  
          P2=0xF0;       //将高4位全部置1 低四位全部置0
        if(P2!=0xF0)  //判断按键是否按下 如果按钮按下 会拉低P2其中的一个端口
        {
          keydown();  //调用按键扫描程序
          beep();
          while(P2!=0xF0);
          m=1;
          keytimes++;
    }
}



/************主函数**********************/
main()
{
  TMOD= 0X10;                                                //定时器1的工作方式1
    EA= 1;                                                        //开启总中断
        ET1= 1;                                                        //开启定时器1
    TH1= 0x3c;                                                //高位赋初值
        TL1= 0xb0;                                                //低位赋初值         3cb0是15535,则计时为(65535-15535=50000)us,即50ms
        TR1= 1;                                                        //启动定时器        T1
        num= 0;
        for(i=0;i<20;i++){
        keydown();
        display1();
        display2();       
           if(num==5){
           num=0;
           codechange();
           }
        }         
}   

//*********************************************中断**********************************************


























//*********************************************        定时中断***************************************//
void int_1()interrupt 3
{

        unsigned char n;

                TH1= 0x3c;
                TL1= 0xb0;                                         //3cb0是15535,则计时为(65535-15535=50000)us,即50ms
                TR1= 1;
                n++;
                if(n==20)                                         //1s  num加1
                {
                        num++ ;
                        n= 0;
                }
          
        }       

/*******************延时函数**********************************************/
void delay(unsigned int i)
{   char j;
    for(i; i > 0; i--)
        for(j = 200; j > 0; j--);
} 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。