用户工具

站点工具


侧边栏

抱歉,您没有权限增加页面
4.单片机入门教程:5.独立按键检测

单片机入门教程之独立按键检测

一:实验现象
通过一个按键控制LED灯,按下按键灯亮,松开灯灭。

二:实验原理
按键是和单片机人机交互的方式之一,单片机按键通常有两种接法,一种是独立按键,每个按键占用一个IO口,一种是矩阵按键,采用行列式矩阵接法,4行4列16个按键只需占用8个IO口。我们只学习独立按键检测方法,矩阵按键以后自己百度一下学习。
51Discovery板上采用了一个五向按键,就是集成了上下左右和中键,其实里面就是五个按键封装在一起的。按键爆个照先:(左:普通按键,右:五向按键)

单片机怎样检测按键呢?So,按键在不按下的时候内部两个接触片是不导通的,我们把按键接触片的一端管脚接地,一端接IO口,当按键按下的时候接触片结合导通IO口相当于接地了,这时候,我们读取单片机IO口电平状态就可以知道按键是否按下了,读到为0(低电平)说明按键按下,否则为没有按下。
下面看看,五向按键与单片机连接的原理图:

注:F1→P3.3上键 F3→P3.6下键 F2→P3.5左键 F4→P3.4右键 F5→P3.2中键

三:代码演示
代码里怎样知道按键是否按下呢?可以这样,用个If语句直接判断IO口就可以了,如果读取到的电平等于0说明按键按下了,否则没按下。来看一下最简单的按键处理代码:

以上代码控制LED灯亮灭人眼是觉察不到有什么毛病,但其实已有一个问题,就是按键按下的时候LED可能已经亮灭了多次,通常的按键所用开关为机械弹性开关,当机械触点断开、闭合时,由于机械触点的弹性作用,按键在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动。如图:

抖动会引起一次按键被误读多次。为确保单片机对按键的一次闭合仅作一次处理,必须去除按键抖动。在按键闭合稳定时读取键的状态,并且必须判别到键释放稳定后再作处理。这样做就称作按键消抖。按键消抖可以采用硬件和软件两种方法,硬件消抖这里不讲,我们采用软件滤除的方式。
一般机械按键的前沿抖动和后沿抖动的时间为5-10毫秒后稳定,我们在读取按键的时候,一旦读到为0,就用软件延时个15毫秒,然后再继续判断按键是否还是按下的,如果还是按下的,就说明按键避开抖动读取成功。代码如下:

#include<stc12.h> //STC12系列头文件 复制到工程目录下
sbit LEDK = P1^4;// 控制三极管基极
sbit Button_Right = P3^4; //右键  按键定义
sbit Button_Left = P3^5; //左键
sbit Button_Up = P3^3; //上键
sbit Button_Down = P3^6;//下键
sbit Button_Ok = P3^2;//确定键
#define uint unsigned int //宏定义uint来替代unsigned int 在程序中只需使用uint即可
#define uchar unsigned char //宏定义uchar来替代unsigned char 在程序中只需使用uchar即可

void Delay(uint time); //延时函数声明

void main(void)
{   
    LEDK=0;  //置0使PNP型三极管导通LED负极接地
    P0=0x00;	//P0口电平初始化为0 关闭全部LED
    P0M1=0x00;
    P0M0=0xff; //P0口全部设置为推挽输出 见手册87页 IO口模式配置
	while(1)
	{
//--------------------------------------------------------------------------
	   //确定键按下 

	   if(Button_Ok==0) // 按键按下IO口接地 IO口读到低电平为0
	   {
	     Delay(60);//15ms延时去抖动
		 if(Button_Ok==0) //再次确认按键是否按下
		 {
		   P0=0x01;
		 }
	   }
	   else{P0=0x00;} //松手后熄灭LED
	}
}

void Delay(uint time) //有参延时函数  time的值决定了延时时间
{
  uint x,y;
  for(x=time;x>0;x--)  //参数传递给X
   for(y=210;y>0;y--); //for嵌套
}

本代码完整工程在stc51 discovery开发板【实验例程】【基础实验】【实验十四】

你会发现,上面的代码,没有松手检测,就是说你一旦按下按键就会立即执行点灯,怎样让按键松开以后再执行呢?很简单,只需加一句话,用while语句一直等待判断按键是否松开,把要执行的内容放到while下面就可以了。如下:

    if(Button_Ok==0) // 按键按下IO口接地 IO口读到低电平为0
    {
        Delay(60);//15ms延时去抖动
	if(Button_Ok==0) //再次确认按键是否按下
	{
	    while(!Button_Ok); //松手判断,按键松开Button_Ok=1 while不成立
            P0=0x01;	       //才会执行下面的代码,点亮LED
	    Delay(2000);	
	}
    }
    else{P0=0x00;} //松手1秒后熄灭LED
    
    本代码完整工程在stc51 discovery开发板【实验例程】【基础实验】【实验十五】

此种按键延时消抖检测方法实时性较低,可以自己去网上找一些高效的按键处理方法,如:状态机按键等。

4.单片机入门教程/5.独立按键检测.txt · 最后更改: 2017/03/04 20:22 由 wawooo