C51学习笔记 2.按键

C51 2.按键

前言

轻触按键是通过内部的金属弹片受力弹动来实现接通和断开

也正应如此这种按键都存在抖动

祝愉快

1.原理图

在这里插入图片描述

P3口为正极,当按下K1时,P31口的电流通过K1到GND,这样P31的电平就为0了。所有当按下K1时,P31输出0。

在这里插入图片描述

  • P14到P17为行选择,P10到P13为列选择。当我们按下S1,P17和P13被连通了。

  • 那么为了检测那个按键按下,我们就给P10到P13循环赋值0,当给一个引脚赋值0后检测P14到P17,看看哪一个引脚也同样变为了0,这两个引脚就对应出了我们按下的那个按键。

  • 我们可以看到这里用了两层循环,外层为列扫描,内层为行扫描。列扫描时我们将列引脚设置为0然后判断行引脚,看看他是否为0,如果是,则就是这对行列所对应的按键被按下了。

2.按键抖动

在这里插入图片描述

因为按键在按下和松开时会发生抖动,那么我们在取值时就跳过按下和松开时,只在中间的时间段取值。

那么我们就要使用到Delay。

3.Delay

Delay是通过代码中每一行命令花费的时间的叠加来控制延时一段时间。

4.C代码

独立按键

#include <REGX52.H>

void main()
{
	while(1)
	{
		if(P3_1==0 || P3_0==0)	//如果K1按键或K2按键按下
		{
			P2_0=0;		//LED1输出0,点亮
		}
		else
		{
			P2_0=1;		//LED1输出1,熄灭
		}
	}
}

  • 上面的代码没有考虑按键抖动,不提倡。

  • 可以看到我们把独立按键的代码放在死循环中,因为我们按下按键这一事件是不确定什么时候发生的,那么我们就要一直等下去,一旦按下了按键 if 就会触发。

Delay

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}
  • 可以看到Delay里没有实质性意义的代码
  • 我们通过_NOP_ 、while循环还有调用函数本身来凑到一个我们想要的延时

独立按键+Delay

#include <REGX52.H>

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}

void main()
{
	while(1)
	{
		if(P3_1==0)			//如果K1按键按下
		{
			Delay(20);		//延时消抖
			while(P3_1==0);	//松手检测
			Delay(20);		//延时消抖
			
			P2_0=~P2_0;		//LED1取反
		}
	}
}

  • 将Delay放在按下后和松手后

矩阵键盘

#include <REGX52.H>
#include "Delay.h"

/**
  * @brief  矩阵键盘读取按键键码
  * @param  无
  * @retval KeyNumber 按下按键的键码值
			如果按键按下不放,程序会停留在此函数,松手的一瞬间,返回按键键码,没有按键按下时,返回0
  */
unsigned char MatrixKey()
{
	unsigned char KeyNumber=0;
	
	P1=0xFF;		//复位 全部置1
	P1_3=0;			//一列置0
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}		//判断那一行为0
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
	
	P1=0xFF;		//复位
	P1_2=0;			//下一列置0
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
	
	P1=0xFF;
	P1_1=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
	
	P1=0xFF;
	P1_0=0;
	if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
	if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
	if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
	if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
	
	return KeyNumber;
}

  • 我们把MatrixKey这样要一直检测的函数放在main的while(1)里面。

  • 当然我们还可以把MatrixKey放在计时器中断里面,并且这样做的话我们还可以忽略按键抖动的问题,并且让按键和其他事件可以同时发生。不过这是后话。

总结

  • 独立按键的引脚端在接通时被置0,这种发生在硬件上的事件对寄存器的影响是和学习C语言时操作变量遇到的情况是很不同的。

  • 寄存器内部数据的变化是不会像变量变化一样写在代码里面的,我们往往要检测寄存器里的数值。

  • Delay等待按键内弹片稳定。

  • Delay在我们之后的学习中也有很大作用,我们往往要等待电流携带数据到达寄存器后再进行操作。(C51反应太慢了,其实后面用的不算多)

  • 矩阵键盘利用行列扫秒完成对按键位置的确定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值