51单片机学习笔记(五) -独立按键&&外部中断


一、按键的工作原理

1、原理图

在这里插入图片描述

2、按键的工作原理

1、按键按下去的时候,I/O引脚接地,CPU检测到低电平,否则检测到高电平;
2、CPU通过监测按键连接的I/O引脚的电平输入是1还是0就知道外部有没有人按下这个按键。相当于人通过按按键给CPU输入了一个信号,这个信号可以被CPU监测到从而指导CPU去做一定的工作。

按键有没有按下的本质是I/O是否接地的问题。
按键引出端子JP1与单片机P1端口相接;

二、使用轮询法处理按键

1、通过按键来点亮LED

按下按键LED灯亮,松开按键LED灯灭,代码如下:

#include <reg51.h>

sbit Key1 = P1^0;
sbit LED1 = P0^0;


void main(void)
{
	while(1)
	{
		if(1 == Key1)
		{
			LED1 = 1;
		}
		else
		{
			LED1 = 0;
		}
	}
}

如果要监测的按键数量少,可以用位监测。如果多则可以直接用端口字节变量来监测。


2、键值检测与显示

一般的产品中按键都有很多,对于整个程序来说一般都是把按键进行编码,给每个按键一个对应的编码值,就叫做按键的键值;

#include <reg51.h>

sbit Key = P1^0;
void Display(unsigned char num);

unsigned char value[16] = {0xC0, 0xf9, 0xA4, 0xb0,
						   0x99, 0x92, 0x82, 0xf8,
						   0x80, 0x90, 0x88, 0x83,
                           0xc6, 0xA1, 0x86, 0x8e
						   };

void main(void)
{
	unsigned char KeyNum = 0;
	unsigned char i;
	while(1)
	{
		for(i = 0; i < 8; i++)
		{
			if((P1 & (0x01 << i)) == 0)
				KeyNum = i + 1;
		}
		
		Display(KeyNum);
	}
}

void Display(unsigned char num)
{
	if(num < 16)
		P0 = value[num];
}

3、按键消抖

1、什么是抖动:按键在按下时,活动触点击打固定触点会有机械振动,因而造成输出波形抖动,在抖动时间范围内引脚的电平变化是不稳定的。
2、抖动的危害:如果程序在这抖动的这一段范围内去判断引脚的电平从而来判断有无按键,则有很大可能性会误判。
3、如何消抖?
(1)硬件消抖,在硬件设计上想办法降低抖动,这是一种主动消抖(加一个小电容)。
(2)软件消抖,既然在硬件上不可能完全消除抖动,软件设计上就要想办法绕开抖动造成的影响,这是一种被动(逃避式)的消抖,也就是在抖动期间不去检测按键。

消抖代码如下:

if(Key == 0)
{
	Delay_mS(10);
	if(Key == 0)
	{
		AddDisplay();
	}			
}	

4、完整的按键检测

一次完整的按键事件:
1、按键事件就是按键操作过程中的不同状态切换;
2、一个完整的按键事件包括:按下事件(由高变低)、弹起事件(由低到高);
3、一般都认为发生了一次完整的按键事件才算是用户操作了一次按键,程序才会去处理按键,所以在一次完整的按键事件中程序只会去处理一次按键。

弹起时处理任务,代码如下:

if(Key == 0)          //检测按键,按下
{
	Delay_mS(10);       //消抖
	if(Key == 0)        //再次检测按键
	{
		flag = 1;         //标志位置一
	}			
}
else
{
	Delay_mS(10);        
	if(Key == 1 && flag == 1)   //检测弹起
	{
		AddDisplay();             //弹起后处理任务
		flag = 0;
	}			
}	

按下时处理任务,代码如下:

if(Key == 0)                       //检测按键,按下
{
	Delay_mS(10);                    //消抖
	if(Key == 0 && flag == 0)        //再次检测按键
	{
		flag = 1;                      //标志位置一
		AddDisplay(); 
	}			
}
else
{
	Delay_mS(10);        
	if(Key == 1)                   //检测弹起
	{
		flag = 0;                 //标志位清零
	}			
}

四、使用中断检测按键

1、功能要求

任务:独立数码管循环显示0-F,同时按键控制LED亮灭;

实现代码如下:

#include <reg51.h>

sbit LED1 = P2^0;
sbit Key1 = P1^0;

void Delay_mS(unsigned int Time);
unsigned char value[16] = {0xC0, 0xf9, 0xA4, 0xb0,
						   0x99, 0x92, 0x82, 0xf8,
						   0x80, 0x90, 0x88, 0x83,
						   0xc6, 0xA1, 0x86, 0x8e
						   };
void main()
{
	unsigned char i = 0;
	while(1)
	{
		for(i = 0; i < 16; i++)
		{
			P0 = value[i];
			Delay_mS(1000);
		}
		if(Key1 == 0)
			LED1 = 0;
		else
			LED1 = 1;
	}
}

void Delay_mS(unsigned int Time)
{
	unsigned char a, b;
	if(Time > 0)
	{
		while(Time--)
		{
			for(a = 2; a > 0; a--)
				for(b = 248; b > 0; b--);
		}
	}	
}

(1)实践证明可以实现功能,但是按键监测控制LED这边非常不灵敏,当所有数字显示完毕后才会响应按键;
(2)逐步认识到单片机只有一个“主线任务”的特点,也就是串行工作的;
(3)多任务时如何及时响应?-----引入中断

2、外部中断INT0和INT1

1、外部中断:中断源来自于单片机外部就叫外部中断,51单片机支持4个外部中断。分别对应4个引脚。每一个外部中断都对应一个特定的单片机IO引脚(譬如INT0对应P3.2,这个是单片机在设计时候定好的,是无法改变的)。我们软件只需要对P3.2做一些相关配置,P3.2就可以响应外部的中断事件。当硬件产生了一个外部中断时CPU就会收到一个中断信号,从而转去执行外部中断对应的处理程序(中断处理程序)。

2、中断寄存器:

3、INT0主要寄存器
IT0:中断触发模式配置(1:下降沿触发,0:低电平触发);
EX0:外部中断使能位(1:使能外部中断,0:禁止外部中断);
EA:全局中断使能位(1:使能全局中断,0:禁止全局中断)。

3、代码实现

外部中断初始化代码如下:

void INT0_Init(void)
{
	IT0 = 1;            //设置下降沿触发中断
	EX0 = 1;            //使能外部中断0
	EA = 1;             //使能全局中断
}

在中断中检测按键,中断函数如下:

void ExInt0() interrupt 0
{
	static unsigned char flag = 0;
	flag = !flag;
	if(Key1 == 0)
	{
		Delay_mS(5);
		if(Key1 == 0)
		{
			LED1 = flag;
		}
	}
}

延时函数:

void Delay_mS(unsigned int Time)
{
	unsigned char a, b;
	if(Time > 0)
	{
		while(Time--)
		{
			for(a = 2; a > 0; a--)
				for(b = 248; b > 0; b--);
		}
	}	
}

主函数:

#include <reg51.h>

sbit LED1 = P2^0;
sbit Key1 = P3^2;

void Delay_mS(unsigned int Time);
void INT0_Init(void);
unsigned char value[16] = {0xC0, 0xf9, 0xA4, 0xb0,
						   0x99, 0x92, 0x82, 0xf8,
						   0x80, 0x90, 0x88, 0x83,
						   0xc6, 0xA1, 0x86, 0x8e
						   };
void main()
{
	unsigned char i = 0;
	INT0_Init();
	while(1)
	{
		for(i = 0; i < 16; i++)
		{
			P0 = value[i];
			Delay_mS(1000);
		}
	}
}

程序最终功能就是,在静态数码管循环计数的同时,按键可以控制LED灯亮灭。

总结

1、本节介绍了按键的检测方式,以及消抖的原理和方法;
2、本节介绍了中断的使用和原理,并使用中断进行按键的检测;
3、中断函数时不需要声明的,但是得有关键字interrupt关键字。

  • 6
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值