矩阵键盘原理图:
第一行的行控制线接到p17,第二行的行控制线接到p16,第三行的行控制线接到p15,第4行的行控制线接到p14
第一列的列控制线接到p13,第二列的列控制线接到p12,第三列的列控制线接到p11,第四列的列控制线接到p10

矩阵键盘的原理和独立按键类似,另外我们可以把矩阵键盘的任意一行或一列作为一个独立键盘使用,假如我们把第一行作为独立键盘,那么我们只需要让P17输出高电平,其余7个io口输出低电平即可,假如我们按下了s1,那么p13的电平就会被拉低,变为低电平,所以我们可以通过查找低4位里哪一位为低电平就可以知道哪个按键按下了。

下面来说说矩阵按键扫描原理(即当我们按下一个矩阵键盘的按键时,如何获取按键的位置)

方法有2种,一种是逐行扫描,一种是行列扫描.接下来就主要讲讲行列扫描.

行列扫描的话,就是一开始让p1口高4位输出高电平,低4位输出低电平,若这4行按键里,有按键按下了,那么那一行按键对应的io的电平就会被拉低,我们就可以知道按键的行坐标.获取按键列坐标的方法也是类似的,就是一开始让p1口高4位输出低电平,低4位输出高电平,若这4列按键里,有按键按下了,那么那一列按键对应的io的电平就会被拉低,我们就可以知道按键的列坐标,获得了行坐标x,列坐标y后,4*(x-1)+y就是按键的编号.
接下来贴份应用的代码,目的就是赋予16个按键键值,分别对应的键值是从0~F。按下一个键,第一个数码管就显示对应的键值

#include<reg52.h>
sbit lsa=P2^2;
sbit lsb=P2^3;
sbit lsc=P2^4;
#define duanxuan P0
#define keyboard P1
int zxm[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
int x,y;
void delay(int i)
{
	while(i--);
}
void keyproc()
{
    int a=0;
	P1=0x0f;//检测是哪一列有按键按下;
	if(P1!=0x0f)
	{
		delay(1000);
		if(P1!=0x0f)
		{
			P1=0x0f;
			switch(P1)
			{
				case(0x07):y=1;break;
				case(0x0b):y=2;break;
				case(0x0d):y=3;break;
				case(0x0e):y=4;break;
			}
		}
		P1=0xf0;//检测是哪一行有按键按下
		switch(P1)
		{
			case(0x70):x=1;break;
			case(0xb0):x=2;break;
			case(0xd0):x=3;break;
			case(0xe0):x=4;break;
		}
		while(a<50&&P1!=0xf0)//当按键按下的时间超过了500ms或者按键松开了就退出while循环
		{
			delay(1000);
			a++;
		}
		

	}
}
int main()
{
	lsa=0;
	lsb=0;
	lsc=0;//位选选中第一个数码管
	P0=0x00;//第一个数码管先什么都不显示
	while(1)
	{
		keyproc();
		P0=zxm[(x-1)*4+y-1];//送入段选信息
		
		
	}
	return 0;
	
}

数码管和138译码器原理图:
通过138译码器控制位选,例如p22输出电平为1,p23输出电平为0,p24输出电平为0,由p24,p23,p22构成了一个三位二进制数001,转换成10进制就是1,那么138译码器的输出端里y1就输出低电平到第二个数码管的com端,相当于位选选中了第二个数码管。
每一个数码管的8段led都是共阴极的,只要给对应数码管的com端输入低电平,数码管就能亮,至于哪些段亮哪些不亮就通过p0口控制,

版权声明:本文为eason9906原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/eason9906/archive/2004/01/13/11755123.html