80c51day04独立键盘与矩阵键盘

独立键盘

在这里插入图片描述

电路

在这里插入图片描述
在这里插入图片描述
简单地说,就是引脚置高然后如果按键被按下就会检测到低电位,但是呢,因为机械按键的缘故,还要进行消抖操作
在这里插入图片描述
就理解为弹片按下会抖动使电压产生波动

代码

#include <reg52.h>
#include <intrins.h>

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
sbit key_s2 = P3^0;//独立按键S2
sbit key_s3 = P3^1;//独立按键S3
uchar num;//数码管显示的值

//共阴数码管段选表0-9
uchar  code tabel[]= {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};


//毫秒级延时函数定义
void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--); 		
} 

void main()//main函数自身会循环
{
	WE = 1;//打开位选锁存器
	P0 = 0XFE; //1111 1110
	WE = 0;//锁存位选数据
	
	while(1)
	{
		if(key_s2 == 0)//判断S2是否被按下
		{
			delay(20);//按键消抖,通过延时跳过可能存在的抖动时间
			if(key_s2 == 0)
			{
				if(num != 9)//如果值不等于9则+1,功能把值限定为小于9
				num++;
				while(!key_s2);//松手检测,不松一直卡在这里
			}	
		}
		if(key_s3 == 0)//判断S3是否被按下
		{
			delay(20);//按键消抖
			if(key_s3 == 0)
			{
				if(num > 0)	//如果大于0则执行减一
					num--;
				while(!key_s3);//松手检测
			}	
		}
		//松手之后刷新显示
		DU = 1;//打开段选锁存器
		P0 = tabel[num];//
		DU = 0;//锁存段选数据
	}	
}  

矩阵键盘

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们将1234作为一组,5678作为一组,然后我们先把第一组的io口置1,第二组的io口置0,假设有一个按钮被按下,那么它所在行会被拉低,同理我们再把第一组置0,第二组置1,这样就可以得到被按下按钮的坐标,这个过程叫做两次扫描
检测过程和独立键盘一样要消抖什么的

代码

#include <reg52.h>//包含51头文件
#include <intrins.h>//包含移位标准库函数头文件

#define uint unsigned int
#define uchar unsigned char

sbit DU = P2^6;//数码管段选
sbit WE = P2^7;//数码管段选
uchar num;//数码管显示的值
uchar KeyValue = 20;//按键值 显示-

//共阴数码管段选表
uchar  code tabel[]= {
//0		1	 2     3     4     5     6     7     8
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9     A     B	   C	 D	   E	 F		H	 L	 
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x76, 0x38,
//n	   u	  -	  熄灭
0x37, 0x3E, 0x40, 0x00 };

/*====================================
函数	: delay(uint z)
参数	:z 延时毫秒设定,取值范围0-65535
返回值	:无
描述	:12T/Fosc11.0592M毫秒级延时
====================================*/
void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--); 		
} 
/*====================================
函数	:KeyScan()
参数	:无
返回值	:无
描述	:4*4矩阵键盘与独立键盘扫描
按键按下KeyValue全局变量值发生相应变化
====================================*/
void KeyScan()
{
	//4*4矩阵键盘扫描
	P3 = 0XF0;//列扫描
	if(P3 != 0XF0)//判断按键是否被按下
	{
		delay(10);//软件消抖10ms
		if(P3 != 0XF0)//判断按键是否被按下
		{
			switch(P3) //判断那一列被按下
			{
				case 0xe0:	KeyValue = 0;	break;//第一列被按下
				case 0xd0:	KeyValue = 1;	break;//第二列被按下
				case 0xb0:	KeyValue = 2;	break;//第三列被按下
				case 0x70:	KeyValue = 3;	break;//第四列被按下 
			}
			P3 = 0X0F;//行扫描
			switch(P3) //判断那一行被按下
			{
				case 0x0e:	KeyValue = KeyValue;	break;//第一行被按下
				case 0x0d:	KeyValue = KeyValue + 4;	break;//第二行被按下
				case 0x0b:	KeyValue = KeyValue + 8;	break;//第三行被按下
				case 0x07:	KeyValue = KeyValue + 12;	break;//第四行被按下 
			}
			while(P3 != 0X0F);//松手检测	
		}
	}
	P3 = 0XFF;//独立按键扫描
	if(P3 != 0XFF)
	{
		delay(10);//软件消抖10ms
		if(P3 != 0XFF)
		{
			switch(P3) //判断那一行被按下
			{
				case 0xfe:	KeyValue = 16;	break;//S2被按下
				case 0xfd:	KeyValue = 17;	break;//S3被按下
				case 0xfb:	KeyValue = 18;	break;//S4被按下
				case 0xf7:	KeyValue = 19;	break;//S5被按下 
			}
			while(P3 != 0XFF);//松手检测			
		}	
	}

}

void main()//main函数自身会循环
{
	WE = 1;//打开位选锁存器
	P0 = 0XFE; //1111 1110
	WE = 0;//锁存位选数据

	DU = 1;//打开段选锁存器
	while(1)
	{
		KeyScan();//20个按键键盘扫描
		P0 = tabel[KeyValue];//显示按键值
	}	
}  

列扫描,消抖判断是否被按下,确认按下则得到列偏移,马上进行行扫描得到段的值(有段地址加偏移地址的味道),相加得到按键编号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值