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

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

一個(gè)簡(jiǎn)單的按鍵去抖延時(shí)程序

作者:huqin   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年11月21日   【字體:

按鍵去抖,一般采用普通延時(shí),如

if((GPIOC->IDR & 0x01)== 0)
{
    delay_ms(20);
    if(GPIOC->IDR & 0x01)== 0
    {
            //進(jìn)行按鍵處理函數(shù)
    }
}

這個(gè)程序,需要有一個(gè)普通的延時(shí)程序,來檢測(cè)去抖動(dòng),這個(gè)延時(shí)一般采用for循環(huán)和while循環(huán)。這樣的話,就有一個(gè)問題,在延時(shí)的這20ms中,cpu一直在判斷時(shí)間有沒有到。如果不是中斷,是不會(huì)打斷cpu的程序的。這樣的話,去抖延時(shí),就會(huì)浪費(fèi)cpu的效率。
假如,按鍵掃描的后面跟一個(gè)協(xié)議處理的函數(shù)。
即:

while(1)

        scan_key();    //按鍵掃描
        exe();              //協(xié)議解析

這個(gè)時(shí)候,若接收中斷,在按鍵掃描時(shí)已經(jīng)處理完成,正好按下按鍵,這個(gè)時(shí)候就必須要有20ms的間隔,在判斷完按鍵后,才可以進(jìn)入?yún)f(xié)議解析函數(shù)。也就是說,如果沒有掃描函數(shù),協(xié)議會(huì)立即執(zhí)行解析并返回響應(yīng)數(shù)據(jù)。而添加按鍵掃描后,協(xié)議有可能會(huì)在20ms后,進(jìn)行解析并返回?cái)?shù)據(jù),這樣的話,就會(huì)使產(chǎn)品的實(shí)時(shí)性無法保證。

所以我想了另一個(gè)方法,采用標(biāo)致位,來實(shí)現(xiàn)延時(shí),當(dāng)然這個(gè)方法,肯定不是我第一個(gè)想出來的。如有雷同,可采用翻鋼镚方法進(jìn)行選擇。
就是采用if語句來實(shí)現(xiàn)延時(shí),只不過寫程序時(shí)比較麻煩,但穩(wěn)定性在stm8上測(cè)試了一下,感覺還可以。

代碼如下
首先申請(qǐng)幾個(gè)全局變量
unsigned int time_ms,time_us,time_ns,time_flag;
//以上這幾個(gè)是定時(shí)標(biāo)志和定時(shí)計(jì)數(shù)變量
unsigned key_old, key_new;
//這兩個(gè)是按鍵鍵值

/*******************************************************************************
 函數(shù)名:delay_ms()
 函數(shù)功能:延時(shí)
 參數(shù):ms 毫秒
 返回:無
 備注:此延時(shí)函數(shù)采用if實(shí)現(xiàn),使用時(shí),必須先申請(qǐng)flag變量然后調(diào)用延時(shí)函數(shù),最后在
  執(zhí)行中加入flag判斷
例:u16 time_flag,time_ms,time_us,time_ns;
delay_ms(u16 ms);
if(time_flag>0){time_flag=0;......內(nèi)容}
*******************************************************************************/
void key_delay(unsigned int ms)
{
if(time_ms<ms)
{
 if(time_us<10)                  //在應(yīng)用時(shí),不同的單片機(jī),不同的頻率,需要進(jìn)行調(diào)整
{
if(time_ns<8)            //在應(yīng)用時(shí)不同的單片機(jī),不同的頻率,需要進(jìn)行調(diào)整
{
time_ns++;
}
else
{
 time_us++;
 time_ns=0;
}
}
else
{
 time_ms++;
 time_us=0;
}
}
else
{
 time_flag=1;
 time_ms=0;
}
}


以上代碼,有一個(gè)time_flag,變量,這個(gè)變量就是定時(shí)標(biāo)致變量。一旦這個(gè)標(biāo)致置一,則說明定時(shí)器到時(shí)間
使用時(shí)可以

///////////////////////////////////////////////////////////
//函數(shù)名:scan()   
//功能:按鍵掃描    
//參數(shù):無     
//返回值:無        
//備注:        
///////////////////////////////////////////////////////////
void scan()
{
    u8 key_new;
    key_new = GPIOC->IDR;
    if(key_old != key_new)
    {
        key_delay(150);
        if(time_flag == 1)
        {
            time_flag = 0;
            if(key_old != key_new)
            {
               switch()
               {
                   case 1:  k1_exe();  break;
                   case 2:  k2_exe();  break;
                   case 3:  k3_exe();  break;
                   case 4:  k4_exe();  break;
                   default:        break;
                }
                key_old = key_new;
            }
            else
            }
                time_ms=0;   
            }
        }
    }
}

以上就是代碼
在大循環(huán)中,直接調(diào)用即可,和普通的按鍵函數(shù)一樣,只不過,這個(gè)的實(shí)時(shí)性,應(yīng)該相對(duì)較高一些。
while(1)

         scan_key();    //按鍵掃描
         exe();              //協(xié)議解析 

讓我們來分析一下,為啥這個(gè)函數(shù)相對(duì)較好一些。
首先,我們來看
scan_key(); 
首先,掃描IO端口,存放如新按鍵變量
key_new = GPIOC->IDR;
然后將新按鍵與老按鍵號(hào)進(jìn)行對(duì)比,如果新的按鍵號(hào)與老按鍵號(hào)不同,說明有按鈕按下。
if(key_old != key_new)
當(dāng)有按鈕按下的時(shí)候進(jìn)入,延時(shí)函數(shù),
key_delay(150);
這時(shí),進(jìn)入多個(gè)if判斷,進(jìn)行time_ns++;這個(gè)函數(shù),最主要的功能就是判斷,當(dāng)前的時(shí)間time_ms,與參數(shù)時(shí)間,是否一致,若不一致,則退出函數(shù)。這時(shí)time_flag不為1,當(dāng)前的時(shí)間time_ms,與參數(shù)時(shí)間一致 ,這時(shí)time_flag為1。
if(time_flag == 1)
這個(gè)判斷就是判斷到時(shí)標(biāo)致,如果到時(shí),則說明去抖時(shí)間完成,則在判斷一次if(key_old != key_new),如果為否,則說明按鍵確實(shí)按下,否則則為沒有按下。有按鍵按下時(shí),則會(huì)執(zhí)行按鍵處理函數(shù)。
若沒有按鍵按下,則清楚計(jì)數(shù)器。程序繼續(xù)執(zhí)行。
也就是說,不管是否在延時(shí)狀態(tài),程序,都會(huì)向下執(zhí)行,而不會(huì)卡在某一個(gè)函數(shù)或循環(huán)內(nèi)不動(dòng)。這樣的話,程序就會(huì)向下繼續(xù)執(zhí)行。
在程序中,若既有按鍵,又有一些對(duì)待實(shí)時(shí)性較高,但又不樂意放在中斷里的程序。可以采用這種方法來實(shí)現(xiàn)按鍵延時(shí),可以相對(duì)的提高程序的運(yùn)行效率。目前這個(gè)程序,不支持長(zhǎng)按,但可以實(shí)現(xiàn)簡(jiǎn)單的組合按鍵。
歡迎一切拍磚,轉(zhuǎn)載以及抄襲。若感覺此文章對(duì)您有所幫助,請(qǐng)支持一下51hei單片機(jī)論壇
您的支持,是我原創(chuàng)的動(dòng)力,謝謝。

關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 狠狠干狠狠插 | 国产超碰人人爽人人做人人爱 | 性色在线 | 久久国产精品免费一区二区三区 | 免费成人在线网站 | 欧美日韩在线免费观看 | 久久久精品国产 | 日韩在线视频一区二区三区 | 三级高清 | 毛片电影 | 日本不卡在线观看 | 国产一区91精品张津瑜 | 久久精品一区 | 91精品国产乱码久久久久久久久 | 亚洲免费网 | 先锋资源站 | 国产午夜精品一区二区三区嫩草 | 亚洲高清视频在线观看 | 国产精品久久久久久久久久免费看 | 中文字幕精品一区久久久久 | 夜夜夜久久久 | 久久专区 | 狠狠操婷婷 | 亚洲精品一区在线观看 | 91精品国产综合久久久动漫日韩 | 成人在线一区二区三区 | 美女福利网站 | 97视频在线观看网站 | 免费网站国产 | 暖暖日本在线视频 | 亚洲一区中文字幕 | 一区二区三区免费 | 亚洲一区二区三区四区五区午夜 | 男女羞羞视频在线看 | 91精品国产91综合久久蜜臀 | 久久精品欧美一区二区三区不卡 | 在线一区二区三区 | 久久亚洲综合 | 国产精品一区二区免费 | 欧美一级淫片007 | 久久精品屋|