51單片機學習筆記———2.按鍵檢測及其延時消抖附加代碼優化

我們在學習51單片機用按鍵控制LED的時候,通常會遇到按鍵抖動的問題,這是因爲按鍵裏面內置彈簧片,不能夠精確的控制,下面是其原理圖(Powered by AxGlyph):
在這裏插入圖片描述
可以看到我們在按下按鍵的時候電平並沒有立馬變成低電平,而是有一個彈簧的抖動,所以我們要設計一個程序來抵消這個抖動,思路如下:

當按下按鍵的時候,我們先檢測一次是否真的爲低電平然後延時一小段時間,大概是5ms。

你們可能覺得5ms很少,但對於單片機來說,5ms是非常長的,我的單片機的晶振是11.0592MHZ,所以機器時鐘週期是晶振的倒數,1/11.0592MHZ,大概是1us,這是每條C語句執行的大概時間,當然更精確的可以通過外接示波器通過50%的佔空比來測量,所以我們延時5ms大概能夠自信5*1000條C語句,這對於單片機來說是非常長的,這一點一定不要忽略。

然後再次檢測是否真的爲低電平,若是,那就執行相應的操作。
所以整理完思路,我們的執行流程如下:
在這裏插入圖片描述
一般消除抖動有兩種方法:

  • 硬件
  • 程序

但是用硬件還要增加電容等一系列配套設備,增加了成本,所以我們採用程序控制
這是一個簡單的點亮小燈的程序,並循環閃爍:

#include<reg52.h>
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<reg52.h>
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<reg52.h>
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++)//延時任意輸入秒數
        {
            ;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章