单片机/MCU论坛
直播中

晓白嵌入式

8年用户 727经验值
擅长:嵌入式技术
私信 关注
[文章]

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

/*    矩阵按键控制程序*/#include typedef unsigned char u8;typedef unsigned int u16;***it LSA=P2^2;  //定义 P2 口的第 2 位为特殊位变量 LSA***it LSB=P2^3;  //定义 P2 口的第 3 位为特殊位变量 LSB***it 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。

回帖(1)

杨洋

2020-11-23 10:56:51
厉害,蟹蟹分享
举报

更多回帖

发帖
×
20
完善资料,
赚取积分