在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

經(jīng)常需要MCU判斷短按和長按的兩種動作

GReq_mcu168 ? 來源:TopSemic嵌入式 ? 作者:TopSemic嵌入式 ? 2022-05-26 16:17 ? 次閱讀

電子產(chǎn)品中經(jīng)常用到按鍵,尤其是經(jīng)常需要MCU判斷短按長按這兩種動作,本篇我們來專門聊下這個話題

只談理論太無聊,我們還是結(jié)合著實(shí)際應(yīng)用來說明。之前寫過一篇關(guān)于《CH573第一篇:實(shí)現(xiàn)自拍桿藍(lán)牙遙控器1》的文章,例子默認(rèn)的功能是藍(lán)牙連接后不斷的發(fā)送數(shù)據(jù),從而不斷的拍照。而實(shí)際中的遙控器通常是按一次按鍵,控制一次,我們在來實(shí)現(xiàn)該功能。

7415d88a-dcbb-11ec-ba43-dac502259ad0.png

板子上只有兩個按鍵,一個是RESET按鍵,一個是DOWNLOAD按鍵,我們使用DOWNLAOD按鍵,按鍵的一端接GND,另外一端接CH573的PB22引腳。

7439a4ae-dcbb-11ec-ba43-dac502259ad0.png

原理圖中有一個NC的C5,但是實(shí)際板子上我卻沒有找到它,可能是版本不一致。

提前說明一下:CH573的代碼里跑了TMOS(Task Management Operating System),可以理解為一個簡單的操作系統(tǒng),所以下面的代碼一般的裸機(jī)代碼看著略有不同,不過核心思想都是一樣的,用在其他地方也很容易移植,只需要將其中的定時器部分改寫即可。

最初我是這么做的,把PB22配置為上拉輸入,開啟下降沿中斷,在中斷服務(wù)函數(shù)里,啟動一個事件,執(zhí)行藍(lán)牙發(fā)送。代碼如下:

voidKey_Init()
{
GPIOB_ModeCfg(GPIO_Pin_22,GPIO_ModeIN_PU);
GPIOB_ITModeCfg(GPIO_Pin_22,GPIO_ITMode_FallEdge);
PFIC_EnableIRQ(GPIO_B_IRQn);
}
voidGPIOB_IRQHandler(void)
{
if(GPIOB_ReadPortPin(GPIO_Pin_22)==0)
{
GPIOB_ClearITFlagBit(GPIO_Pin_22);
tmos_set_event(hidEmuTaskId,START_REPORT_EVT);
}
}

這么寫能工作,但是有問題,就是經(jīng)常會出現(xiàn)按一下誤判為多次按下。原因大家應(yīng)該都清楚,因為按鍵存在抖動,所以一次按下有可能進(jìn)入多次進(jìn)入中斷。

理想中的按下-彈起波形是這樣的:

745bd100-dcbb-11ec-ba43-dac502259ad0.png

但是實(shí)際由于按鍵抖動的存在,實(shí)際的波形可能是這樣的:

74cc78e2-dcbb-11ec-ba43-dac502259ad0.png

不信的話你可以接上示波器看看,或者軟件驗證,比如在GPIO中斷服務(wù)函數(shù)里,設(shè)置一個全局變量,讓它每次進(jìn)入中斷后加1,按按鍵觀察這個變量的值。

那么該如何消除抖動呢?一種方法是硬件消抖,即按鍵兩端并聯(lián)一個小電容(電容大小由按鍵的機(jī)械特性來決定),另外一種方法是我們今天要重點(diǎn)介紹的軟件消抖。

方法一:常用的加延時函數(shù)

在中斷服務(wù)函數(shù)中加一個比如10ms的延時函數(shù),延時時間的長短取決于實(shí)際所用的按鍵特性,只要延時時間比抖動時間略大即可。原理很簡單,加了延時就避開了抖動的這段時間,在延時之后判斷引腳電平,如果為低電平就表示是按下。

voidGPIOB_IRQHandler(void)
{
if(GPIOB_ReadPortPin(GPIO_Pin_22)==0)
{
mDelaymS(10);
if(GPIOB_ReadPortPin(GPIO_Pin_22)==0)
tmos_set_event(hidEmuTaskId,START_REPORT_EVT);
GPIOB_ClearITFlagBit(GPIO_Pin_22);
}
}

這個方法很簡單,但是不好的地方是延時占用MCU資源。尤其是這里的BLE應(yīng)用,在中斷服務(wù)函數(shù)中執(zhí)行時間長會引起藍(lán)牙連接中斷,所以這里不能這么用,我實(shí)際測試當(dāng)按鍵按快一點(diǎn)就很容易引起藍(lán)牙連接中斷。

方法二:加定時器

它的原理和方法一類似,只不過是不在中斷服務(wù)函數(shù)中阻塞等待,而是用一個定時器,代碼如下:

voidGPIOB_IRQHandler(void)
{
if(GPIOB_ReadPortPin(GPIO_Pin_22)==0)
{
GPIOB_ClearITFlagBit(GPIO_Pin_22);

tmos_stop_task(hidEmuTaskId,START_DEBOUNCE_EVT);
tmos_start_task(hidEmuTaskId,START_DEBOUNCE_EVT,16);
}
}
if(events&START_DEBOUNCE_EVT)
{
if(GPIOB_ReadPortPin(GPIO_Pin_22)==0)
{
PRINT("shortpress
");
tmos_set_event(hidEmuTaskId,START_REPORT_EVT);
}

return(events^START_DEBOUNCE_EVT);
}

它的邏輯是每次抖動的下降沿重新開啟10ms定時器,在定時器時間到之后判斷IO電平狀態(tài)來判斷按鍵是否按下。

需要注意的是:10ms定時器不是一個周期性的定時器,它是一次性的,即時間到了之后就停止計時了。另外每次進(jìn)中斷后先讓定時器重新重頭開始計時。如果大家用其他代碼實(shí)現(xiàn)時要注意這兩點(diǎn)。

此方法的好處不像加延時函數(shù)那樣占用MCU資源。我實(shí)際測試這個方法可用,不會引起藍(lán)牙連接中斷。

以上介紹了使用中斷的方式來判斷按鍵短按,可以看到它判斷的依據(jù)是按鍵按下(由高電平變到低電平)這個狀態(tài)。下面在方法二的基礎(chǔ)上我們來實(shí)現(xiàn)長按的檢測,判斷長按的依據(jù)是按下后持續(xù)的維持一段時間低電平。代碼如下:

if(events&START_DEBOUNCE_EVT)
{
if(GPIOB_ReadPortPin(GPIO_Pin_22)==0)
{
PRINT("shortpress
");
tmos_set_event(hidEmuTaskId,START_REPORT_EVT);
tmos_start_task(hidEmuTaskId,START_LONGCHECK_TIMER,16);
}

return(events^START_DEBOUNCE_EVT);
}
if(events&START_LONGCHECK_TIMER)
{
staticintcnt=0;
if(GPIOB_ReadPortPin(GPIO_Pin_22)==0)
{
cnt++;
if(cnt>100)
{
PRINT("longpress
");
tmos_stop_task(hidEmuTaskId,START_LONGCHECK_TIMER);
cnt=0;
}
else
tmos_start_task(hidEmuTaskId,START_LONGCHECK_TIMER,16);
}
else
{
cnt=0;
tmos_stop_task(hidEmuTaskId,START_LONGCHECK_TIMER);
}

return(events^START_LONGCHECK_TIMER);
}

實(shí)現(xiàn)的邏輯是:當(dāng)檢測到短按時,再開啟一個10ms定時器,在定時器到時之中判斷電平狀態(tài),如果為低電平,就讓cnt變量加1,否則cnt=0,當(dāng)cnt>100,即低電平持續(xù)1s認(rèn)為是長按。我在這里當(dāng)判斷到長按之后或者IO變高之后會停止掉這個定時器,否則周期定時,因為沒必要一直開著定時器。

除了上述的中斷方式,還可以使用輪詢的方式來實(shí)現(xiàn),代碼如下:

voidKey_Init()
{
GPIOB_ModeCfg(GPIO_Pin_22,GPIO_ModeIN_PU);
}
if(events&START_KEYSCAN_EVT)
{
KeyScan();
tmos_start_task(hidEmuTaskId,START_KEYSCAN_EVT,160);//100ms執(zhí)行一次KeyScan()
return(events^START_KEYSCAN_EVT);
}
boolkey_press_flag=false;//按下標(biāo)志
boolkey_long_press_flag=false;//長按標(biāo)志

voidKeyScan()
{
if(GPIOB_ReadPortPin(GPIO_Pin_22)==0)//低電平
{
if(key_press_flag==false)
tmos_start_task(hidEmuTaskId,START_LONGCHECK_TIMER,1600);//啟動1s定時器

key_press_flag=true;//置位按下標(biāo)志
}
elseif(key_press_flag==true)//高電平同時按鍵被按下過,表示是按下后的彈起
{
key_press_flag=false;//清除按下標(biāo)志

if(key_long_press_flag==false)//短按后的彈起
{
tmos_stop_task(hidEmuTaskId,START_LONGCHECK_TIMER);
PRINT("shortpress
");
tmos_set_event(hidEmuTaskId,START_REPORT_EVT);
}
else//長按后的彈起
{
key_long_press_flag=false;
}
}
else
{
key_press_flag=false;
key_long_press_flag=false;
}

}
if(events&START_LONGCHECK_TIMER)
{
key_long_press_flag=true;
PRINT("longpress
");
return(events^START_LONGCHECK_TIMER);
}

上面的這段代碼初次看著有點(diǎn)繞,但是看明白了之后會覺得這個實(shí)現(xiàn)邏輯還是挺好的,注釋寫了,這里不再詳細(xì)解釋了,我在多個項目里使用的都是它。它兼顧了去抖和短按/長按的檢測,并且長按可以判斷出長按按下/長按彈起。短按是檢測到彈起時認(rèn)為是短按動作。另外如果想同時支持多個長按,也很方便添加。

輪詢和中斷各有優(yōu)缺點(diǎn),大家可以根據(jù)實(shí)際情況來選擇,你一般常用哪種方式呢?

審核編輯 :李倩

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • mcu
    mcu
    +關(guān)注

    關(guān)注

    146

    文章

    17422

    瀏覽量

    353598
  • 操作系統(tǒng)
    +關(guān)注

    關(guān)注

    37

    文章

    6929

    瀏覽量

    124035

原文標(biāo)題:如何實(shí)現(xiàn)按鍵的短按、長按檢測?

文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    覆銅的兩種形式是什么

    在電子電路設(shè)計與制造領(lǐng)域,覆銅的實(shí)現(xiàn)形式多樣,其中大面積的覆銅和網(wǎng)格銅是最為常見且各具特色的兩種,它們在不同的應(yīng)用場景下發(fā)揮著關(guān)鍵作用。 大面積的覆銅,顧名思義,是指在印刷電路板(PCB)的特定區(qū)域
    的頭像 發(fā)表于 02-04 14:10 ?138次閱讀

    AMC1204有兩種封裝,SOIC-8和SOIC-16,功能一樣嗎?為什么要推出兩種封裝?

    呢?AMC1204,AMC1304這樣做有什么好處嗎? 2、AMC1204有兩種封裝,SOIC-8和SOIC-16,功能一樣嗎?為什么要推出兩種封裝?
    發(fā)表于 12-27 07:22

    噪聲傳導(dǎo)的兩種模式

    噪聲傳導(dǎo)有兩種模式,一為差模傳導(dǎo),一為共模傳導(dǎo)。
    的頭像 發(fā)表于 10-15 11:33 ?433次閱讀
    噪聲傳導(dǎo)的<b class='flag-5'>兩種</b>模式

    Linux應(yīng)用層控制外設(shè)的兩種不同的方式

    眾所周知,linux下一切皆文件,那么應(yīng)用層如何控制硬件層,同樣是通過 文件I/O的方式來實(shí)現(xiàn)的,那么應(yīng)用層控制硬件層通常有兩種方式。
    的頭像 發(fā)表于 10-05 19:03 ?798次閱讀
    Linux應(yīng)用層控制外設(shè)的<b class='flag-5'>兩種</b>不同的方式

    兩種電纜類型的特點(diǎn)及優(yōu)勢

    隨著技術(shù)的發(fā)展,電纜的材料和結(jié)構(gòu)不斷優(yōu)化,以滿足日益增長的電力需求和復(fù)雜的應(yīng)用環(huán)境。本文將詳細(xì)探討兩種廣泛使用的電纜類型——聚氯乙烯絕緣電纜和交聯(lián)聚乙烯絕緣電纜,它們的特點(diǎn)、優(yōu)勢及適用范圍。 一
    的頭像 發(fā)表于 08-28 16:23 ?573次閱讀

    晶閘管的阻斷狀態(tài)有兩種是什么

    晶閘管(Thyristor)是一半導(dǎo)體器件,具有單向?qū)щ娦裕瑥V泛應(yīng)用于電力電子領(lǐng)域。晶閘管的阻斷狀態(tài)有兩種:正向阻斷狀態(tài)和反向阻斷狀態(tài)。以下是對這兩種阻斷狀態(tài)的分析。 正向阻斷狀態(tài) 正向阻斷狀態(tài)
    的頭像 發(fā)表于 08-14 16:49 ?952次閱讀

    接地保護(hù)分為哪兩種方式

    接地保護(hù)是電氣工程中非常重要的一安全措施,其目的是確保電氣設(shè)備和系統(tǒng)在發(fā)生故障時能夠安全地將電流導(dǎo)向地面,從而保護(hù)人身安全和設(shè)備安全。接地保護(hù)主要分為兩種方式:工作接地和保護(hù)接地。以下是對這兩種
    的頭像 發(fā)表于 08-05 10:24 ?1433次閱讀

    S8115系列應(yīng)用于長按或者短按ON-OFF開關(guān)控制芯片中文手冊

    S8115系列是專門用于長按或者短按ON-OFF開關(guān)控制芯片。廣泛應(yīng)用于各種電子產(chǎn)品和需要電子開關(guān)的場合。可選擇對正極觸發(fā)和對負(fù)極觸發(fā)。可選擇長按或者
    發(fā)表于 07-24 11:48 ?2次下載

    wdm設(shè)備的兩種傳輸方式

    系統(tǒng)中,有多種傳輸方式,其中最常見的兩種是密集波分復(fù)用(DWDM)和粗波分復(fù)用(CWDM)。 1. 密集波分復(fù)用(DWDM) 1.1 DWDM技術(shù)原理 密集波分復(fù)用(Dense Wavelength Division Multiplexing,簡稱DWDM)是一將多個不
    的頭像 發(fā)表于 07-18 09:45 ?586次閱讀

    時間繼電器按照觸點(diǎn)動作方式分為哪兩種

    時間繼電器是一常用的自動化控制元件,廣泛應(yīng)用于各種工業(yè)自動化控制系統(tǒng)中。它通過控制電路的通斷,實(shí)現(xiàn)對時間的控制。根據(jù)觸點(diǎn)動作方式的不同,時間繼電器可以分為兩種類型:瞬時型和延時型。 一、瞬時型
    的頭像 發(fā)表于 06-21 10:21 ?2693次閱讀

    PCBA加工中常見的兩種焊接方式詳解

    ,在PCBA行業(yè)中經(jīng)常被使用。接下來深圳PCBA加工廠家為大家詳細(xì)介紹PCBA加工手工焊接的兩種方式,為您揭秘行業(yè)內(nèi)的技術(shù)細(xì)節(jié)。 PCBA加工過程中常用焊接方式 第一方式是傳統(tǒng)手工焊接。這種方式主要依靠技術(shù)工人的手動操作進(jìn)行焊
    的頭像 發(fā)表于 06-14 09:18 ?701次閱讀

    CC2340R5無法讀取到按鍵按下的動作怎么解決?

    電平,自己實(shí)現(xiàn)長按/短按的邏輯判斷。 調(diào)用接口GPIO_read;如下所示: MenuModule_printf()打印方式已調(diào)整為滾屏打印; 經(jīng)驗證task1中的GPIO_toggle(CONFIG_GPIO_LED_GRE
    發(fā)表于 05-30 07:59

    充電樁為什么有直流與交流兩種接口?

    充電樁設(shè)計有直流(DC)和交流(AC)兩種接口,主要是為了適應(yīng)不同類型的電動汽車(EV)充電需求以及電池的充電特性。
    的頭像 發(fā)表于 04-30 15:33 ?1909次閱讀

    800G光模塊的兩種主流封裝

    隨著信息時代的快速發(fā)展,網(wǎng)絡(luò)通信的數(shù)據(jù)傳輸速率也在不斷提升。800G光模塊作為當(dāng)前網(wǎng)絡(luò)通信領(lǐng)域的重要組件,其封裝類型對于模塊的性能和可靠性具有重要影響。本文小易將為大家介紹800G光模塊的兩種封裝類型。
    的頭像 發(fā)表于 04-24 16:20 ?960次閱讀

    GYFTA、GYFTY兩種光纜的區(qū)別

    GYFTA和GYFTY兩種光纜的區(qū)別主要在于它們的結(jié)構(gòu)和應(yīng)用場景。 GYFTA光纜是一室外非金屬加強(qiáng)芯松套管層絞聚乙烯粘連鋁帶護(hù)套光纜。這種光纜的結(jié)構(gòu)特點(diǎn)是它使用了非金屬加強(qiáng)芯,并且光纜的外護(hù)套
    的頭像 發(fā)表于 03-26 10:26 ?2320次閱讀
    主站蜘蛛池模板: 国产精品乱码高清在线观看 | 在线a亚洲老鸭窝天堂新地址 | 国产―笫一页―浮力影院xyz | 一国产大片在线观看 | 天天碰天天操 | 国产人成午夜免费看 | xx毛片 | 国产精品久久久久久久久久免费 | 欧美色综合久久 | 亚洲毛片大全 | 成人理伦 | 特级毛片aaaa免费观看 | 天天插天天射 | 久久香蕉国产视频 | 欧美午夜网站 | 日本免费黄色录像 | 欧洲无线区一二区 | 国产精品四虎 | 一级特黄aaa大片在线观看视频 | 美女被拍拍拍拍拍拍拍拍 | 插白浆| 四虎影院成人在线观看 | 国产va精品免费观看 | 快乐你懂的在线视频免费观看 | 人人做人人爽人人爱秋霞影视 | 99久久免费中文字幕精品 | 成人三级在线观看 | 午夜爽爽| aaa一级最新毛片 | 天堂网最新 | 天天干人人| 狠狠色噜狠狠狠狠 | 亚洲一区欧美二区 | 国内精品久久久久影院薰衣草 | 五月婷婷激情综合网 | 日本加勒比高清一本大道 | 狠狠干狠狠爱 | 国产亚洲综合视频 | 一级片免费在线播放 | 亚洲成人免费观看 | yy6080亚洲半夜理论一级毛片 |