51单片机学习笔记———2.按键检测及其延时消抖附加代码优化

我们在学习51单片机用按键控制LED的时候,通常会遇到按键抖动的问题,这是因为按键里面内置弹簧片,不能够精确的控制,下面是其原理图(Powered by AxGlyph):

可以看到我们在按下按键的时候电平并没有立马变成低电平,而是有一个弹簧的抖动,所以我们要设计一个程序来抵消这个抖动,思路如下:

当按下按键的时候,我们先检测一次是否真的为低电平然后延时一小段时间,大概是5ms。

你们可能觉得5ms很少,但对于单片机来说,5ms是非常长的,我的单片机的晶振是11.0592MHZ,所以机器时钟周期是晶振的倒数,1/11.0592MHZ,大概是1us,这是每条C语句执行的大概时间,当然更精确的可以通过外接示波器通过50%的占空比来测量,所以我们延时5ms大概能够自信5*1000条C语句,这对于单片机来说是非常长的,这一点一定不要忽略。

然后再次检测是否真的为低电平,若是,那就执行相应的操作。
所以整理完思路,我们的执行流程如下:

一般消除抖动有两种方法:

  • 硬件
  • 程序

但是用硬件还要增加电容等一系列配套设备,增加了成本,所以我们采用程序控制
这是一个简单的点亮小灯的程序,并循环闪烁:

#include
sbit LED = P0^4;//按位操作,定义使用的引脚
void delay();//函数声明
void main()
{
    while(1)
    {
        LED = 0;//点亮小灯
        delay();//延时1s
        LED = 1;//熄灭小灯
        delay();//延时1s
    }
}
void delay()
{
    unsigned char i;
    unsigned int j;
    for(i = 0;i<183;i++)
    {
        for(j = 0;j<1000;j++)//延时1s
        {
            ;
        }
    }
}

但是我们的延时描述是固定的,假如我们想修改小灯的闪烁时间还要重复对delay()函数进行修改,那样太麻烦,所以我们可以向delay()函数传递参数,来自定义我们想要的时间,修改后的代码如下:

#include
sbit LED = P0^4;//按位操作,定义使用的引脚
void delay(unsigned int n);//函数声明
void main()
{
    while(1)
    {
        LED = 0;//点亮小灯
        delay(1000);//延时1s
        LED = 1;//熄灭小灯
        delay(2000);//延时2s
    }
}
void delay(unsigned int n)
{
    unsigned char i;
    unsigned int j;
    for(i = 0;i<183;i++)
    {
        for(j = 0;j<n;j++)//延时任意输入秒数
        {
            ;
        }
    }
}

检测按键是否按下:

if(KEY==0)//判断按键KEY的值是否为0
{
     delay(5);//延时5ms
     if(KEY==0)//再次判断按键KEY的值是否为0
     {
       LED = ~LED;//LED状态取反,点亮小灯
     }
}

判断按键是否松开:

while(!KEY);//判断按键是否松开

按键重复检测(循环):

 while(1)
{
    if(KEY==0)//判断按键KEY的值是否为0
   	{
        delay(5);//延时5ms
        if(KEY==0)//再次判断按键KEY的值是否为0
        {
           LED = ~LED;//LED状态取反,点亮小灯
        }
      	 while(!KEY);//判断按键是否松开
     }
}

按键控制LED灯代码(简单版本):

/*
 * @Author: 王云龙
 * @Date:   2020-02-23 12:48:51
 * @Last Modified by:   王云龙
 * @Last Modified time: 2020-02-23 12:48:51
 */
#include
sbit KEY = p3^4;
sbit LED = P0^7;//按位操作,定义使用的引脚
void delay(unsigned int n)//函数声明
void main()
{
    while(1)
    {
        if(KEY==0)//判断按键KEY的值是否为0
        {
            delay(5);//延时5ms
            if(KEY==0)//再次判断按键KEY的值是否为0
            {
                 LED = ~LED;//LED状态取反,点亮小灯
            }
            while(!KEY);//判断按键是否松开
        }
    }
}
void delay(unsigned int n)
{
    unsigned char i;
    unsigned int j;
    for(i = 0;i<183;i++)
    {
        for(j = 0;j<n;j++)//延时任意输入秒数
        {
            ;
        }
    }
}

你可能感兴趣的:(C语言)