【Proteus仿真】51单片机4x4矩阵键盘扫描lcd1602显示

【Proteus仿真】51单片机4x4矩阵键盘扫描lcd1602显示


📝主程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <REGX51.H>
#include "LCD1602.H"

/\*\*\* 0-15键值 \*\*\*/
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
0x77,0x7B,0x7D,0x7E
0xB7,0xBB,0xBD,0xBE
0xD7,0xDB,0xDD,0xDE
0xE7,0xEB,0xED,0xEE

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/

unsigned char Key\_Scan(); //按键扫描函数声明

/\* 主函数从这里开始 \*/
void main(void)
{
static unsigned char Key_Code = 0x00; //定义一个静态变量

LCD\_Init(); //初始化LCD1602,用来显示键值
LCD\_ShowString(1,3,"Matrix Key");
while(1)
{
Key_Code = Key\_Scan();
switch (Key_Code) //演示示例;用switch语句操作键码;比如我在1602液晶屏上显示数字1-16;也可以用数组来操作,自由发挥!
{
case 0x77: LCD\_ShowNum(2,6,1,2); break;
case 0x7B: LCD\_ShowNum(2,6,2,2); break;
case 0x7D: LCD\_ShowNum(2,6,3,2); break;
case 0x7E: LCD\_ShowNum(2,6,4,2); break;
case 0xB7: LCD\_ShowNum(2,6,5,2); break;
case 0xBB: LCD\_ShowNum(2,6,6,2); break;
case 0xBD: LCD\_ShowNum(2,6,7,2); break;
case 0xBE: LCD\_ShowNum(2,6,8,2); break;
case 0xD7: LCD\_ShowNum(2,6,9,2); break;
case 0xDB: LCD\_ShowNum(2,6,10,2); break;
case 0xDD: LCD\_ShowNum(2,6,11,2); break;
case 0xDE: LCD\_ShowNum(2,6,12,2); break;
case 0xE7: LCD\_ShowNum(2,6,13,2); break;
case 0xEB: LCD\_ShowNum(2,6,14,2); break;
case 0xED: LCD\_ShowNum(2,6,15,2); break;
case 0xEE: LCD\_ShowNum(2,6,16,2); break;
default: break;
}
}
}

/\* 带返回值的按键扫描函数\*/
unsigned char Key\_Scan()
{
unsigned char Key_Temp; //定义一个存放组合键码的变量
unsigned char Key_A,Key_B; // 定义两个变量,Key\_A 用于存放正向扫描的键码; Key\_B 用于存放反向扫描的键码。

P1 = 0xF0; //把P1口的高4位(P1.4-P1.7)置高,低4位置低;(如果有按键按下 高4位肯定有一条线会被拉低)。
Key_Temp = P1; //把P1口的状态读回来,传递给Key\_Temp。没有按键按下Key\_Temp肯定是0XF0; 否则就是其它的数;
if(Key_Temp!= 0xF0) // 进入if判断语句;如果Key\_Temp不等于0XF0,说明有键按下了。
{
Key_A = P1; // 把P1口此时被按下的状态传递给Key\_A保存
P1 = 0x0F; //开始反转扫描;把P1口的高4位置低,低4位(P1.0-P1.3)置高;(如果有按键按下 低4位肯定有一条线会被拉低)。
Key_B = P1; //把P1口此时被按下的状态传递给Key\_A保存
}

Key_Temp = (Key_A | Key_B); //把正反两次扫描的结果相或, 就会得到按键按下的正确键码
return Key_Temp; //把键码返回,给其他的函数调用
}


//下面是图解正反转扫描的程序工作原理

/\*
正向扫描,比如P1.7和P1.3连接的按键被按下 那么P1口的0XF0:1111 0000 就会变成0X70:0111 0000

P1.3 P1.2 P1.1 P1.0
0 0 0 0
P1.7 1 -+- --- --- ---

P1.6 1 --- --- --- ---

P1.5 1 --- --- --- ---

P1.4 1 --- --- --- ---



反向扫描,比如P1.7和P1.3连接的按键被按下 那么P1口的0X0F:0000 1111 就会变成0X07:0000 0111

P1.3 P1.2 P1.1 P1.0
1 1 1 1
P1.7 0 -+- --- --- ---

P1.6 0 --- --- --- ---

P1.5 0 --- --- --- ---

P1.4 0 --- --- --- ---


最后把 正反两次扫描的结果 0X70 与0X07相或 就会得到0X77的键码
只要得到正确的键码,就可以用这个键码做任何事情。比如我在液晶屏上显示数字1;表示数字1键被按下。
\*/

//下面这组键值根据不同的接线方式,会有不同的键值,需要提前自己算好;就类似数码管的段码一样;也可以做成一个数组。
/\*\*\* 0-15键值 \*\*\*/
/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*
0x77,0x7B,0x7D,0x7E
0xB7,0xBB,0xBD,0xBE
0xD7,0xDB,0xDD,0xDE
0xE7,0xEB,0xED,0xEE

\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/




📚程序源码和仿真资源

  • 🔖基于Proteus8.12
1
2
3
链接: https://pan.baidu.com/s/1N2Q5dXZr5i-CxL5jkhk8jA
提取码: q4ue