标题: 各位大神,这个是4*4矩阵键盘按键值数码管显示的程序 帮忙解释一下代码的意思(详... [打印本页]

作者: konggang    时间: 2017-7-8 22:29
标题: 各位大神,这个是4*4矩阵键盘按键值数码管显示的程序 帮忙解释一下代码的意思(详...
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define SCANPORT P1
sbit spk=P3^0;
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
                                         0x6d,0x7d,0x07,0x7f,0x6f,
                                         0x77,0x7c,0x39,0x5e,0x79,
                                         0x71};
uchar uca_LineScan[4]={0xEF,0xDF,0xBF,0x7F};
uchar ucKeyScan()
{
        uchar Temp=0;                                 
        uchar ucRow=0,ucLine=0;            

        for(ucLine=0;ucLine<4;ucLine++)       
                {
                        SCANPORT=uca_LineScan[ucLine];                          
                        Temp=SCANPORT & 0x0F;                                         
                        if(Temp!=0x0F)                 
                                {                                                                         
                                switch(Temp)
                                        {
                                        case 0x0E: ucRow=10;break;                 
                                        case 0x0D: ucRow=20;break;
                                        case 0x0B: ucRow=30;break;
                                        case 0x07: ucRow=40;break;
                                        default:   ucRow=50;break;
                                        }
                                break;
                                }
                }

        SCANPORT=0x0F;                                         
        return ucRow+ucLine+1;                         
}
void vKeyProcess(unsigned char ucKeyCode)
{
               
        switch(ucKeyCode)
                {
                case 11:P0=table[0];spk=1;break;                                                          //'7'
                case 12:P0=table[1];spk=1;break;                                                          //'8'
                case 13:P0=table[2];spk=1;break;
                case 14:P0=table[3];spk=1;break;
                                                          
                case 21:P0=table[4];spk=1;break;                                                          //'4'
                case 22:P0=table[5];spk=1;break;                                                          //'5'
                case 23:P0=table[6];spk=1;break;
                case 24:P0=table[7];spk=1;break;
                                                  
                case 31:P0=table[8];spk=1;break;                                                          //'1'
                case 32:P0=table[9];spk=1;break;                                                          //'2'
                case 33:P0=table[10];spk=1;break;
                case 34:P0=table[11];spk=1;break;

                case 41:P0=table[12];spk=1;break;                                  //'3'
                case 42:P0=table[13];spk=1;break;
                case 43:P0=table[14];spk=1;break;                                                  //'0'
                case 44:P0=table[15];spk=1;break;                                                          //'+'

                default:break;
                }
}
void main()
{
        spk=0;
        P0=0;
       
        while(1)
        {
                vKeyProcess(ucKeyScan());
                spk=0;
        }
}

作者: 大黄蜂001    时间: 2017-7-10 14:11
#include<reg51.h>        //头文件
#define uchar unsigned char     //宏定义 uchar代替unsigned char
#define uint unsigned int    //宏定义 uint 代替unsigned int
#define SCANPORT P1  //宏定义SCANPORT代替P1口
sbit spk=P3^0;    //P3.0蜂鸣器输出
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
                                         0x6d,0x7d,0x07,0x7f,0x6f,
                                         0x77,0x7c,0x39,0x5e,0x79,
                                         0x71};            //数组显示0~F
uchar uca_LineScan[4]={0xEF,0xDF,0xBF,0x7F};  //数组定义4显示
uchar ucKeyScan()
{
        uchar Temp=0;                                 
        uchar ucRow=0,ucLine=0;            

        for(ucLine=0;ucLine<4;ucLine++)          //循环4次
                {
                        SCANPORT=uca_LineScan[ucLine];                              //每次循环时P1依次显示数组uca_LineScan的4个数字
Temp=SCANPORT & 0x0F;                                            //P1高4位清零,低四位不变。并把此值赋给Temp
                        if(Temp!=0x0F)                   //如果有按键按下,低四位会变化,进入IF语句
                                {                                                                        
                                switch(Temp)             //4个按键按下ucRow显示不同的值
{
                                        case 0x0E: ucRow=10;break;                    
                                        case 0x0D: ucRow=20;break;
                                        case 0x0B: ucRow=30;break;
                                        case 0x07: ucRow=40;break;
                                        default:   ucRow=50;break;
                                        }
                                break;
                                }
                }

        SCANPORT=0x0F;                                            //P01高4位清零,使他不影响下次的按键显示
return ucRow+ucLine+1;                            //3个数相加,按键按下 (没有电路图),可能是这个数字,仅写出第一次循环的数字,共4次循环,
                                                      0001 0000+0000 0000+0000 0001=0x11
                                                      0010 0000+0000 0000+0000 0001=0x21
                                                      0011 0000+0000 0000+0000 0001=0x31
                                                      0100 0000+0000 0000+0000 0001=0x41
                                                    (。。。0x12,0x22,0x32,0x42
                                                       ......
                                                         ....                               )
}
void vKeyProcess(unsigned char ucKeyCode)
{
               
        switch(ucKeyCode)                         显示一个数字,蜂鸣器响
    {
                case 11:P0=table[0];spk=1;break;                                                          //'7'
                case 12:P0=table[1];spk=1;break;                                                          //'8'
                case 13:P0=table[2];spk=1;break;
                case 14:P0=table[3];spk=1;break;
                                                         
                case 21:P0=table[4];spk=1;break;                                                          //'4'
                case 22:P0=table[5];spk=1;break;                                                          //'5'
                case 23:P0=table[6];spk=1;break;
                case 24:P0=table[7];spk=1;break;
                                                  
                case 31:P0=table[8];spk=1;break;                                                          //'1'
                case 32:P0=table[9];spk=1;break;                                                          //'2'
                case 33:P0=table[10];spk=1;break;
                case 34:P0=table[11];spk=1;break;

                case 41:P0=table[12];spk=1;break;                                  //'3'
                case 42:P0=table[13];spk=1;break;
                case 43:P0=table[14];spk=1;break;                                                  //'0'
                case 44:P0=table[15];spk=1;break;                                                          //'+'

                default:break;
                }
}
void main()
{
        spk=0;
        P0=0;
        
        while(1)
        {
                vKeyProcess(ucKeyScan());    //进入显示子程序
                spk=0;                //关闭蜂鸣器
        }
}

作者: wulin    时间: 2017-7-10 18:05
楼上注释的很好,略做补充。
for(ucLine=0;ucLine<4;ucLine++) //行扫描1~4次,一旦行、列条件满足立即跳出循环
{
        SCANPORT=uca_LineScan[ucLine]; //每次循环时P1依次置数,数组uca_LineScan的4个数字,判断行码
        Temp=SCANPORT & 0x0F;          //P1高4位清零,低四位不变。并把此值赋给Temp
        if(Temp!=0x0F)                 //如果有按键按下,低四位会变化,进入IF语句
        {                                                                        
                switch(Temp)             //4个按键按下ucRow显示不同的值,判断列码
                ......
                break;                                        //获取有效键值即跳出for循环
        }
        ......
}
return ucRow+ucLine+1;;                //返回键值=列值+行值+1(行值0~3,所以要+1)





欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1