51单片机编程_矩阵按键控制_0x04

/*
    矩阵按键控制程序
*/

#include 

typedef unsigned char u8;
typedef unsigned int u16;

sbit LSA=P2^2;  //定义 P2 口的第 2 位为特殊位变量 LSA
sbit LSB=P2^3;  //定义 P2 口的第 3 位为特殊位变量 LSB
sbit LSC=P2^4;  //定义 P2 口的第 4 位为特殊位变量 LSC


#define GPIO_KEY P1     //定义 矩阵键盘的接口/按键的接口接到 P1 端口
#define GPIO_DIG P0     //定义 数码管发送段码数据 的接口接到 P0 端口

u8 KeyValue;            //用来存放读取到的按键值


//共阴数码管段编码数据
u8 code smgduan[]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,  
                   0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; //显示0~F的值

//延时函数
void delay(u16 i)
{
    while(i--);
}

//按键扫描程序,识别具体哪一个按键按下
void KeyDown()
{
    u8 a=0;                 //记录按键检测次数

    //按照矩阵按键行列扫描原理判断哪一个按键按下
    GPIO_KEY=0x0f;          //设置按键触点初始值默认为零(高四位为 0000,低四位为 1111)

    if(GPIO_KEY!=0x0f)      //判断按键是否按下
    {
        delay(50000);       //延时函数:软件消除抖动,按键按下时,触点会发生抖动现象,造成电压不稳

        if(GPIO_KEY!=0x0f)  //判断触点的值是否为零(低电平有效)
        {
            GPIO_KEY=0x0f;

            //列检测:判断具体哪一列按下
            switch(GPIO_KEY)
            {
                case 0x07: KeyValue=0;break;
                case 0x0b: KeyValue=1;break;
                case 0X0d: KeyValue=2;break;
                case 0x0e: KeyValue=3;break;
            }

            GPIO_KEY=0xf0;  //设置按键触点初始值默认为1(高四位为 1111,低四位为 0000)

            //行检测:判断具体哪一行按下
            switch(GPIO_KEY)
            {
                case 0x70: KeyValue=+0;break;
                case 0xb0: KeyValue=+4;break;
                case 0xd0: KeyValue=+8;break;
                case 0xe0: KeyValue=+12;break;
            }

            //按键超时判断并且退出程序
            while((a<50) && (GPIO_KEY!=0xf0))   //判断按键是否松下(按键触点电平不为0,即按键持续按下,未松开)
            {
                delay(1000);
                a++;    
            }
        }
    }
}

void main()
{
    LSA=0;
    LSB=0;
    LSC=0;

    while(1)
    {
        KeyDown();  //执行按键扫描函数,识别具体哪一个按键按下
        GPIO_DIG=smgduan[KeyValue]; //向端口 P0 发送数码管段选数据  
    }
}

问题 1:(u8 KeyValue;)
为什么用来存放读取到的按键值需要用 u8 类型的来定义,而不是 char 或者 int 类型;

答案:
u8 = unsigned char, u16 = unsigned int; char 本身范围(-128~127), 按键的值是没有负数的。所以用 u8 比较合适,且 char 类型占用的内存比 int 小。


问题 2:(u8 code smgduan[ ]={ })
为什么共阴数码管段编码数据需要用 u8 类型的来定义,而不是 int 类型或者其他类型的;

答案:
同1。


问题 3:(void delay(u16 i){ })
为什么延时函数要用 u16 类型的来定义,而不是 u8 类型或者 int 类型;

答案:
delay()延时函数通常取较大的数字,char 的范围(-128~127),u8 是(0~255),int 的范围(-2^31~2^(31-1)),u16 的范围(0~2^(31-1))。显然,(0~255)不能满足延时的需求。


问题 4:(u8 a=0; )
这个语句定义 a 是用来干什么用的,为什么是 u8 字符类型来定义,而不是用 char 类型或者 int 类型。

答案:
a 是用来检测按键是否松开的,每隔多少秒检测一次,未松开则 a++, 若到达一定次数则判定未松开,这里显然 a 也不可能为负数,故用u8。


你可能感兴趣的:(Unit))