51单片机学习记录(7) “矩阵按键”
首先还是让我们先看一下原理图
可以看的出来,矩阵按键的连接方式
- 矩阵按键是由P1口控制的
- P1口的高四位(P17–P14)控制着矩阵按键的行
- P1口的低四位(P13–P10)控制着矩阵按键的列
行列扫描
这里为了判断具体是哪个按键被按下,采用了行列扫描的方法,现在来具体说明行列扫描的具体操作原理
行列扫描的步骤
- 先让高四位都为0,低四位都为1 ---为了判断列
- 再让高四位都为1,低四位都为0 ---为了判断行
假设我们按下的是第3行第2列按上述步骤(按下时,变为低电平)
首先先判断列
低四位 | P1^3 | P1^2 | P1^1 | P1^0 |
---|---|---|---|---|
对应列 | 第一列 | 第二列 | 第三列 | 第四列 |
值 | 1 | 0 | 1 | 1 |
因为高四位为0
所以第二列对应的值(0000 1011) = (0x0b)
同理判断行
高四位 | P1^7 | P1^6 | P1^5 | P1^4 |
---|---|---|---|---|
对应行 | 第一行 | 第二行 | 第三行 | 第四行 |
值 | 1 | 1 | 0 | 1 |
因为低四位为0
所以第3行对应的值(1101 0000) = (0xd0)
最后编写程序,用矩阵按键来控制数码管
#include <reg51.h>
typedef unsigned char u8;
typedef unsigned int u16;
#define JuZhen P1 //宏定义控制矩阵按键P1口
#define smg P0 //宏定义控制数码管的P0口
//定义控制数码管的引脚
sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;
//定义存放显示十六位进制数的数组
u8 code smgduan[]={ 0x3f,0x06,0x5b,0x4f,
/* 0 1 2 3 */
0x66,0x6d,0x7d,0x07,
/* 4 5 6 7 */
0x7f,0x6f,0x77,0x7c,
/* 8 9 A B */
0x39,0x5e,0x79,0x71
/* C D E F */}
u8 KeyValue; //定义一个全局变量,用来存放具体是哪个按键被按下
void delay(u16); //声明延时函数
void Ju_Zhen(); // 声明判断哪个按键被按下的函数
void main()
{
while(1)
{
LSA = 0;
LSB = 0;
LSC = 0;
Ju_Zhen();
smg = smgduan[Keyvalue];
}
}
void delay(u16 i)
{
while(i--);
}
void Ju_Zhen()
{
u8 a;
/*准备进行行列扫描来判断*/
JuZhen = 0x0f; //先让矩阵按键的高四位为0,低四位为1,这一步主要是为了后面判断是否有按键按下
if(JuZhen != 0x0f) //如果不等于0x0f说明有按键被按下
{
delay(1000); //同样的需要进行按键的消抖
if(JuZhen != 0x0f) //再次判断是否按下了按键
{
JuZhen = 0x0f; //确定按下后给定初值开始进行对列的扫描
switch(JuZhen)
{
case 0x07: KeyValue=0;break; //表示第一列有按键被按下
case 0x0b: KeyValue=1;break; //表示第二列有按键被按下
case 0X0d: KeyValue=2;break; //表示第三列有按键被按下
case 0x0e: KeyValue=3;break; //表示第四列有按键被按下
}
JuZhen = 0xf0; //判断完列重新赋初值进行对行的扫描
switch(JuZhen)
{
case 0x70: KeyValue+=0;break; //表示第一行有按键被按下
case 0xb0: KeyValue+=4;break; //表示第二行有按键被按下
case 0xd0: KeyValue+=8;break; //表示第三行有按键被按下
case 0xe0: KeyValue+=12;break;//表示第四行有按键被按下
}
/*判断按下按键是否超时,是否已经松开*/
while((a < 50) && (JuZhen != 0xf0))
{
delay(1000);
a++;
}
}
}
}
/*最后说一下KeyValue,举个例子,比如我们按下的是第2列的第2行,程序里,第一次判断完列后KeyValue=1
接着继续判断行,KeyValue就加了4,为什么是4呢,这就跟矩阵按键的布局有关了,我所使用的矩阵按键是4X4的,
假设第一个按键是0,第二个按键是1,依次类推 那么第2列第2行的按键就是5,通过简单的加法就可以计算出具体需要加多少了*/
最后实验的效果就是,按下第一个按键数码管显示0,按下第二个按键数码管显示1,依次下去。