|
Delphi Tang實(shí)現(xiàn)S1,S2,User三個(gè)物理按鍵的獨(dú)立事件-上(解決思路分析), 上一篇帖子《實(shí)現(xiàn)物理按鍵的“長(zhǎng)按事件”(按鍵通用框架 V0.0.2)》中開源了
DTButton – V0.0.2 的完整代碼,這個(gè)版本的實(shí)現(xiàn)完全封裝了Hi3861的原生SDK,實(shí)現(xiàn)了開箱即用,所見即所得。然而,相信大家也發(fā)現(xiàn)了一個(gè)有趣的現(xiàn)象:S1, S2 和 User 三個(gè)物理按鍵同時(shí)對(duì)應(yīng)了 GPIO_5 端口。
程序中將 GPIO_5 作為按鍵端口連接使用后,無(wú)論按下 S1,S2,User 中的哪一個(gè)都會(huì)觸發(fā)事件,就好像“同一個(gè) GPIO 按鍵有了3個(gè)不同分身”。為什么會(huì)這樣呢?因?yàn)樵谟布B接上,這三個(gè)物理按鍵確實(shí)共用了 GPIO_5 ,所以才有了這個(gè)問(wèn)題。
那么,怎么解決這個(gè)問(wèn)題呢?
就目前來(lái)看,想要區(qū)分 S1,S2 和 User 只能從電氣特性來(lái)入手了,根據(jù)上圖中黃色下劃線處的提示翻看原理圖《HiSpark_WiFi_IoT_OLED_VER.A》,可以發(fā)現(xiàn) S1 和 S2 的連接如下:
明顯可知:S1 和 S2 按下之后紅框位置 switch 處的電壓肯定會(huì)發(fā)生變化,并且 S1 按下后的電壓與 S2 按下后的電壓不同。
所以,可以考慮通過(guò)檢測(cè)電壓的方式來(lái)判斷究竟哪個(gè)鍵被按下了!!
看起來(lái)是不是有點(diǎn)瘋狂!然而,確實(shí)可以這么解決問(wèn)題。
通過(guò)實(shí)驗(yàn)發(fā)現(xiàn)這 3 個(gè)物理按鍵按下后的電壓范圍大致如下:
并且,通過(guò)查閱文檔《Hi3861V100/Hi3861LV100 設(shè)備驅(qū)動(dòng) 開發(fā)指南》中的第 5 章可以找到讀取 ADC 值的 API 接口,以及 ADC 值到電壓值的轉(zhuǎn)換公式:
問(wèn)題:ADC 是什么?
ADC 指的是 analog-to-Digital Convertor,即:模/數(shù)轉(zhuǎn)換器。
在這個(gè)問(wèn)題中,3 個(gè)物理按鍵的電壓模擬值會(huì)被 ADC 轉(zhuǎn)換為數(shù)字值(ADC值),并且電壓值和 ADC 值是單純的線性轉(zhuǎn)換關(guān)系,所以,
通過(guò)檢測(cè) ADC 值的變化就可以判斷被按下的物理按鍵。
將表一中的電壓范圍通過(guò)公式轉(zhuǎn)換為 ADC 范圍:
有了這張表之后,離解決問(wèn)題就更近了一步,接下來(lái)看看相關(guān) API 接口的示例:
調(diào)用 hi_adc_read() 讀取通道7的 ADC 值。
函數(shù) hi_adc_read() 第一個(gè)參數(shù)用于指定需要讀取的 ADC 通道,第二個(gè)參數(shù)用于保存讀取的 ADC 值。
對(duì)于我們這個(gè)問(wèn)題來(lái)說(shuō),
最關(guān)鍵的就是要知道 GPIO_5 對(duì)應(yīng)的 ADC 通道是哪一個(gè)。這時(shí)可以查閱文檔《Hi3861V100/Hi3861LV100/Hi3881V100 WiFi芯片 用戶指南》,在第 6 章中可以找到下面的表格:
表6-2中紅框部分的對(duì)應(yīng)關(guān)系指出:由于 Hi3861 數(shù)字管腳有限,故 GPIO_5 與 ADC_2 復(fù)用同一管腳。
So! 在代碼層面,可以通過(guò) hi_adc_read() 讀取 HI_ADC_CHANNEL_2 處的 ADC 值,進(jìn)而判斷 S1,S2,User 中被按下的按鍵。
OK!所有障礙已被掃清,這時(shí)可以用代碼描述了:
很顯然,每次調(diào)用 GetSSU() 即可知道是否有鍵被按下,以及具體哪個(gè)鍵被按下。
看到此處,問(wèn)題已徹底解決!
PS:所查閱的文檔以及最終示例代碼均可在附件中下載。
Enjoy it! |
|