鴻蒙Hi3861開發(fā)板實(shí)現(xiàn)按鍵“按下事件”和“釋放事件”的通用框架
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
在帖子 《鴻蒙開發(fā)板外設(shè)控制》直播圖文版(2020.10.28) 中我們提到過:“開發(fā)板上的按鍵也可以看作一種 GPIO 外設(shè)。” 因此,要捕捉按鍵的狀態(tài)(按下或釋放)必須操作對(duì)應(yīng)的 GPIO 端口,具體步驟如下:
- 確定目標(biāo)按鍵對(duì)應(yīng)的 GPIO 引腳(可通過設(shè)備文檔找到對(duì)應(yīng)關(guān)系)
- 重新定義 GPIO 引腳的功能,數(shù)據(jù)傳輸方向設(shè)置為輸入(WIFI_IOT_GPIO_DIR_IN)
- 設(shè)置按鍵事件觸發(fā)方式(電平觸發(fā)或邊沿觸發(fā)),并注冊(cè)回調(diào)函數(shù)
示例代碼如下:
代碼說明:
- WIFI_IOT_IO_NAME_GPIO_8 端口連接了按鍵,若需要捕獲按鍵事件需要調(diào)用 IoSetFunc() 函數(shù)重定義端口功能
- 調(diào)用 IoSetPull() 函數(shù)將端口初始電平拉高(Pull Up)
- 調(diào)用 GpioRegisterIsrFunc() 函數(shù)設(shè)置按鍵事件為邊沿觸發(fā)方式,具體為下降沿觸發(fā)
- 將自定義的 OnButtonPressed() 函數(shù)注冊(cè)為按鍵回調(diào)函數(shù),即:按鍵被按下時(shí)調(diào)用此函數(shù)
綜上可知,每個(gè)下降沿對(duì)應(yīng)著按鍵按下,那么上升沿顯然對(duì)應(yīng)這按鍵釋放;因此,可設(shè)置上升沿觸發(fā)按鍵事件,即:按鍵釋放時(shí)調(diào)用注冊(cè)的回調(diào)函數(shù)。
代碼如下:
GpioRegisterIsrFunc(WIFI_IOT_IO_NAME_GPIO_8,
WIFI_IOT_INT_TYPE_EDGE,
WIFI_IOT_GPIO_EDGE_RISE_LEVEL_HIGH,
OnButtonReleased, NULL);
0K! 接下來我們思考一個(gè)問題:如果同時(shí)需要捕獲按鍵按下和釋放兩個(gè)事件,如何寫代碼實(shí)現(xiàn)?即:按鍵按下時(shí) OnButtonPressed() 被調(diào)用,按鍵釋放時(shí) OnButtonReleased() 被調(diào)用。
也許有同學(xué)的第一想法會(huì)是:注冊(cè)兩次不就完事了嗎?。?!
用代碼描述就是:
這看起來似乎合情合理,但,這么做是不行滴?。?!因?yàn)椋湍壳皝碚f,每個(gè) GPIO 口只能注冊(cè)一個(gè)回調(diào)函數(shù);所以,第二次注冊(cè)的信息將覆蓋第一次的注冊(cè)信息;說得更直白些:這么寫,只會(huì)在上升沿觸發(fā)回調(diào) OnButtonReleased() !
那么是不是就沒法同時(shí)捕獲按鍵按下和釋放兩個(gè)事件呢?
那到不是,我們可以采用下面的方法實(shí)現(xiàn)。
對(duì)應(yīng)代碼如下:
初始回調(diào)注冊(cè):
回調(diào)函數(shù)中切換注冊(cè):
看到這里,相信大家已經(jīng)掌握了同時(shí)捕獲按下事件和釋放事件的方法了。然而,即便如此,當(dāng)程序中需要使用多個(gè)按鍵時(shí),我們不得不反復(fù)的編寫幾乎一模一樣的代碼。。。這并不是一件有趣的事,我們的時(shí)間應(yīng)該花在更有創(chuàng)造性的工作上!所以,我把上面的方法封裝到兩個(gè)獨(dú)立的文件(dt_btn_util.h和dt_btn_util.c)中,方便大家需要時(shí)一鍵調(diào)用!
示例代碼如下:
是不是很簡(jiǎn)單?!一行代碼即可同時(shí)捕獲按下事件和釋放事件。
示例代碼和封裝好的文件在附件中開箱即用。
相關(guān)代碼附件可以前往原文進(jìn)行下載:https://harmonyos.51cto.com/posts/1512
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)