51单片机入门03--按键

Catalogue
  1. 1. 51单片机入门03–按键
    1. 1.1. 键盘的原理
      1. 1.1.1. 分类
      2. 1.1.2. 键位的识别
    2. 1.2. 示例:每次按下按键试数码管数字加一(独立键盘)
    3. 1.3. 示例:按下不同的按键显示不同的数字(矩阵键盘)

51单片机入门03–按键

键盘的原理

image-20200513133011891

按键需要一个上拉电阻,当没有按下去的时候,由于上拉电阻,左边的端口是高电平,当按键闭合后,左边的端口会变成低电平

这里按下的瞬间存在一个电平抖动的问题,所以需要消除抖动:

  1. 硬件消抖:锁存器
  2. 软件消抖:延时程序

分类

分为两类:

  1. 独立式键盘
    • 每个按键占用一根并口线
    • 用于键位较少的情况,处理简单
  2. 矩阵键盘
    • 键位分布在行列交叉点上
    • 占用并口少,键位越多越明显

后面将以示例介绍两种键盘

键位的识别

对于独立式键盘:直接识别对应并口即可

对于矩阵键盘:

  1. 先检测键盘上是否有键被按下
  2. 然后识别按下的是哪一个按键

示例:每次按下按键试数码管数字加一(独立键盘)

原理图:

image-20200513193902218

P1~P3自带上拉电阻,P0需要自己加上拉电阻

代码:

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
#include "reg51.h"
unsigned char s[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
sbit key0=P0^0;
unsigned char num=0;flag=0;

//程序消抖
void key(){
if(key0==0&&flag==0){ //判断按键是否按下
flag=1;
}
if(key0==1&&flag==1){ //判断按键是否从按下状态中弹起,如果是,则实现功能
num++;
flag=0;
}
}


void seg(){
if(num>9)num=0;
P2 = s[num];
}


void main(){
while(1){
key();
seg();
}
}

示例:按下不同的按键显示不同的数字(矩阵键盘)

原理图:

image-20200513204000884

如何判断按下的按键是哪个按键?

1
2
3
4
5
6
L3 L2 L1 L0 H3 H2 H1 H0  hex
0 0 0 0 1 1 1 1 0x0f 默认情况
0 0 0 0 1 1 1 0 0x0e 判断按下按键的行,H0
1 1 1 1 0 0 0 0 0xf0 默认情况取反
1 1 0 1 0 0 0 0 0xd0 判断按下按键的列,L1
将第二行和第四行的值相加:0xde 即为(H0,L1)按键在P2中的值

代码:

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
#include "reg51.h"
unsigned char s[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char num=99;

void delay(int n){
int i=0,j=0;
for(i=0;i<n;i++){
for(j=0;j<120;j++);
}
}


void key_scan(){
unsigned char tmp=0,tmp0=0,tmp1=0;

//判断按下去的按键
P1=0x0f;
if(P1!=0x0f){
delay(20);//还是这样消除抖动最方便
tmp0 = P1;
P1=0xf0;
if(P1!=0xf0) tmp1 = P1;
}
tmp = tmp1+tmp0;

//实现功能
if (tmp == 0xee)num=0; //display 0
if (tmp == 0xde)num=1; //display 1
}


void display(){
P2=s[num];
}


void main(){
while(1){
key_scan();
display();
}
}