搜索
bottom↓
回复: 7

郭天祥51单片机 矩阵键盘的程序问题,求解

[复制链接]

出0入0汤圆

发表于 2012-4-8 13:52:42 | 显示全部楼层 |阅读模式
要求如下:在没有键摁下的情况下,数码管没有显示。但是每摁下一个键后,会在六个数码上同时显示相同的数字,释放是数码管灭掉。

下面是我写的一个程序,运行的结果不对,没键摁下是数码管也有显示,键被摁下之后被释放,数码管依然有显示,这个问题要怎么解决呀?进主函数我就把数码管的位选全部关掉了,结果数码管是乱码,怎么回事???求高手解决

#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit wela=P2^7;
sbit dula=P2^6;
uchar code table[]=
{0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};
uchar temp,num;

uchar keyscan();
void display(uchar aa);
void delay(uint z);

//主函数
void main()
{

        wela=1;
        P0=0xc0;    //开所有位选
        wela=0;

        dula=1;
        P0=0x00;
        dula=0;

        while(1)
                {
                        display(keyscan());
                }       
}
//延时函数
void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
//键盘扫描函数
uchar keyscan()
{
                        P3=0xfe;
                        temp=P3;
                        temp=temp&0xf0;
                        if(temp!=0xf0)
                                {
                                        delay(8);                   //去抖
                                        temp=P3;
                                        temp=temp&0xf0;
                                        if(temp!=0xf0)
                                                {
                                                        temp=P3;
                                                        switch(temp)
                                                                {
                                                                        case 0xee:num=0;break;
                                                                        case 0xde:num=1;break;
                                                                        case 0xbe:num=2;break;
                                                                        case 0x7e:num=3;break;       
                                                                }
                                                }
                                }

                        P3=0xfd;
                        temp=P3;
                        temp=temp&0xf0;
                        if(temp!=0xf0)
                                {
                                        delay(8);                   //去抖
                                        temp=P3;
                                        temp=temp&0xf0;
                                        if(temp!=0xf0)
                                                {
                                                        temp=P3;
                                                        switch(temp)
                                                                {
                                                                        case 0xed:num=4;break;
                                                                        case 0xdd:num=5;break;
                                                                        case 0xbd:num=6;break;
                                                                        case 0x7d:num=7;break;       
                                                                }
                                                }
                                }

                        P3=0xfb;
                        temp=P3;
                        temp=temp&0xf0;
                        if(temp!=0xf0)
                                {
                                        delay(8);                   //去抖
                                        temp=P3;
                                        temp=temp&0xf0;
                                        if(temp!=0xf0)
                                                {
                                                        temp=P3;
                                                        switch(temp)
                                                                {
                                                                        case 0xeb:num=8;break;
                                                                        case 0xdb:num=9;break;
                                                                        case 0xbb:num=10;break;
                                                                        case 0x7b:num=11;break;       
                                                                }
                                                }
                                }

                        P3=0xf7;
                        temp=P3;
                        temp=temp&0xf0;
                        if(temp!=0xf0)
                                {
                                        delay(8);                   //去抖
                                        temp=P3;
                                        temp=temp&0xf0;
                                        if(temp!=0xf0)
                                                {
                                                        temp=P3;
                                                        switch(temp)
                                                                {
                                                                        case 0xe7:num=12;break;
                                                                        case 0xd7:num=13;break;
                                                                        case 0xb7:num=14;break;
                                                                        case 0x77:num=15;break;       
                                                                }
                                                }
                                }
        return num;       
}

//数码管显示函数
void display(uchar aa)
{
                dula=1;
                P0=table[aa];
                dula=0;       
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-4-11 13:14:10 | 显示全部楼层
uchar code table[]={。。。。。。0x00};第十七个数设为0x00,num默认为设置为16,主程序如下        while(1)
                 {
                         display(keyscan());
                                                 display(num);
                                                 num=16;
                 }

出0入0汤圆

发表于 2012-6-6 13:19:00 | 显示全部楼层

出0入0汤圆

发表于 2012-6-6 21:31:19 | 显示全部楼层
本帖最后由 yao1 于 2012-6-6 21:35 编辑

看的头大 给你个看看
//////////////////////////////////////////////////////////////////////////////////
//扫描法:逐行扫描查询 一般用在按键比较少的场合
int keyscan()
{
      unsigned char k, k_temp;
      P1=0xf0;      //低位置0,准备查询按键
      k=P1;         //取得当前P1口状态
      if(k!=0xf0)   //如果有变化则表示有按键按下
      {
            delay(10);    //延迟 消抖
            k_temp=p1;
            if(k==k_temp)  //确实有键按下
            {
                  k=0xfe;
                  do         //循环扫描每一行
                  {
                         p1=k;
                         if(k!=p1)
                         {
                             switch(P1)  //判断按键 并返回键值
                            {
                                     //第1行
                                     case 0x7e:{return 0; break;}
                                     case 0xbe:{return 1; break;}
                                     case 0xde:{return 2; break;}
                                     case 0xee:{return 3; break;}
                                     //第2行
                                     case 0x7d:{return 4; break;}
                                     case 0xbd:{return 5; break;}
                                     case 0xdd:{return 6; break;}
                                     case 0xed:{return 7; break;}
                                     //第3行
                                     case 0x7b:{return 8; break;}
                                     case 0xbb:{return 9; break;}
                                     case 0xdb:{return 10;break;}
                                     case 0xeb:{return 11;break;}
                                     //第4行
                                     case 0x77:{return 12;break;}
                                     case 0xb7:{return 13;break;}
                                     case 0xd7:{return 14;break;}
                                     case 0xe7:{return 15;break;}
                                  }                                                                                 
                            }  
                            k=_crol_(k,1);   //移位 进入下一行扫描               
               }
                     while(k!=0xef); //超过列范围 退出扫描                        
          }           
       }
}
////////////////////////////////////////////////////////////////////////////////
//线反转法 :只需2步便可获得按键位置,最常用
unsigned int  keyboar()/*线反转法 */
{
      static unsigned int a=0;
      unsigned char a1=0,b1=0;
    /*行线为输入线,列线为输出线 */
      v1=v2=v3=v4=0;
      h1=h2=h3=h4=1;
      if(P2<0xf0)/*检查行是否有按键按下 */
      {
             delayms(10);
             if(P2<0xf0)
             {
                  /*行线为输入线,列线为输出线 */
                  v1=v2=v3=v4=0;
                  h1=h2=h3=h4=1;
                  a1=P2;
                  /*行线为输出线,列线为输入线 */
                  h1=h2=h3=h4=0;
                  v1=v2=v3=v4=1;
                  b1=P2;
         
                  a=a1|b1;
             }   
       }     
       if       (a==0xe7) {return 1;}
       else if(a==0xeb) { return 2;}
       else if(a==0xed) { return 3;}
       else if(a==0xee) { return 4;}               
      
       else if(a==0xd7) {return 5; }
       else if(a==0xdb) {return 6; }
       else if(a==0xdd) {return 7; }
       else if(a==0xde) {return 8; }   
      
       else if(a==0xb7) {return 9;  }
       else if(a==0xbb) {return 10;}
       else if(a==0xbd) {return 11;}
       else if(a==0xbe) {return 12;}  
      
       else if(a==0x77) {return 13;}
       else if(a==0x7b) {return 14;}
       else if(a==0x7d) {return 15;}
       else if(a==0x7e) {return 16;}   
      
       else return 17;                  
}

出0入0汤圆

发表于 2012-6-6 22:27:50 | 显示全部楼层
楼主这程序本来就是一直显示的,因为天详的板子的位选是会被锁存住的,你在进入大循环前,就已经  P0=0xc0;    //开所有位选了,并且被573锁存住,当初始上电时,num被初始化为0,所以应该显示0,当有键按下,和释放按键之后,num都维持被按下的那个数,所以都会一直显示~~~建议你在keyscan()里,当有键按下时,返回被按下值,没键按下里,返回一个无键按下标志,在display(uchar aa)里,判断aa,如果aa是无键按下标志,则关闭位选,不显示,如果是有键按下,则显示相应值。


出0入0汤圆

发表于 2012-6-6 22:43:19 | 显示全部楼层
uchar num; 51单片机中变量不赋初值,初始化时将是什么值?如果初始化为0,则一开始显示应该是0,如果不是0,是任意一个数,那初始上电,就有可能像你说的那样显示乱码~~~好久没用51了,没有板子测试一下~~希望楼主测试一下~~

出0入0汤圆

发表于 2012-8-24 19:54:29 | 显示全部楼层
矩阵键盘超级难理解。。。楼主现在懂了吗?求教啊!

出0入0汤圆

发表于 2012-8-24 21:51:11 | 显示全部楼层
先扫描行,再扫描列
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 00:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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