91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

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

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

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

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

GReq_mcu168 ? 來(lái)源:TopSemic嵌入式 ? 作者:TopSemic嵌入式 ? 2022-05-26 16:17 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

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

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

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

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

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

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

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

最初我是這么做的,把PB22配置為上拉輸入,開啟下降沿中斷,在中斷服務(wù)函數(shù)里,啟動(dòng)一個(gè)事件,執(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);
}
}

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

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

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

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

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

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

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

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

在中斷服務(wù)函數(shù)中加一個(gè)比如10ms的延時(shí)函數(shù),延時(shí)時(shí)間的長(zhǎng)短取決于實(shí)際所用的按鍵特性,只要延時(shí)時(shí)間比抖動(dòng)時(shí)間略大即可。原理很簡(jiǎn)單,加了延時(shí)就避開了抖動(dòng)的這段時(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);
}
}

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

方法二:加定時(shí)器

它的原理和方法一類似,只不過(guò)是不在中斷服務(wù)函數(shù)中阻塞等待,而是用一個(gè)定時(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);
}

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

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

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

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

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)檢測(cè)到短按時(shí),再開啟一個(gè)10ms定時(shí)器,在定時(shí)器到時(shí)之中判斷電平狀態(tài),如果為低電平,就讓cnt變量加1,否則cnt=0,當(dāng)cnt>100,即低電平持續(xù)1s認(rèn)為是長(zhǎng)按。我在這里當(dāng)判斷到長(zhǎng)按之后或者IO變高之后會(huì)停止掉這個(gè)定時(shí)器,否則周期定時(shí),因?yàn)闆](méi)必要一直開著定時(shí)器。

除了上述的中斷方式,還可以使用輪詢的方式來(lái)實(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;//長(zhǎng)按標(biāo)志

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

key_press_flag=true;//置位按下標(biāo)志
}
elseif(key_press_flag==true)//高電平同時(shí)按鍵被按下過(guò),表示是按下后的彈起
{
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//長(zhǎng)按后的彈起
{
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)繞,但是看明白了之后會(huì)覺(jué)得這個(gè)實(shí)現(xiàn)邏輯還是挺好的,注釋寫了,這里不再詳細(xì)解釋了,我在多個(gè)項(xiàng)目里使用的都是它。它兼顧了去抖和短按/長(zhǎng)按的檢測(cè),并且長(zhǎng)按可以判斷出長(zhǎng)按按下/長(zhǎng)按彈起。短按是檢測(cè)到彈起時(shí)認(rèn)為是短按動(dòng)作。另外如果想同時(shí)支持多個(gè)長(zhǎng)按,也很方便添加。

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

審核編輯 :李倩

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

    關(guān)注

    147

    文章

    19015

    瀏覽量

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

    關(guān)注

    37

    文章

    7416

    瀏覽量

    129455

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

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

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    TVS vs TSS 兩種保護(hù)機(jī)制的深度博弈

    在現(xiàn)代電子設(shè)備日益精密、工作環(huán)境愈發(fā)復(fù)雜的背景下,電路安全問(wèn)題尤其是雷擊和瞬態(tài)過(guò)壓(Surge)防護(hù),已成為產(chǎn)品設(shè)計(jì)中不可忽視的重要環(huán)節(jié)。其中,TVS(瞬態(tài)電壓抑制器)與TSS(晶閘管浪涌抑制器)是兩種廣泛應(yīng)用的浪涌保護(hù)器件。盡管二者均服務(wù)于同一目標(biāo)——保障電路
    的頭像 發(fā)表于 02-12 15:23 ?1305次閱讀
    TVS vs TSS <b class='flag-5'>兩種</b>保護(hù)機(jī)制的深度博弈

    如何正確配置AG32 MCU,實(shí)現(xiàn)FLASH或者代碼加密?

    功能主要包括兩種方式:Lock fash(鎖定Flash)和代碼加密(Code Encryption),它們可以在燒錄過(guò)程中通過(guò)特定工具和配置啟用。 方式一:Lockflash Lockflash
    發(fā)表于 01-22 15:01

    使用Firebase AI Logic生成圖像模型的兩種新功能

    為您的應(yīng)用添加自定義圖像,能夠顯著改善和個(gè)性化用戶體驗(yàn),有效提高用戶參與度。本文將探討使用 Firebase AI Logic 生成圖像的兩種新功能: 其一是 Imagen 專屬編輯功能預(yù)覽版;其二
    的頭像 發(fā)表于 11-30 09:28 ?479次閱讀

    用PLC實(shí)現(xiàn)卷徑計(jì)算的兩種算法

    卷徑計(jì)算,是動(dòng)態(tài)計(jì)算如鋼卷,紙卷等存料量的一方法,它是實(shí)現(xiàn)張力控制和自動(dòng)充放料、以及甩尾控制的重要前提。卷徑計(jì)算目前主流的方法有兩種,一是根據(jù)機(jī)列速度(產(chǎn)線速度)和和被測(cè)卷的轉(zhuǎn)動(dòng)角速度求得;另一
    的頭像 發(fā)表于 11-14 16:54 ?2253次閱讀
    用PLC實(shí)現(xiàn)卷徑計(jì)算的<b class='flag-5'>兩種</b>算法

    極簡(jiǎn)主義者的福音:GPIO關(guān)機(jī)功能,短按長(zhǎng)按一代碼搞定!

    追求代碼簡(jiǎn)潔高效?這個(gè)GPIO關(guān)機(jī)方案正適合你。僅需少量代碼,即可實(shí)現(xiàn)按鍵短按執(zhí)行重啟、長(zhǎng)按觸發(fā)關(guān)機(jī),結(jié)構(gòu)清晰,易于移植和維護(hù)。 本文將以Air8000核心板為例,分享如何使用GPIO控制預(yù)留
    的頭像 發(fā)表于 10-26 16:58 ?1038次閱讀
    極簡(jiǎn)主義者的福音:GPIO關(guān)機(jī)功能,<b class='flag-5'>短按</b><b class='flag-5'>長(zhǎng)按</b>一代碼搞定!

    ADI GMSL技術(shù)兩種視頻數(shù)據(jù)傳輸模式的區(qū)別

    本文深入介紹GMSL技術(shù),重點(diǎn)說(shuō)明用于視頻數(shù)據(jù)傳輸?shù)南袼啬J胶退淼滥J街g的差異。文章將闡明這兩種模式之間的主要區(qū)別,并探討成功實(shí)施需要注意的具體事項(xiàng)。
    的頭像 發(fā)表于 10-10 13:49 ?2445次閱讀
    ADI GMSL技術(shù)<b class='flag-5'>兩種</b>視頻數(shù)據(jù)傳輸模式的區(qū)別

    兩種TVS有啥不同?

    當(dāng)我們查看TVS二極管的規(guī)格書,常會(huì)看到有以下兩種種引腳功能標(biāo)識(shí)圖:對(duì)于初學(xué)者,看到感到疑惑,他們一樣嗎?他們有啥區(qū)別?為啥有的個(gè)尖頭往外,陽(yáng)極連在一起,有的個(gè)尖頭往里,陰極連在一起?一連三問(wèn)。EMC小哥根據(jù)自己經(jīng)驗(yàn)略作分析
    的頭像 發(fā)表于 09-15 20:27 ?870次閱讀
    這<b class='flag-5'>兩種</b>TVS有啥不同?

    兩種散熱路徑的工藝與應(yīng)用解析

    背景:兩種常見(jiàn)的散熱設(shè)計(jì)思路 在大電流或高功率器件應(yīng)用中,散熱和載流能力是PCB設(shè)計(jì)中必須解決的難題。常見(jiàn)的兩種思路分別是: 厚銅板方案:通過(guò)整體增加銅箔厚度(如3oz、6oz甚至更高),增強(qiáng)導(dǎo)熱
    的頭像 發(fā)表于 09-15 14:50 ?852次閱讀

    CMOS 2.0與Chiplet兩種創(chuàng)新技術(shù)的區(qū)別

    摩爾定律正在減速。過(guò)去我們靠不斷縮小晶體管尺寸提升芯片性能,但如今物理極限越來(lái)越近。在這樣的背景下,兩種創(chuàng)新技術(shù)站上舞臺(tái):CMOS 2.0 和 Chiplet(芯粒)。它們都在解決 “如何讓芯片更強(qiáng)” 的問(wèn)題,但思路卻大相徑庭。
    的頭像 發(fā)表于 09-09 15:42 ?1098次閱讀

    【BPI-CanMV-K230D-Zero開發(fā)板體驗(yàn)】+兩種開發(fā)板間的比較

    ,這里就不一一加以比對(duì)了。 此外,兩種在運(yùn)行是都需要軟件的支持,盡管都使用的是OPEN MV IDE,但還是有些許的差異,見(jiàn)圖3所示。 圖3 圖標(biāo)差異 當(dāng)然最本質(zhì)的還是在性能上的差異,單就AI識(shí)別
    發(fā)表于 07-17 21:40

    貼片晶振中兩種常見(jiàn)封裝介紹

    貼片晶體振蕩器作為關(guān)鍵的時(shí)鐘頻率元件,其性能直接關(guān)系到系統(tǒng)運(yùn)行的穩(wěn)定性。今天,凱擎小妹帶大家聊聊貼片晶振中兩種常見(jiàn)封裝——金屬面封裝與陶瓷面封裝。
    的頭像 發(fā)表于 07-04 11:29 ?1348次閱讀
    貼片晶振中<b class='flag-5'>兩種</b>常見(jiàn)封裝介紹

    兩種驅(qū)動(dòng)方式下永磁直線開關(guān)磁鏈電機(jī)的研究

    方式。 純分享帖,需要者可點(diǎn)擊附件免費(fèi)獲取完整資料~~~*附件:兩種驅(qū)動(dòng)方式下永磁直線開關(guān)磁鏈電機(jī)的研究.pdf【免責(zé)聲明】本文系網(wǎng)絡(luò)轉(zhuǎn)載,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問(wèn)題,請(qǐng)第一時(shí)間告知,刪除內(nèi)容!
    發(fā)表于 06-09 16:18

    兩種感應(yīng)電機(jī)磁鏈觀測(cè)器的參數(shù)敏感性研究

    (MRAS)轉(zhuǎn)速估算對(duì)參數(shù)的敏感性。 純分享帖,需要者可點(diǎn)擊附件免費(fèi)獲取完整資料~~~*附件:兩種感應(yīng)電機(jī)磁鏈觀測(cè)器的參數(shù)敏感性研究.pdf【免責(zé)聲明】本文系網(wǎng)絡(luò)轉(zhuǎn)載,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問(wèn)題,請(qǐng)第一時(shí)間告知,刪除內(nèi)容!
    發(fā)表于 06-09 16:16

    銣原子鐘與CPT原子鐘:兩種時(shí)間標(biāo)準(zhǔn)的區(qū)別

    在物理學(xué)的世界中,精密的時(shí)間測(cè)量是至關(guān)重要的。這就需要一個(gè)高度準(zhǔn)確且穩(wěn)定的時(shí)間標(biāo)準(zhǔn),這就是原子鐘。今天我們將探討兩種重要的原子鐘:銣原子鐘和CPT原子鐘,以及它們之間的主要區(qū)別。首先,我們來(lái)了解一下
    的頭像 發(fā)表于 05-22 15:49 ?794次閱讀
    銣原子鐘與CPT原子鐘:<b class='flag-5'>兩種</b>時(shí)間標(biāo)準(zhǔn)的區(qū)別

    TPS3423 毫微功耗雙按鈕控制器,具有短按長(zhǎng)按差異化技術(shù)手冊(cè)

    TPS3423 和 TPS3424 是按鈕控制器,可提供廣泛的短按長(zhǎng)按獨(dú)立檢測(cè)功能。這些器件每個(gè)按鈕提供多達(dá)個(gè)輸出(RESET 和 INT),可用于各種用例,包括啟用穩(wěn)壓器或斷路器、在給定的按下
    的頭像 發(fā)表于 04-09 10:49 ?920次閱讀
    TPS3423 毫微功耗雙按鈕控制器,具有<b class='flag-5'>短按</b>和<b class='flag-5'>長(zhǎng)按</b>差異化技術(shù)手冊(cè)