按鍵的實(shí)現(xiàn)邏輯(包括長(zhǎng)按、短按、雙擊等),在交互之中的用戶體驗(yàn)尤為重要,機(jī)智云GoKit_STM32按鍵的實(shí)現(xiàn)邏輯,在我見(jiàn)過(guò)的按鍵模塊中算不錯(cuò)的一個(gè)了!
上期我們分享了機(jī)智云串口的環(huán)形buff,相信大家在看了思維導(dǎo)圖之后對(duì)整個(gè)協(xié)議的結(jié)構(gòu)有了很好的理解,今天我們重點(diǎn)分析下機(jī)智云的按鍵處理機(jī)制。
在主程序main.c中,我們看到有2個(gè)定義
keyTypedef_tsingleKey[2];
keysTypedef_tkeys;
這個(gè)就是按鍵結(jié)構(gòu)體的相關(guān)定義了,我們先來(lái)看下singleKey[2],這是一個(gè)數(shù)組,類型為keyTypedef_t,我們看看具體定義:
__packed typedefstruct
{
uint8_tkeyNum;
uint32_tkeyRccPeriph;
GPIO_TypeDef *keyPort;
uint32_tkeyGpio;
gokitKeyFunction shortPress;
gokitKeyFunction longPress;
}keyTypedef_t;
結(jié)構(gòu)體包括第幾個(gè)按鍵、所屬按鍵時(shí)鐘、Port、Gpio、短按回調(diào)函數(shù)與長(zhǎng)按回調(diào)函數(shù),gokitKeyFunction是一個(gè)函數(shù)指針類型的定義,使用回調(diào)的好處就是一次性定義好,之后按下去所做的事情直接在回調(diào)函數(shù)中寫就可以了,結(jié)構(gòu)比較明了。
接下來(lái)再看看keysTypedef_t的定義
__packed typedefstruct
{
uint8_tkeyNum;
keyTypedef_t*singleKey;
}keysTypedef_t;
這個(gè)比較簡(jiǎn)單,定義了一個(gè)按鍵數(shù)量與 keyTypedef_t *類型的一個(gè)指針。然后我們看兩者怎么聯(lián)系的。
首先通過(guò)keyInitOne將按鍵0的相關(guān)信息定義到singleKey[0] 中,然后keys.keyNum++,之后將相關(guān)信息也定義到singleKey[1]中,之后將singleKey數(shù)組的指針賦值給 keys.singleKey ,之后通過(guò)keys就可以輕松調(diào)用2個(gè)按鍵的各項(xiàng)功能了。
在下面的keyParaInit中,實(shí)際初始化了按鍵IO的各項(xiàng)參數(shù),最后有一個(gè)定時(shí)器的初始化函數(shù)。timer2Init();主要初始化了定時(shí)器2,從預(yù)分頻與自動(dòng)重裝初值我們判斷出定時(shí)器1ms中斷一次,那么每1ms中斷一次做什么呢?我們追蹤到定時(shí)器2的中斷函數(shù),
我們看到,中斷中只做了一件事,按鍵句柄,我們具體看
keyHandle((keysTypedef_t*)&keys),
首先是讀取按鍵值,這個(gè)比較重點(diǎn),也是精髓,我們進(jìn)去看看,里面會(huì)對(duì)keyCountTime進(jìn)行累加10次,用來(lái)消抖,確定之后去得到按鍵真正的值
PRESS_KEY1與PRESS_KEY2定義如下
#define PRESS_KEY1 0x01
#define PRESS_KEY2 0x02
之后返回的readKey便是按鍵的值,函數(shù)返回值賦給keyPress,接下來(lái)便是一個(gè)狀態(tài)機(jī)。
具體的過(guò)程為:
開(kāi)始keyState為0,第一個(gè)10ms進(jìn)來(lái),如果檢測(cè)到keyPress!=0,證明有按鍵按下,將keyState狀態(tài)更新為1,keyPrev = keyPress;并將keyPress賦值給上一次的按鍵值。下一個(gè)10ms的時(shí)候我們進(jìn)去狀態(tài)1的地方執(zhí)行,分為2步,
1、如果當(dāng)前獲取到的狀態(tài)與上次一樣,認(rèn)為按鍵確實(shí)按下了,將狀態(tài)更新為2,同時(shí)將哪個(gè)按鍵以及按鍵按下的值賦給keyReturn,通過(guò)這個(gè)就可以明確哪個(gè)按鍵按下了。
2、如果當(dāng)前獲取到的狀態(tài)與上次不一樣,認(rèn)為是按鍵抖動(dòng),不進(jìn)行響應(yīng)。
第三個(gè)10ms來(lái)之后,進(jìn)去狀態(tài)2(假如不是抖動(dòng)),也是分2步
1、如果按鍵不等于上次的狀態(tài)(按下),則認(rèn)為按鍵松開(kāi),認(rèn)為一次按下完成,狀態(tài)清零,返回按鍵值。
2、如果狀態(tài)與上次還是一樣,則認(rèn)為一直在按著按鍵,就可以做長(zhǎng)按功能了。返回按鍵值。
如果進(jìn)去長(zhǎng)按了,則將狀態(tài)更新為3。
第四個(gè)10ms到來(lái)之后,進(jìn)去狀態(tài)3,用于判斷長(zhǎng)按之后的松手狀態(tài)。就不多說(shuō)了。
之后,通過(guò)keyReturn & KEY_UP判斷短按,keyReturn & KEY_LONG判斷長(zhǎng)按,之后通過(guò)回掉函數(shù)進(jìn)去相應(yīng)的函數(shù)執(zhí)行,這里的一個(gè)好處就是通過(guò)指針keys就可以調(diào)用所有的回調(diào)函數(shù)指針。
好,就先分析到這里,相信大家對(duì)按鍵部分的代碼都有一個(gè)比較詳細(xì)的了解了,但還是要一個(gè)一個(gè)分析,達(dá)到為我所用的地步,方可真正學(xué)會(huì)其中的精髓。覺(jué)得好的話可以下面點(diǎn)贊哦,你們的點(diǎn)贊是我最大的動(dòng)力!
-
函數(shù)
+關(guān)注
關(guān)注
3文章
4381瀏覽量
64895 -
源代碼
+關(guān)注
關(guān)注
96文章
2953瀏覽量
68392 -
機(jī)智云
+關(guān)注
關(guān)注
3文章
617瀏覽量
26851
原文標(biāo)題:Gokit3.0 STM32源代碼分析之四
文章出處:【微信號(hào):IoTMaker,微信公眾號(hào):機(jī)智云開(kāi)發(fā)者】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
【GoKit試用體驗(yàn)】+機(jī)智云GoKit開(kāi)發(fā)套件學(xué)習(xí)分享1之開(kāi)箱圖
【GoKit試用體驗(yàn)】+機(jī)智云GoKit開(kāi)發(fā)套件學(xué)習(xí)分享2之開(kāi)發(fā)板初認(rèn)識(shí)
【科技亦能傳承】轉(zhuǎn)贈(zèng) Gokit2.0,免費(fèi)換加強(qiáng)版Gokit3.0
【萬(wàn)元大獎(jiǎng)】機(jī)智云智能硬件創(chuàng)新大賽
【Gokit 3試用體驗(yàn)】(8)微信控制Gokit體驗(yàn)之機(jī)智云寵物屋
重磅| Gokit1.0用戶真情回饋-Gokit3.0免費(fèi)兌換
如何使用機(jī)智云開(kāi)發(fā)一款智能硬件產(chǎn)品
機(jī)智云在Amazon Alexa平臺(tái)發(fā)布Smarthome和Custom Skill,實(shí)現(xiàn)亞馬遜Echo直接控制Gokit
機(jī)智云2016~2017優(yōu)秀項(xiàng)目盤點(diǎn)
Cortex-M3的異常處理機(jī)制分析

機(jī)智云Gokit3.0源代碼分析之協(xié)議結(jié)構(gòu)體的定義

總結(jié):ARM的異常處理機(jī)制分析資料下載

基于機(jī)智云Gokit3.0的智能加濕器APP控制系統(tǒng)
基于機(jī)智云Gokit3.0的智能加濕器APP控制系統(tǒng)

如何處理機(jī)智云移動(dòng)應(yīng)用的刪除問(wèn)題

評(píng)論