51单片机小白零基础教程——独立键盘检测原理以及实际应用

一、键盘的概念

键盘:是电子系统中,人机对话的重要组成部分,是人向机器发出指令、输入信息必须的设备

通常来说,键盘有编码键盘非编码键盘两种。

编码键盘:键盘上闭合键的识别由专门的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算机键盘,这种键盘使用方便,所需程序简单,但硬件电路复杂

非编码键盘:是利用软件编程来实别键盘的,在单片机组成的各种系统中,最常用的就是非编码键盘,特点是硬件电路简单

非编码键盘又分为独立键盘矩阵式键盘

二、独立键盘的检测

在这里插入图片描述
在单片机的外围电路中,常常用到的按键是机械弹性开关,当开关闭合时,线路导通,开关断开时,线路断开。

如图,当按下开关时,原本连在一起的1和2脚,3和4脚被断开,原本没有连在一起的1和3脚,2和4脚被吸和,导通;当松手后自动断开。

自锁式按键:按下时闭合且会自动锁住,只有再次按下时才弹起断开。像我所用的单片机板子上的电源开关就是自锁按键。

单片机检测按键的原理是:单片机I/0口既可以作为输入使用,也可以作为输出使用。当检测按键时,用的是它输入功能,我们把按键一端接地,另一端与单片机的某个I/O口相连,开始时先给该I/O口赋一高电平,然后让单片机不断检测该I/O口是否变为低电平,当按键闭合时,即相当于该I/O口通过按键与地相连,变成低电平,程序一旦检测到I/O口变为低电平则说明按键被按下,然后执行相关的指令。

按键按下时,触电的电压变化过程:
在这里插入图片描述
理想波形:没有按下为高电平,按下之后为低电平,松开之后又为高电平

实际波形:按下之后,存在机械抖动,需要过一段时间才会稳定成低电平,然后,松开时又会产生机械抖动

机械式按键在按下或者释放时,由于机械弹性的影响,通常会伴随有一定的时间触电机械抖动,然后其触电才稳定下来。
在触点抖动期间检测按键的通与断,可能会导致错误,即有可能被认为进行了多次操作,这种情况是不允许出现的。因此在单片机检测键盘是否按下都要加上去抖动操作,按键少时,可采用硬件消抖,按键较多时,采用软件消抖。

编写单片机的键盘检测程序时,一般在检测按下时加入去抖延时(10~20ms即可),检测松手时,就不用加了。

三、独立键盘原理图

在这里插入图片描述

在这里插入图片描述
单片机控制系统中,如果只需要几个功能键,此时,可以采用独立式按键结构。

独立按键式:

  1. 直接用I/O口线构成单个按键电路,其特点是每个按键单独占用一根I/O口,每个按键的工作不会影响其他I/O口的状态。
  2. 按键电路配置灵活,软件结构简单
  3. 由于每个按键必须占用一个I/O口线,因此,在按键较多时,I/O口线浪费较大,不宜采用

四、实际应用

设计要求:按下S2,LED1点亮;按下S3,LED2点亮;按下S4,LED3点亮;按下S5,LED4点亮
程序:

#include<reg51.h>  //52单片机头文件

sbit S2 = P3^0;	   //位定义 S2为标示符 P3^0为地址值 
sbit S3 = P3^1;
sbit S4 = P3^2;
sbit S5 = P3^3;

sbit Led1 = P1^0;
sbit Led2 = P1^1;
sbit Led3 = P1^2;
sbit Led4 = P1^3;

void main()
{
	while(1)		   //通过大循环不断扫描按键状态
	{
		if(S2==0)	   //这里的循环意思为:如果S2按键没有被按下,那么LED1不得电;如果S2按键被按下,那么LED1得电
			Led1 = 0;
		else
			Led1 = 1;

		if(S3==0)
			Led2 = 0;
		else
			Led2 = 1;

		if(S4==0)
			Led3 = 0;
		else
			Led3 = 1;

		if(S5==0)
			Led4 = 0;
		else
			Led4 = 1;
	}
}

效果:
在这里插入图片描述
设计要求:第一次按下S5,并松开S5,第一个数码管从0开始变为1;第二次按下S5,并松开S5,第一个数码管从1变为2;依次类推,直到变为9为止,一直循环。

#include <reg52.h>			 //52单片机头文件
#define uchar unsigned char //宏定义
#define uint unsigned int 
sbit S5 = P3^3;     //位定义 S5标识符 P3^4地址符
sbit WE = P2^7;
sbit DU = P2^6;

uchar num;
uchar code table[] = {	 //显示0~f的码表
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

void delay(uint z)		 //延时函数
{
	uint x,y;
	for(x = z;x>0;x--)
		for(y = 144;y>0;y--);
}

void main()              //主函数
{
	WE = 1;				 //打开位选锁存器
	P0 = 0xfe;			 //点亮第一个数码管
	WE = 0;				 //关闭位选锁存器 让数据锁存
	
	while(1)			 //大循环
	{	
	   if(S5 == 0)		  
	   {
	   	delay(20);         //按键消抖
	    if(S5 == 0)
			{
				num++;
				if(num == 10)
			    num = 0;
			    while(!S5);	  //松手检测
			}
	    }
	DU = 1;				  //打开段选锁存器
	P0 = table[num];	  //num从第一个数开始亮
	DU = 0;				  //关闭段选,锁存数据
	}
}

设计要求:按下S4按键,第一个数码管的数码管的数从0开始加1,;按下S3按键第一个数码管的数就开始减1

#include <reg52.h>			 //52单片机头文件
#define uchar unsigned char //宏定义
#define uint unsigned int 
sbit S5 = P3^3;     //位定义 S5标识符 P3^4地址符
sbit S4 = P3^2;     //位定义 S5标识符 P3^4地址符

sbit WE = P2^7;
sbit DU = P2^6;

uchar num;
uchar code table[] = {	 //显示0~f的码表
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71};

void delay(uint z)		 //延时函数
{
	uint x,y;
	for(x = z;x>0;x--)
		for(y = 144;y>0;y--);
}

void main()              //主函数
{
	WE = 1;				 //打开位选锁存器
	P0 = 0xfe;			 //点亮第一个数码管
	WE = 0;				 //关闭位选锁存器 让数据锁存
	
	while(1)			 //大循环
	{	
	   if(S5 == 0)		  
	   {
	   	delay(20);         //按键消抖
	    if(S5 == 0)
			{
				num++;
				if(num == 10)
			    num = 0;
			    while(!S5);	  //松手检测
			}
	    }

		if(S4 == 0)		  
	   {
	   	delay(20);         //按键消抖
	    if(S4 == 0)
			{
				if(num > 0)
			    num--;
			    while(!S4);	  //松手检测
			}
	    }
	DU = 1;				  //打开段选锁存器
	P0 = table[num];	  //num从第一个数开始亮
	DU = 0;				  //关闭段选,锁存数据
	}
}

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值