第五讲:独立键盘、矩阵键盘的检测原理及实现(郭天祥)

news/2024/11/8 16:48:34/

说明:此文章仅是我学习过程中的一些记录,如有侵权,请联系我删除,文章中难免有遗漏错误之处,欢迎指出。

目录

一、键盘的分类

二、独立键盘的识别

三、一个读取独立按键状态的程序

四、矩阵键盘的识别

五、按下矩阵键盘使数码管上显示0~F间的一个数的程序


一、键盘的分类

        键盘分编码键盘和非编码键盘。键盘上闭合键的识别由专用的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘。

而靠软件编程来识别的称为非编码键盘;

在单片机组成的各种系统中,用的最多的是非编码键盘。也有用到编码键盘的。

非编码键盘有分为:独立键盘和行列式(又称为矩阵式)键盘

二、独立键盘的识别

                                                 

独立键盘的接法通常如上图所示,通过将键盘连接在单片机的I/O口,并利用I/O口来读取按键是否被按下I/O口连接到按钮的一端,按钮另一端接地

那么,具体是如何利用I/O口来检测的呢,我们首先要了解下面的内容。

我们暂且将单片机输出与输入定义为TTL电平,具体内容详情郭老师的教材。

在TTL电路中,如果I/O口没有三态状态,它与跟它相连的线是线与关系。

而在89C51型号的单片机中P1,P2,P3口都是准双向8位I/O口,每个口可独立控制,内带上拉电阻,这种接口输出没有高阻状态,输入也不能锁存,故不是真正的双向I/O口。之所以称它为“准双向”,是因为该口在作为输入使用前,要先向该口进行写1操作。

说了这么多,我们最终要知道的就是,准双向I/O口即没有三态状态,所以它与跟它相连的线是线与的关系。上图中的P3口是准双向I/O口,它通过按钮与GND相连,所以当按钮按下,相连的P3口变成低电平状态,并且在按钮按下之前,我们必须先向其写1,才可以通过当前是高电平还是低电平判断是否按下。

注:如果I/O口有三态功能,即有高阻态功能,例如89C51型号单片机的P0口,它与跟它相连的线则是线或关系。

三、一个读取独立按键状态的程序

现在让我们来具体写一个程序,判断开发板上的独立按键之S2按键是否被按下,按下时,第一个发光二极管点亮,松手时熄灭

首先是找到S2按键对应单片机的哪个I/O口。与键盘相关的原理图如下。

可以看到S2按键对应的是单片机的P3.4口,因此要对其进行操作。

对单片机I/O口的操作主要有两步,一是位定义,方便后面程序的书写,二是进行“先写1”操作,在本程序中,我们选用的是直接对整个P3口进行写1操作,当然也可以只对我们想操作的I/O口进行单独操作。

然后就是判断按键是否按下了:

if(key1 == 0)

当我们按下按键时,单片机I/O口与地是线与的关系,所以该I/O口是低电平状态。

以及松手检测

while(!key1);

当I/O口是低电平状态,即按键在按下状态时,一直在while循环中等待,直到松手了再执行下面的语句。

那么,为什么要添加消抖和松手检测呢?原因如下:

按键在闭合和断开时,触点会存在抖动现象。

示意图如上。当我们手动按下与松开一次按键时,由于抖动的关系,如果只是用简单的一个if语句进行判断,计算机会判断我们按下了多次按键,也许在一个简单的按下按键点亮发光二极管的程序中,并不明显看出,但是如果我们的程序时,每按下一次按键,数码管显示内容自动加1,就可以很明显的看出,有时候我们按下一次按键,数码管却加了好几个数。所以,我们应该消抖,防止噪声。

消抖有两种方法,一种是软件法,利用delay函数,进行两次if语句的判断,delay函数消除掉按下抖动的时间,而释放抖动一般不用考虑,当然也可以写。 

if(key1 == 0)

        {

        delay(5);

        if(key1 == 0)

        ......

释放抖动的消除其实就是在松手检测语句下面写一个delay函数,然后再写一句松手检测语句。

while(!key1);

delay(5);

while(!key1); 

至于delay的时间,一般可取5~10ms,常取10ms,当然也可以取5ms,尽量不让CPU过多地等待。

还有一种是硬件法,接法如下,这里不介绍。

代码如下:

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit D1 = P1^0;
sbit key1 = P3^4; //P3.4口对应键盘S2
void delay(uint z)  //延时函数,z的取值为这个函数的延时ms数,如delay(200);大约延时200ms.
{					//delay(500);大约延时500ms.uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);	
}
void main()
{P3 = 0xff;//先写1while(1){if(key1 == 0)          {delay(10);   //消抖if(key1 == 0){D1 = 0;  //发光二极管亮}				while(!key1);	 //松手检测delay(10);while(!key1);	}else{D1 = 1;}    }
}

四、矩阵键盘的识别

下面是矩阵键盘的典型接法。各连线的I/O口之间仍为线与的关系。分行读取,每次只能读取一行中某个按键的按下。

矩阵键盘的识别方法其实和独立键盘类似,都是检测低电平,但矩阵键盘没固定接地,接的是I/O口,地(即低电平)由写程序给它

以扫描第一行为例,通过给P3.0口赋低电平其他口给高电平为基础,通过对P3.4~P3.7口的读取,若P3.4口读取结果是低电平,则第一行第一个按键按下,依次类推,后面三个按键。

检测完第一行,检测第二行,同理,给P3.1口赋低电平,其他口给高电平,再读取P3.4~P3.7口的电平情况,第三、四行也如此,通过分别给P3.2,P3.3口赋值低电平,然后对P3.4~P3.7口进行读取,来判断是否有按键按下。

五、按下矩阵键盘使数码管上显示0~F间的一个数的程序

观察开发板上的矩阵键盘连接图,可以看到与典型接法一致。

具体代码如下:

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[] = {       
0x3f  , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d ,
0x7d , 0x07 , 0x7f  , 0x6f , 0x77 , 0x7c ,
0x39 , 0x5e , 0x79 , 0x71}; 
sbit wela = P2^7;
sbit dula = P2^6;
uchar num,temp;
void delay(uint z)  //延时函数,z的取值为这个函数的延时ms数,如delay(200);大约延时200ms.
{					//delay(500);大约延时500ms.uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);	
}
void main()
{dula = 1;P0 = 0;dula = 0;wela = 1;P0 = 0xc0;wela = 0;while(1) //始终检测键盘{P3 = 0xfe; //检测第一行temp = P3; //读回来,如果有键按下肯定不一样temp = temp&0xf0;//比较while(temp != 0xf0)//第一行有按键按下{delay(5); //去抖temp = P3;temp = temp&0xf0;while(temp != 0xf0){temp = P3; //循环检测同一行switch(temp){case  0xee:num = 1;break;case  0xde:num = 2;break;case  0xbe:num = 3;break;case  0x7e:num = 4;break;}while(temp!=0xf0){temp = P3;temp = temp&0xf0;//松手检测,退出while}dula = 1;P0 =table[num - 1];dula = 0;}}P3 = 0xfd; //检测第二行temp = P3;temp = temp&0xf0;while(temp != 0xf0){delay(5);temp = P3;temp = temp&0xf0;while(temp != 0xf0){temp = P3;switch(temp){case  0xed:num = 5;break;case  0xdd:num = 6;break;case  0xbd:num = 7;break;case  0x7d:num = 8;break;}while(temp!=0xf0){temp = P3;temp = temp&0xf0;//松手检测,退出while}dula = 1;P0 =table[num - 1];dula = 0;}}P3 = 0xfb; //第三行temp = P3;temp = temp&0xf0;while(temp != 0xf0){delay(5);temp = P3;temp = temp&0xf0;while(temp != 0xf0){temp = P3;switch(temp){case  0xeb:num = 9;break;case  0xdb:num = 10;break;case  0xbb:num = 11;break;case  0x7b:num = 12;break;}while(temp!=0xf0){temp = P3;temp = temp&0xf0;//松手检测,退出while}dula = 1;P0 =table[num - 1];dula = 0;}}P3 = 0xf7; //第四行temp = P3;temp = temp&0xf0;while(temp != 0xf0){delay(5);temp = P3;temp = temp&0xf0;while(temp != 0xf0){temp = P3;switch(temp){case  0xe7:num = 13;break;case  0xd7:num = 14;break;case  0xb7:num = 15;break;case  0x77:num = 16;break;}while(temp!=0xf0){temp = P3;temp = temp&0xf0;//松手检测,退出while}dula = 1;P0 =table[num - 1];dula = 0;}}}
}

 其中关键语句是:

P3 = 0xfe;

扫描第一行,给P3.0口赋值低电平,其他赋值高电平,然后是

temp  = P3;

把P3口的状态赋值给temp,接着变是利用按位与操作,读取P3口的高四位是否有按下

temp = temp&0xf0;

将temp与0xf0即11110000进行按位与操作,如果没有按键按下,因为P3 = 0xfe的缘故,temp与0xf0按位与的结果仍然是0xf0,而如果按键按下,则temp的高四位将有低电平的出现,按位与的结果就不会是0xf0利用按位与之后的temp与0xf0去比较,可以判断出按键是否有按下,最后再将P3的值赋值给temp,利用switch case语句判断按下的是哪个按键,进而进行处理,后面三行同样是这种操作。

上述代码有重复性的内容,在实际中,常利用带返回值的子函数来书写这个代码,如下:

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uchar code table[] = {       
0x3f  , 0x06 , 0x5b , 0x4f , 0x66 , 0x6d ,
0x7d , 0x07 , 0x7f  , 0x6f , 0x77 , 0x7c ,
0x39 , 0x5e , 0x79 , 0x71,0}; 
sbit wela = P2^7;
sbit dula = P2^6;
uchar keyscan();
void display(uchar num11);
uchar num,temp,num1;
void delay(uint z)  //延时函数,z的取值为这个函数的延时ms数,如delay(200);大约延时200ms.
{					//delay(500);大约延时500ms.uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);	
}
void main()
{num = 17;dula = 1;P0 = 0;dula = 0;wela = 1;P0 = 0xc0;wela = 0;while(1) //始终检测键盘{display(keyscan());}
}uchar keyscan()
{P3 = 0xfe; //检测第一行temp = P3; //读回来,如果有键按下肯定不一样temp = temp&0xf0;//比较while(temp != 0xf0){delay(5); //去抖temp = P3;temp = temp&0xf0;while(temp != 0xf0){temp = P3; //循环检测同一行switch(temp){case  0xee:num = 1;break;case  0xde:num = 2;break;case  0xbe:num = 3;break;case  0x7e:num = 4;break;}while(temp!=0xf0){temp = P3;temp = temp&0xf0;//松手检测,退出while}}}P3 = 0xfd; //第二行temp = P3;temp = temp&0xf0;while(temp != 0xf0){delay(5);temp = P3;temp = temp&0xf0;while(temp != 0xf0){temp = P3;switch(temp){case  0xed:num = 5;break;case  0xdd:num = 6;break;case  0xbd:num = 7;break;case  0x7d:num = 8;break;}while(temp!=0xf0){temp = P3;temp = temp&0xf0;//松手检测,退出while}}}P3 = 0xfb; //第三行temp = P3;temp = temp&0xf0;while(temp != 0xf0){delay(5);temp = P3;temp = temp&0xf0;while(temp != 0xf0){temp = P3;switch(temp){case  0xeb:num = 9;break;case  0xdb:num = 10;break;case  0xbb:num = 11;break;case  0x7b:num = 12;break;}while(temp!=0xf0){temp = P3;temp = temp&0xf0;//松手检测,退出while}}}P3 = 0xf7; //第四行temp = P3;temp = temp&0xf0;while(temp != 0xf0){delay(5);temp = P3;temp = temp&0xf0;while(temp != 0xf0){temp = P3;switch(temp){case  0xe7:num = 13;break;case  0xd7:num = 14;break;case  0xb7:num = 15;break;case  0x77:num = 16;break;}while(temp!=0xf0){temp = P3;temp = temp&0xf0;//松手检测,退出while}}}return num;
}void display(uchar num11)
{dula = 1;P0 = table[num11 - 1];dula = 0;
}

http://www.ppmy.cn/news/461898.html

相关文章

三、键盘检测原理及应用实现

键盘检测原理及应用实现 视频链接&#xff1a;[3-4] 独立按键控制LED移位_哔哩哔哩_bilibili 对应课程P7-P10 键盘实际上就是一组按键&#xff0c;在单片机的外围电路中&#xff0c;通常用到的按键都是机械弹性开关&#xff0c;当开关闭合时&#xff0c;线路导通&#xff0c;开…

实验 键盘与LED实验

实验 键盘与LED实验 一、实验要求 P0口接7段LED数码管&#xff0c;P1口接8个独立按钮&#xff0c;分别控制数码管显示数字0-7&#xff0c;画出原理电路图&#xff0c;编写驱动程序。 二、实验目的 1、熟练keil软件的基本操作&#xff1b; 2、掌握80c51单片机p1口的使用方法…

html 游戏键盘,HTML tabindex属性与web网页键盘无障碍访问

本文要介绍的是属性tabindex和下一篇要介绍的accesskey&#xff0c;与web网页无障碍访问息息相关&#xff0c;而且是键盘访问领域的。这些属性不仅可以触发浏览器层面的行为&#xff0c;本身对HTML的元素的交互特性甚至UI表现都会有影响。下面就来看看今天的重点HTML tabindex属…

键盘扫描并控制数码管C语言,CH454 数码管显示驱动和键盘扫描控制芯片

1、概述 CH454 是数码管显示驱动和键盘扫描控制芯片。CH454内置时钟振荡电路&#xff0c;可以动态驱动8 只16段的数码管或者128 只LED&#xff0c;支持11 段、14 段、16 段8 以及17 段7 等;同时还可以进行64 键的键盘扫描;CH454 通过2 线串行接口与单片机等交换数据。 2、特点 …

查询式键盘实验c语言,单片机实验上机--实验十七查询式键盘实验.doc

单片机实验上机--实验十七查询式键盘实验 实验十七 查询式键盘实验 一、实验目的 1、掌握键盘和显示器的接口方法和编程方法 2、掌握键盘和八段码显示器的工作原理 3、静态显示的原理和相关程序的编写 二、实验说明 本实验提供了8个按钮的小键盘,如果有键按下,则相应输出为低…

计算机键盘英语,电脑键盘打字时中英文如何切换?

1、首先&#xff0c;需要安装输入法&#xff0c;安装完毕之后按照输入法默认设置就可以&#xff1b;或者是您可以尝试使用键盘上的【Shift】 【Ctrl】组合键调出输入法&#xff0c;一般会在右下角状态栏上显示当前的输入法&#xff1b; 2、在输入法的状态栏中可以看到当前输入法…

Win11触摸键盘主题如何更换

Win11触摸键盘主题要如何更换&#xff1f;现在有一些使用Windows11平板电脑的朋友&#xff0c;大家会用到触摸键盘&#xff0c;因此也希望显示出来好看一点&#xff0c;所以想要去更换触摸键盘主题颜色&#xff0c;那么应该如何操作呢&#xff1f;下面我给CSDN的朋友讲讲Win11更…

计算机控制键盘,键盘装置及其计算机控制系统的制作方法

技术特征&#xff1a; 1.一种键盘装置&#xff0c;其特征在于&#xff1a;包括一键盘本体&#xff0c;该键盘本体上形成有一操作面&#xff0c;并该操作面的两侧边分别形成有一邻近边及一远离边&#xff0c;且该操作面上设置有复数按键及至少一发光元件&#xff0c;另该键盘本体…