鴻蒙實現(xiàn)S1,S2,User三個物理按鍵的獨立事件-上(解決思路分析)
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
https://harmonyos.51cto.com/#zz
上 一篇帖子《實現(xiàn)物理按鍵的“長按事件”(按鍵通用框架 V0.0.2)》中開源了 DTButton – V0.0.2 的完整代碼,這個版本的實現(xiàn)完全封裝了Hi3861的原生SDK,實現(xiàn)了開箱即用,所見即所得。然而,相信大家也發(fā)現(xiàn)了一個有趣的現(xiàn)象:S1, S2 和 User 三個物理按鍵同時對應(yīng)了 GPIO_5 端口。

程序中將 GPIO_5 作為按鍵端口連接使用后,無論按下 S1,S2,User 中的哪一個都會觸發(fā)事件,就好像“同一個 GPIO 按鍵有了3個不同分身”。為什么會這樣呢?因為在硬件連接上,這三個物理按鍵確實共用了 GPIO_5 ,所以才有了這個問題。
那么,怎么解決這個問題呢?
就目前來看,想要區(qū)分 S1,S2 和 User 只能從電氣特性來入手了,根據(jù)上圖中黃色下劃線處的提示翻看原理圖《HiSpark_WiFi_IoT_OLED_VER.A》,可以發(fā)現(xiàn) S1 和 S2 的連接如下:

明顯可知:S1 和 S2 按下之后紅框位置 switch 處的電壓肯定會發(fā)生變化,并且 S1 按下后的電壓與 S2 按下后的電壓不同。
所以,可以考慮通過檢測電壓的方式來判斷究竟哪個鍵被按下了!!!
看起來是不是有點瘋狂!然而,確實可以這么解決問題。
通過實驗發(fā)現(xiàn)這 3 個物理按鍵按下后的電壓范圍大致如下:

并且,通過查閱文檔《Hi3861V100/Hi3861LV100 設(shè)備驅(qū)動 開發(fā)指南》中的第 5 章可以找到讀取 ADC 值的 API 接口,以及 ADC 值到電壓值的轉(zhuǎn)換公式:

問題:ADC 是什么?
ADC 指的是 Analog-to-Digital Convertor,即:模/數(shù)轉(zhuǎn)換器。
在這個問題中,3 個物理按鍵的電壓模擬值會被 ADC 轉(zhuǎn)換為數(shù)字值(ADC值),并且電壓值和 ADC 值是單純的線性轉(zhuǎn)換關(guān)系,所以,通過檢測 ADC 值的變化就可以判斷被按下的物理按鍵。
將表一中的電壓范圍通過公式轉(zhuǎn)換為 ADC 范圍:
有了這張表之后,離解決問題就更近了一步,接下來看看相關(guān) API 接口的示例:調(diào)用 hi_adc_read() 讀取通道7的 ADC 值。

函數(shù) hi_adc_read() 第一個參數(shù)用于指定需要讀取的 ADC 通道,第二個參數(shù)用于保存讀取的 ADC 值。
對于我們這個問題來說,最關(guān)鍵的就是要知道 GPIO_5 對應(yīng)的 ADC 通道是哪一個。這時可以查閱文檔《Hi3861V100/Hi3861LV100/Hi3881V100 WiFi芯片 用戶指南》,在第 6 章中可以找到下面的表格:
表6-2中紅框部分的對應(yīng)關(guān)系指出:由于 Hi3861 數(shù)字管腳有限,故 GPIO_5 與 ADC_2 復(fù)用同一管腳。
So! 在代碼層面,可以通過 hi_adc_read() 讀取 HI_ADC_CHANNEL_2 處的 ADC 值,進(jìn)而判斷 S1,S2,User 中被按下的按鍵。
OK!所有障礙已被掃清,這時可以用代碼描述了:
很顯然,每次調(diào)用 GetSSU() 即可知道是否有鍵被按下,以及具體哪個鍵被按下。
看到此處,問題已徹底解決!!
PS:所查閱的文檔以及最終示例代碼均可在附件中下載。
Enjoy it!
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
https://harmonyos.51cto.com/#zz