天天看點

51單片機入門 - 按鍵驅動程式設計實驗

部落客福利:100G+電子設計學習資源包!

​​http://mp.weixin.qq.com/mp/homepage?__biz=MzU3OTczMzk5Mg==&hid=7&sn=ad5d5d0f15df84f4a92ebf72f88d4ee8&scene=18#wechat_redirect​​ --------------------------------------------------------------------------------------------------------------------------

獨立按鍵原理是這樣的:按鍵沒按下的時候,相應端口是高電平狀态,而當按鍵按下的時候,相應的端口則是低電平。是以可以根據這個現象,實作相應的功能。

還有一點應該注意的是:按鍵在閉合和斷開時,觸點會存在抖動現象。

51單片機入門 - 按鍵驅動程式設計實驗

在實際情況下,我們需要的是穩定閉合的那部分狀态。是以可以采用延時的方法來解決這個問題,具體的過程就是先看看有沒有鍵按下,有鍵按下了,再延遲一段時間,再看看有沒有鍵按下,

這時候如果還是有鍵按下的話那就真的是有鍵按下了。

而這個抖動的時間大概是10ms,是以隻要用一個延時10ms的子函數就行。

上面代碼的第66行那個判斷按鍵是否松開也是必要的,雖然在這個程式中有和沒有差別不大,但是在有的程式中加入要求按鍵松開之後才出現什麼現象之類的東西的話,那這部分就顯得必要了。

/*******************************************************************************
實驗名稱:       8個獨立按鍵控制8盞LED燈(按下哪個鍵,那個鍵對應的LED亮)
實驗時間:        
*******************************************************************************/
#include <reg51.h>

#define LED_KEY P0   //LED燈用P0口
#define IO_KEY  P1     //獨立按鍵用P1口

void Delay();        //延時函數
unsigned char Key_Scan();     //擷取按鍵值

void main()
{
    unsigned char Key_Value, LED_Value;
    
    while(1)
    {
        Key_Value = Key_Scan();
        switch(Key_Value)
        {
            case(0xFE):         //K1按下
                LED_Value = 0x01;
                break;
            case(0xFD):         //K2按下
                LED_Value = 0x02;
                break;
            case(0xFB):         //K3按下
                LED_Value = 0x04;
                break;
            case(0xF7):         //K4按下
                LED_Value = 0x08;
                break;
            case(0xEF):         //K5按下
                LED_Value = 0x10;
                break;
            case(0xDF):         //K6按下
                LED_Value = 0x20;
                break;
            case(0xBF):         //K7按下
                LED_Value = 0x40;
                break;
            case(0x7F):         //K8按下
                LED_Value = 0x80;
                break;
            default:
                break;
        }
        
        LED_KEY = LED_Value;  //點亮相應LED        
    }
}

unsigned char Key_Scan()
{
    unsigned char Key_Value,i;

    if(IO_KEY != 0)
    {
        Delay();            //消除抖動

        if(IO_KEY != 0xFF)
        {
            Key_Value = IO_KEY;
            i = 0;
            if((i<50)&&(IO_KEY != 0xFF)) //判斷按鍵是否松開
            {
                Delay();
                i++;    
            }
        }
    }
    return Key_Value;
}

void Delay()              //延遲10ms
{
    unsigned char a,b,c;

    for(c=1;c>0;c--)
    {
        for(b=38;b>0;b--)
        {
            for(a=130;a>0;a--)
            {};
        }
    }
}      
/*******************************************************************************
*實驗名稱       :按鍵控制LED左右移
*實驗時間              
*******************************************************************************/
#include <reg51.h>
#include <intrins.h>

//--定義要使用的IO口--//
sbit      K1 = P1^0;       //對應按鈕K1
sbit     K2 = P1^1;        //對應按鈕K2
#define  LED_KEY P0    //LED使用P0口

//--定義全局函數--//
void Delay10ms(unsigned int c);   //延時10ms
unsigned char Key_Scan();

/*******************************************************************************
* 函 數 名         : main
* 函數功能           : 主函數
*******************************************************************************/
void main(void)
{
    unsigned char ledValue, keyNum;

    ledValue = 0x01;

    while (1)
    {    
        keyNum = Key_Scan();  //掃描鍵盤

        if (keyNum == 1)      //如果鍵值傳回1
        {
            ledValue = _crol_(ledValue, 1);    //左循環
        }
        else if (keyNum == 2)
        {
            ledValue = _cror_(ledValue, 1);    //右循環
        }

        LED_KEY = ledValue;  //點亮LED燈
    }                
}

/*******************************************************************************
* 函 數 名                     : Key_Scan()
* 函數功能                       : 掃描鍵盤
*******************************************************************************/

unsigned char Key_Scan()
{
    unsigned char keyValue = 0 , i; //儲存鍵值

    //--檢測按鍵1--//
    if (K1==0)        //檢測按鍵K1是否按下
    {
        Delay10ms(1);    //消除抖動

        if (K1==0)    //再次檢測按鍵是否按下
        {
            keyValue = 1;
            i = 0;
            while ((i<50) && (K1==0))     //檢測按鍵是否松開
            {
                Delay10ms(1);
                i++;
            }
        }
    }

    //--檢測按鍵2--//
    if (K2==0)        //檢測按鍵K1是否按下
    {
        Delay10ms(1);    //消除抖動

        if (K2==0)    //再次檢測按鍵是否按下
        {
            keyValue = 2;
            i = 0;
            while ((i<50) && (K2==0))     //檢測按鍵是否松開
            {
                Delay10ms(1);
                i++;
            }
        }
    }

    return keyValue;   //将讀取到鍵值的值傳回
}

/*******************************************************************************
* 函 數 名                     : Delay10ms
* 函數功能                     : 延時函數,延時10ms
*******************************************************************************/

void Delay10ms(unsigned int c)   //誤差 0us
{
    unsigned char a, b;

    //--c已經在傳遞過來的時候已經指派了,是以在for語句第一句就不用指派了--//
    for (;c>0;c--)
    {
        for (b=38;b>0;b--)
        {
            for (a=130;a>0;a--);
        }
           
    }       
}