久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術學習與研究
當前位置:單片機教程網(wǎng) >> MCU設計實例 >> 瀏覽文章

用狀態(tài)機做獨立按鍵檢測

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2010年05月26日   【字體:
人機界面最重要的就是按鍵了,覺得按鍵做的最好的就是手機的按鍵了,有長按、敵探、連發(fā)等功能。還有組合等。一個好的按鍵程序用書本上學的按鍵檢測方法已經(jīng)不能適應工程的需要了,為此人們設計出一種狀態(tài)機檢測按鍵的方法。 在一個系統(tǒng)中按鍵是隨機的,因此系統(tǒng)軟件對按鍵要一直循環(huán)查詢,由于按鍵檢測過程需要進行消抖處理,因此取狀態(tài)機的時間序列為10ms,這樣不僅可以跳過按鍵抖動的影響,同時也小于0.3-0.5秒的穩(wěn)定閉合期,不會將按鍵的操作過程丟失。 程序?qū)崿F(xiàn)方法,用定時器定時10ms,每隔10ms檢測一次按鍵,將一個按鍵的檢測過程分為幾個不同的狀態(tài),最簡單的分為 初使狀態(tài)-按鍵閉合確認狀態(tài)-按鍵釋放狀態(tài),如果要求按鍵實現(xiàn)的功能越多,狀態(tài)也就越多 ,比如還有常用的長按狀態(tài)。以下是一個狀態(tài)機按鍵程序,僅供參考。 程序基于AVR單片機, key.h文件的一部分
#define KEY0_PORT           PORTD
#define KEY0_DDR            DDRD
#define KEY0_PIN               PIND
#define KEY0                        PD0

#define KEY1_PORT           PORTD
#define KEY1_DDR             DDRD
#define KEY1_PIN                PIND
#define KEY1                        PD1

#define KEY2_PORT           PORTD
#define KEY2_DDR              DDRD
#define KEY2_PIN                    PIND
#define KEY2                   PD2

#define KEY3_PORT           PORTD
#define KEY3_DDR          DDRD
#define KEY3_PIN                    PIND
#define KEY3                   PD3

#define KEY0_STATUS    (BIT_STATUS(KEY0_PIN,KEY0))
#define KEY1_STATUS     (BIT_STATUS(KEY1_PIN,KEY1))
#define KEY2_STATUS    (BIT_STATUS(KEY2_PIN,KEY2))
#define KEY3_STATUS   (BIT_STATUS(KEY3_PIN,KEY3))


#define KEY_SERIES_FLAG     200      //按鍵連發(fā)開始所需時間長度
#define KEY_SERIES_DELAY    5       //按鍵連發(fā)的時間間隔長度

//按鍵屬性
#define KEY_DOWN        0xA0
#define KEY_LONG        0xB0
#define KEY_LIAN        0xC0
#define KEY_UP          0xD0

#define KEY_LONG        0xB0
#define KEY_LIAN        0xC0
#define KEY_UP          0xD0

#define NO_KEY          0x00

#define KEY0_DOWN       0X01
#define KEY1_DOWN       0X02
#define KEY2_DOWN       0X03
#define KEY3_DOWN       0X04

#define KEY0_PRESS      (KEY_DOWN|KEY0_DOWN)
#define KEY1_PRESS      (KEY_DOWN|KEY1_DOWN)
#define KEY2_PRESS      (KEY_DOWN|KEY2_DOWN)
#define KEY3_PRESS      (KEY_DOWN|KEY3_DOWN)

key.c文件一部分

static uchar Get_Key(void)
{
    if (KEY0_STATUS==0) return KEY0_DOWN;
    if (KEY1_STATUS==0) return KEY1_DOWN;
    if (KEY2_STATUS==0) return KEY2_DOWN;
    if (KEY3_STATUS==0) return KEY3_DOWN;
    return NO_KEY;
}
uchar Key_Scan(void)
{
    static uchar Key_State   = 0;        //按鍵狀態(tài)
    static uchar Key_Prev    = 0;        //上一次按鍵
    static uchar Key_Delay   = 0;        //按鍵連發(fā)時間
    static uchar Key_Series  = FALSE;    //標志連發(fā)開始

    uchar Key_Press  = NO_KEY;           //按鍵值
    uchar Key_Return = NO_KEY;           //按鍵返回值

    Key_Press = Get_Key();

    switch (Key_State)
    {

    case 0://按鍵初始態(tài)00
        if (Key_Press !=NO_KEY)//有按鍵按下
        {
            Key_State = 1;//轉(zhuǎn)到按鍵確認
            Key_Prev  = Key_Press;//保存按鍵狀態(tài)
        }
        break;

    case 1://按鍵確認態(tài)01
        if ( Key_Press ==Key_Prev )//確認和上次按鍵相同
        {
            Key_State = 2;//判斷按鍵長按

            //返回按鍵按下鍵值,按鍵按下就響應,如果想彈起來再響應
            //可以在彈起來后再返回按鍵值

            Key_Return = KEY_DOWN | Key_Prev;
        }
        else//按鍵抬起,是抖動,不響應按鍵
        {
            Key_State = 0;
        }
        break;

    case 2://按鍵釋放態(tài)10
        if (Key_Press == NO_KEY )//按鍵釋放了
        {
            Key_State = 0;
            Key_Delay = 0;
            Key_Series  = FALSE;
            Key_Return  = KEY_UP | Key_Prev;      //返回按鍵抬起值
            break;
        }
        if ( Key_Press ==Key_Prev )
        {
            Key_Delay++;
            if ((Key_Series==TRUE) && (Key_Delay>KEY_SERIES_DELAY))
            {
                Key_Delay  = 0;
                Key_Return = KEY_LIAN | Key_Press;  //返回連發(fā)的值
                Key_Prev   = Key_Press;      //記住上次的按鍵.
                break;
            }
            if (Key_Delay>KEY_SERIES_FLAG)
            {
                Key_Series = TRUE;
                Key_Delay  = 0;
                Key_Return = KEY_LONG | Key_Prev;   //返回長按后的值
                break;
            }
        }

    default :
        break;
    }

    return Key_Return;
}
每10ms調(diào)用一次按鍵檢測,根據(jù)Key_Return的值來判斷按鍵的操作,用狀態(tài)機省去傳統(tǒng)按鍵的延時去抖,也不在在按鍵的死等待,對程序時間的利用有很大的幫助,根據(jù)按鍵返回的狀態(tài)值,事件可以在按鍵按下響應,也可以在按鍵彈起來響應,也可以實現(xiàn)連發(fā)、長按等功能。
關閉窗口

相關文章

主站蜘蛛池模板: 日韩视频精品在线 | 国产一区二区精品在线观看 | 精品亚洲一区二区 | 九九久久久久久 | 国产精品久久久久久52avav | 国产区在线观看 | 中文字幕一区二区三区在线乱码 | 黄页网址在线观看 | 人人操日日干 | 青青草综合网 | 国产精品高潮呻吟久久av野狼 | 久久久久久黄 | 精品国产乱码久久久久久丨区2区 | 久久亚洲欧美日韩精品专区 | 超碰导航| 欧美精品91爱爱 | 亚洲视频一区在线观看 | 欧美一区二区三区视频 | 久久久av| 国产高清视频在线观看 | 欧美一区二区 | 在线视频一区二区 | 精品视频一区二区三区四区 | 日韩av在线一区 | 欧美一区二区三区视频 | www.久草.com | 午夜国产一区 | a在线视频观看 | 久久久国产一区二区三区 | 国产精品自产拍在线观看蜜 | 亚洲日韩视频 | 三级黄色片在线播放 | 国产露脸国语对白在线 | 日韩成人中文字幕 | 国产一区二区视频免费在线观看 | 羞羞的视频在线观看 | 色频 | 亚洲自拍偷拍视频 | 五月婷亚洲| 欧美精品网站 | 色av一区二区三区 |