【Proteus仿真】51单片机+4X4矩阵按键扫描+数码管0-F显示

51单片机+4X4矩阵按键扫描+数码管0-F显示


  • 🎞📽📺🎬Proteus仿真实验一效果:
    在这里插入图片描述
  • 🎞📽📺🎬Proteus仿真实验二效果:
    在这里插入图片描述
  • 📓工程项目一架构在这里插入图片描述

📚工程项目一功能说明

📝按键4x4共16个按键,通过按下对应的按键,分别显示0-9,a-f,字符。

  • 🔰数码管显示

✨采用的的共阴数码管,代码实现部分:

1
2
3
4
5
6
7
8
//共阴数码管段码表
unsigned char code seg[]={0x3f/\*0\*/,0x06/\*1\*/,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77/\*A\*/,0x7C,0x39,0x5E,0x79,0x71/\*F\*/};
void display(unsigned char Num)
{
P2=seg[Num];

}

  • 🔰4x4矩阵部分
    在这里插入图片描述

🌼按键扫描功能算法实现方法一:

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
uint16\_t key\_scan(void)
{
uint16\_t key_val=0;
uint16\_t temp=0;
/\*\*\*\*\*\*\*\*\*\*\*\*\*扫描第1行\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
P1 = 0X00;
P1 = 0XF7;
if((P1&0XF0)!=0XF0)
{
delay\_ms();//消抖
if((P1 & 0XF0)!=0XF0)
{
temp=(P1&0XF7);
switch(temp)
{
case 0xE7: key_val=1; break;
case 0xD7: key_val=2; break;
case 0xB7: key_val=3; break;
case 0x77: key_val=4; break;
default: key_val=0; break;
}
}
}

/\*\*\*\*\*\*\*\*\*\*\*\*\*扫描第2行\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
P1=0X00;
P1=0XFB;
if((P1&0XF0)!=0XF0)
{
delay\_ms();
if((P1 & 0XF0)!=0XF0)
{
temp=(P1&0XFB);
switch(temp)
{
case 0xEB: key_val=5; break;

case 0xDB: key_val=6; break;

case 0xBB: key_val=7; break;

case 0x7B: key_val=8; break;

default: key_val=0; break;
}
}
}

/\*\*\*\*\*\*\*\*\*\*\*\*\*扫描第3行\*\*\*\*\*\*\*\*\*\*\*\*/
P1=0X00;
P1=0XFD;
if((P1&0XF0)!=0XF0)
{
delay\_ms();
if((P1 & 0XF0)!=0XF0)
{
temp=(P1&0XFD);
switch(temp)
{
case 0xED: key_val=9; break;
case 0xDD: key_val=10; break;
case 0xBD: key_val=11; break;
case 0x7D: key_val=12; break;
default: key_val=0; break;
}
}
}
/\*\*\*\*\*\*\*\*\*\*\*\*\*Scan 4st Line\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*/
P1=0X00;
P1=0XFE;
if((P1&0XF0)!=0XF0)
{
delay\_ms();
if((P1 & 0XF0)!=0XF0)
{
temp=(P1&0XFE);
switch(temp)
{
case 0xEE: key_val=13; break;
case 0xDE: key_val=14; break;
case 0xBE: key_val=15; break;
case 0x7E: key_val=16; break;
default: key_val=0; break;
}
}
}
return key_val;
}

🌼按键扫描功能算法实现方法二:

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
uint16\_t key\_scan(void)
{
uint16\_t key_val=0;
u8 KeyNO =0x10;
//行码、列码及扫描得到的关码
u8 row,colm;
P1 = 0xf0;
delay\_ms();
if(P1 !=0xf0)
{
delay\_ms();
if(P1 !=0xf0)
{
row = P1;
P1 = 0x0f;
delay\_ms();
colm = P1;
KeyNO = row + colm;
switch(KeyNO)
{
case 0xf0: key_val = 0;break;
case 0xe7: key_val = 1;break;//?1110 0111?
case 0xd7: key_val = 2;break;//?1101 0111?
case 0xb7: key_val = 3;break;//?1011 0111?
case 0x77: key_val = 4;break;// 0111 0111
case 0xeb: key_val = 5;break;//?1110 1011?
case 0xDB: key_val = 6;break;// 1101 1011
case 0xbb: key_val = 7;break;//?1011 1011?
case 0x7b: key_val = 8;break;//?0111 1011?
case 0xed: key_val = 9;break;//?1110 1101?
case 0xdd: key_val = 10;break;//?1101 1101?
case 0xbd: key_val = 11;break;//?1011 1101?
case 0x7d: key_val = 12;break;//?0111 1101?
case 0xee: key_val = 13;break;//?1110 1110?
case 0xde: key_val = 14;break;//?1101 1110?
case 0xbe: key_val = 15;break;//?1011 1110?
case 0x7e: key_val = 16;break;//?0111 1110? ``
default: key_val = 0;
}

}
}
return key_val;
}

🌻按键扫描功能算法实现方法三:

这种是纵向排列的,与前面的两种数字标号不一样。

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
sbit L1=P1^3;   //定义键盘的4列线
sbit L2=P1^2;
sbit L3=P1^1;
sbit L4=P1^0;
uint16\_t key\_scan(void)
{
uint16\_t key_val=0;
uint8\_t i=0;
P1=0xef; //行扫描初值,P1.4=0,P1.5~P1.7=1
for(i=0;i<=3;i++) //按行扫描,一共4行
{
if(L1==0) key_val=i\*4+1; //判断第一列是否有键按下
if(L2==0) key_val=i\*4+2; //判断第二列是否有键按下
if(L3==0) key_val=i\*4+3; //判断第三列是否有键按下
if(L4==0) key_val=i\*4+4; //判断第四列是否有键按下
delay\_ms(); //延时
temp=P1; //读入P1口状态
temp=temp|0x0f;//使P1.3~P1.0为输入
temp=temp<<1; //P1.7~P1.4左移1位,准备下一行扫描
temp=temp|0x0f; //移位后,置P1.3~P1.0为1,保证其仍为输入
P1=temp; //行扫描值送P1口,为下一行扫描做准备
}
return key_val;
}

📖工程项目一主程序代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "key\_scan.h"
#include "SEG.h"

void main()
{
static uint16\_t Key_Value=0;
display(0);
while(1)
{
Key_Value = key\_scan();
if((Key_Value !=0) && (Key_Value != 16))
display(Key_Value);
else if(Key_Value == 16)
display(0);
}

}

⛳工程项目一源码和仿真资源

🍁基于Proteus8.12版本仿真

1
2
3
链接:https://pan.baidu.com/s/16\_9CiAQmoV61NMHtoqb45Q 
提取码:bjk8


📖工程项目二

✨采用共阳数码管作为显示,外部按键扫描引入了74LS148来扩展中断,只有在按键被按下的时候才会触发按键扫描。
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
#include <reg52.h>

#define uchar unsigned char
#define uint unsigned int

sbit BEEP = P3 ^ 0;

uchar code DSY_CODE[] =
{
0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90, 0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e, 0xff
};//共阳段码:0 - F

uchar Pre_KeyNO = 16, KeyNO = 16;
static bit Button_State = 0;

void DelayMS(uint ms)
{
uchar t;
while(ms--)
{
for(t = 0; t < 120; t++);
}
}

void Keys\_Scan()
{
uchar Tmp;
EX0 = 0;
P1 = 0x0f;
// DelayMS(1);
Tmp = P1 ^ 0x0f;
switch(Tmp)
{
case 1: KeyNO = 0; break;
case 2: KeyNO = 1; break;
case 4: KeyNO = 2; break;
case 8: KeyNO = 3; break;
default: KeyNO = 16;
}
P1 = 0xf0;
DelayMS(1);
Tmp = P1 >> 4 ^ 0x0f;
switch(Tmp)
{
case 1: KeyNO += 0; break;
case 2: KeyNO += 4; break;
case 4: KeyNO += 8; break;
case 8: KeyNO += 12;
}
Button_State = 0;
EX0 = 1;
}

void Beep()
{
uchar i;
for(i = 0; i < 120; i++)
{
DelayMS(1);
BEEP = ~BEEP;
}
BEEP = 1;
}

void T0\_Init() //定时器0初始化
{
TMOD = 0x01;
TH0 = 0x3c;
TL0 = 0xb0;
EA = 1; //开总中断
ET0 = 1;
TR0 = 1;
}
void main()
{
P0 = 0xff;//数码管什么都不显示
// T0\_Init();//定时器0初始化
IE = 0x81;//使能EA EX0
IT0 = 1;//一定要选择:边沿触发
while(1)
{
P1 = 0xf0;
if(Button_State){
Keys\_Scan();}

if(Pre_KeyNO != KeyNO)
{
P0 = DSY_CODE[KeyNO];
Beep();
Pre_KeyNO = KeyNO;
}
// DelayMS(100);
}
}

void timer0\_Init() interrupt 1 //定时器0中断函数
{

TL0 = (65536 - 1000) % 256; //1ms预装载值
TH0 = (65536 - 1000) / 256;

}
void EX\_INT0() interrupt 0
{
Button_State = 1;
}


📚工程项目二资源

1
2
3
链接:https://pan.baidu.com/s/1fdpZx6OftxkZfTqu7uo2iA 
提取码:in8t