按键是比较常用的也是比较简单的人机交互操作,按键实际上是一个非自锁的轻触开关,按下时触点会闭合,松开是触点断开。
1 独立式按键
常用的按键电路有两种形式,独立式按键和矩阵式按键,独立式按键比较简单,它们各自与独立的输入线相连接,如图所示。
4 条输入线接到单片机的 IO 口上,当按键 K3
按下时,K3两边的线路将会导通,P32
这个单片机IO口直接接到GND
,此时P32
这个引脚就是低电平了。当松开按键后,当松开按键后,线路断开,就不会有电流通过,那么P32
引脚就会是默认的电平状态,是一个高电平,因为被上拉电阻R8
拉到了VCC
状态。所以我们就可以通过 P32
这个 IO 口的高低电平来判断是否有按键按下。
2 按键抖动
通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动。
抖动时间的长短由按键的机械特性决定,一般为5ms~10ms。 我们只要记得10ms这个参数即可。
2.1 硬件消抖
① RS触发器:利用RS触发器来吸收按键的抖动。一旦有键按下,触发器立即翻转,触电的抖动便不会再对输出产生影响,按键释放时也一样。
② 电容滤波:将电容并联在按键的两端,利用电容的放电的延时特性,即电容两端电压不能突变。将产生抖动的电平通过电容“吸收”掉。从而达到消抖的作用。
2.2 软件消抖
在项目中为了省成本,基本上不使用硬件消抖,一般是使用软件方法去消除抖动,即检测出键闭合后执行一个延时程序,5ms~10ms的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。当检测到按键释放后,也要给5ms~10ms的延时,待后沿抖动消失后才能转入该键的处理程序。
3 原理图
① 独立按键:
② 上拉电阻:
③ MCU原理图:
4 代码
下面我们写一个使用独立按键控制LED亮灭的Demo:
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit key=P3^2; //定义P32口是key
sbit led=P2^0; //定义P20口是led
/*******************************************************************************
* 函 数 名 : delay
* 函数功能 : 延时函数,i=1时,大约延时10us
*******************************************************************************/
void delay(u16 i)
{
while(i--);
}
/*******************************************************************************
* 函 数 名 : KeyProcess
* 函数功能 : 按键处理函数,判断按键K1是否按下
*******************************************************************************/
void KeyProcess()
{
if(key==0) //检测按键是否按下
{
delay(1000); //消除抖动 一般大约10ms
if(key==0) //再次判断按键是否按下
{
led=~led; //led状态取反
}
while(!key); //检测按键是否松开
}
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main()
{
while(1)
{
KeyProcess(); //按键处理函数
}
}
简要分析:
① main
函数单纯给KeyProcess
子函数进行无限循环。
② KeyProcess
子函数首先通过语句if(key==0)
检测按键是否按下,就是判断key
端口是否为低电平,如果当前为低电平,就说明可能有按键被按下。
==》 然后延时大约10ms,消除抖动。
==》紧接着第二次检测按键是否按下,这是已经过了按下抖动的时候,如果key
端口当前仍为低电平,则确定按键被按下了,执行led
端口电平反转led=~led;
,如果当前是LED灯点亮则变成熄灭,反之则点亮。
==》最后检测按键是否松开while(!key);
,只有当前key==1
才说明按键松开了。
③ 事实上这只是一个理解独立按键工作原理的Demo,我们后面会认识到按键在工程中的真正用法,敬请期待!