本文來源電子發燒友社區,作者:juby, 帖子地址:https://bbs.elecfans.com/jishu_2010914_1_1.html
長按、短按的應用

GpioInit();
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_IO_FUNC_GPIO_5_GPIO);
GpioSetDir(WIFI_IOT_GPIO_IDX_5, WIFI_IOT_GPIO_DIR_IN);
//IoSetPull(WIFI_IOT_IO_NAME_GPIO_5,WIFI_IOT_IO_PULL_UP);
if (ret != WIFI_IOT_SUCCESS) {
printf("===== ERROR ======gpio -> GpioSetDir ret:%drn", ret);
return;
}
ret = GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_5,WIFI_IOT_INT_TYPE_EDGE,WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, gpio5_isr_func, NULL);
if (ret != WIFI_IOT_SUCCESS) {
printf("===== ERROR ======gpio -> hi_gpio_register_isr_function ret:%drn", ret);
}
初始化定時器
if (ret != HI_ERR_SUCCESS)
{
printf("timer create failrn");
}
printf("timer create successrn");
void gpio5_isr_func(char *arg)
{
(void)arg;
//臨時取消GPIO_5的中斷響應
GpioUnregisterIsrFunc(WIFI_IOT_GPIO_IDX_5);
printf("----- gpio05 isr success -----rn");
hi_u32 ret = 0;
//啟動定時器
ret = hi_timer_start(g_timer_handle, HI_TIMER_TYPE_PERIOD, 10, app_demo_timer_handle, 0);
if (ret != HI_ERR_SUCCESS)
{
printf("timer start failrn");
}
printf("timer start successrn");
}
* type,定時器類型。
* expire,定時器超時時間(單位:ms)。配置為0時,默認為10ms。
* timer_func,定時器回調函數。
* data,回調函數傳參。
*
* 返回值0,代表操作成功,
* 其他代表失敗, 具體定義詳見: hi_errno.h。
*
* 依賴:hi_timer.h:文件用于描述定時器相關接口。
* 定時器停止使用 hi_timer_stop() 函數。
*/
hi_u32 hi_timer_start(hi_u32 timer_handle, hi_timer_type type, hi_u32 expire,
hi_timer_callback_f timer_func, hi_u32 data);
定時器回調函數
{
hi_unref_param(data);
hi_u32 ret = 0;
//定時器計數+1
nCurrentTimerCount++;
//每一秒打印一次日志,方便調試
if((nCurrentTimerCount % 100) == 0)
printf("count = %d rn",nCurrentTimerCount);
WifiIotGpioValue wigv;
//獲取GPIO_5的狀態
GpioGetInputVal(WIFI_IOT_IO_NAME_GPIO_5,&wigv);
if (wigv == WIFI_IOT_GPIO_VALUE0)
{
//按鍵尚未釋放
}
else
{
//停止定時器
ret = hi_timer_stop(g_timer_handle);
if (ret != HI_ERR_SUCCESS)
{
printf("timer stop failrn");
}
else
{
printf("app demo timer stop , count = %d rn",nCurrentTimerCount);
//根據按鍵持續時間判斷此次按鍵操作為長按還是短按
if (nCurrentTimerCount > 600)
{
nCurrentTimerCount = 0;
printf("long long press key rn");
}
else if (nCurrentTimerCount > 200)
{
nCurrentTimerCount = 0;
printf("long press key rn");
}
else if (nCurrentTimerCount > 4)
{
nCurrentTimerCount = 0;
printf("short press key rn");
}
}
//恢復GPIO_5的中斷響應
ret = GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_5,WIFI_IOT_INT_TYPE_EDGE,WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, gpio5_isr_func, NULL);
}
}
結果展示

資料獲取
長按、短按的應用
我們之前在下面網文中介紹過了ESP8266模塊的配網:
Windows下AliOS Things環境搭建及ESP8266 固件下載
固件使用AliOS Things固件的ESP8266模塊進行配網的時候,文中是這么操作的:
使用一個跳線,先把D5(GPIO14)接GND,再接3.3V,出現如下Log即進入配網模式:

這個過程其實就是模擬了一個按鍵長按過程。
長按、短按的原理
我們學習嵌入式要學習其原理,原理學會了,其他平臺下相同功能的實現也就會了。
通過閱讀AliOS Things 3.0的源碼,其中按鍵狀態判斷的過程如下:
源文件: platform/mcu/esp8266/bsp/key.c


上述過程簡單描述過程如下:
- 按鍵對應的GPIO中斷函數中,開啟定時器;
- 定時器響應函數中,循環判斷此GPIO的狀態。當按鍵仍為按下狀態時,定時計數+1;如果按鍵變為了釋放狀態,則停止定時器,計算按鍵被按下狀態總的持續時間;
-
根據時間長短進而判斷出此次按鍵為長按還是短按,進而可以實現一個按鍵對應多個不同功能。
這種驅動方式跟下面按鍵驅動方式有明顯的優勢:
基于鴻蒙OS的按鍵驅動
此方法優點:天然去抖動,不用延時等待按鍵狀態改變,程序運行效率大大提高。
鴻蒙系統實現單個按鍵的長按和短按
參考上面原理,我們實現一個鴻蒙系統下的按鍵長按和短按判斷。
初始化GPIO中斷
在入口函數SYS_RUN(KeyExampleEntry);中,將GPIO_5設置為下降沿觸發中斷:
hi_u32 ret = 0;GpioInit();
IoSetFunc(WIFI_IOT_IO_NAME_GPIO_5, WIFI_IOT_IO_FUNC_GPIO_5_GPIO);
GpioSetDir(WIFI_IOT_GPIO_IDX_5, WIFI_IOT_GPIO_DIR_IN);
//IoSetPull(WIFI_IOT_IO_NAME_GPIO_5,WIFI_IOT_IO_PULL_UP);
if (ret != WIFI_IOT_SUCCESS) {
printf("===== ERROR ======gpio -> GpioSetDir ret:%drn", ret);
return;
}
ret = GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_5,WIFI_IOT_INT_TYPE_EDGE,WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, gpio5_isr_func, NULL);
if (ret != WIFI_IOT_SUCCESS) {
printf("===== ERROR ======gpio -> hi_gpio_register_isr_function ret:%drn", ret);
}
初始化定時器
在入口函數SYS_RUN(KeyExampleEntry);中創建定時器:
ret = hi_timer_create(&g_timer_handle); if (ret != HI_ERR_SUCCESS)
{
printf("timer create failrn");
}
printf("timer create successrn");
在GPIO_5的中斷處理函數中,使用hi_timer_start()函數開啟定時器。
/* gpio callback func */void gpio5_isr_func(char *arg)
{
(void)arg;
//臨時取消GPIO_5的中斷響應
GpioUnregisterIsrFunc(WIFI_IOT_GPIO_IDX_5);
printf("----- gpio05 isr success -----rn");
hi_u32 ret = 0;
//啟動定時器
ret = hi_timer_start(g_timer_handle, HI_TIMER_TYPE_PERIOD, 10, app_demo_timer_handle, 0);
if (ret != HI_ERR_SUCCESS)
{
printf("timer start failrn");
}
printf("timer start successrn");
}
定時器開始函數定義如下:
* timer_handle,定時器句柄。* type,定時器類型。
* expire,定時器超時時間(單位:ms)。配置為0時,默認為10ms。
* timer_func,定時器回調函數。
* data,回調函數傳參。
*
* 返回值0,代表操作成功,
* 其他代表失敗, 具體定義詳見: hi_errno.h。
*
* 依賴:hi_timer.h:文件用于描述定時器相關接口。
* 定時器停止使用 hi_timer_stop() 函數。
*/
hi_u32 hi_timer_start(hi_u32 timer_handle, hi_timer_type type, hi_u32 expire,
hi_timer_callback_f timer_func, hi_u32 data);
定時器回調函數
在定時器回調函數中,循環判斷GPIO_5的狀態,只要按鍵沒有釋放,就講計數器自加,每增加1,代表10ms,當按鍵釋放之后,停止計時,最終根據定時器長度來判斷此次按鍵的長短。
static hi_void app_demo_timer_handle(hi_u32 data){
hi_unref_param(data);
hi_u32 ret = 0;
//定時器計數+1
nCurrentTimerCount++;
//每一秒打印一次日志,方便調試
if((nCurrentTimerCount % 100) == 0)
printf("count = %d rn",nCurrentTimerCount);
WifiIotGpioValue wigv;
//獲取GPIO_5的狀態
GpioGetInputVal(WIFI_IOT_IO_NAME_GPIO_5,&wigv);
if (wigv == WIFI_IOT_GPIO_VALUE0)
{
//按鍵尚未釋放
}
else
{
//停止定時器
ret = hi_timer_stop(g_timer_handle);
if (ret != HI_ERR_SUCCESS)
{
printf("timer stop failrn");
}
else
{
printf("app demo timer stop , count = %d rn",nCurrentTimerCount);
//根據按鍵持續時間判斷此次按鍵操作為長按還是短按
if (nCurrentTimerCount > 600)
{
nCurrentTimerCount = 0;
printf("long long press key rn");
}
else if (nCurrentTimerCount > 200)
{
nCurrentTimerCount = 0;
printf("long press key rn");
}
else if (nCurrentTimerCount > 4)
{
nCurrentTimerCount = 0;
printf("short press key rn");
}
}
//恢復GPIO_5的中斷響應
ret = GpioRegisterIsrFunc(WIFI_IOT_GPIO_IDX_5,WIFI_IOT_INT_TYPE_EDGE,WIFI_IOT_GPIO_EDGE_FALL_LEVEL_LOW, gpio5_isr_func, NULL);
}
}
結果展示

資料獲取
公眾號留言區置頂留言獲取本文對應示例源碼。
ps: 文章首發于電子發燒友。
歡迎關注
程序員小哈帶你玩轉嵌入式,微信搜索:嵌入式從0到1,更多干貨等著你。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
wi-fi
+關注
關注
15文章
2424瀏覽量
129558 -
HarmonyOS
+關注
關注
80文章
2153瀏覽量
36053 -
HiSpark
+關注
關注
1文章
156瀏覽量
7757
發布評論請先 登錄
相關推薦
熱點推薦
技術資訊 I Wi-Fi 模塊設計
本文要點Wi-Fi模塊設計旨在打造一套緊湊且高效的硬件和軟件解決方案,使設備能夠通過Wi-Fi網絡實現通信。Wi-Fi模塊設計是一個復雜的過程,要求研發人員兼具硬件與軟件工程方面的專業
ESP32 Wi-Fi 控制 LED 燈的原理
在智能家居、物聯網設備中,用手機通過Wi-Fi控制燈光、風扇或插座,已經非常普遍。而在嵌入式開發中,ESP32是最常用的Wi-Fi模塊之一。本文將帶你系統理解:ESP32是如何通過Wi-Fi
Wi-Fi:無線連接的全球通用語
一、什么是Wi-Fi?Wi-Fi是Wi-Fi聯盟制造商的商標認證,是基于IEEE 802.11標準的無線局域網技術。它允許電子設備在特定范圍內無線接入網絡,實現高速數據交換與互聯網訪問
發表于 01-07 09:49
Nordic發布nRF7002 EBII 開發板, 支持Wi-Fi 6, 解鎖nRF54L新玩法
和 5 GHz)以及高級 Wi-Fi 6 功能,例如目標喚醒時間 (TWT)、OFDMA 和 BSS 著色,從而實現高效、無干擾的電池供電運行。它采用雙頻芯片天線,確保在各個 Wi-Fi 頻段上都能提供
發表于 12-10 11:58
淺談Wi-Fi 6E與Wi-Fi 7的關鍵器件——BAW濾波器新技術
作者: Qorvo 亞太區無線連接事業部高級行銷經理林健富 ? 2020年1月,Wi-Fi聯盟正式宣布開放6GHz頻段(5925MHz-7125MHz),并將其命名為Wi-Fi 6E。2020年4月
發表于 09-19 18:29
?2128次閱讀
解讀Nordic基于SSID的Wi-Fi定位解決方案
,與 nRF91 系列蜂窩物聯網模組配合使用,可實現基于 SSID 的 Wi-Fi 定位。Nordic基于SSID的Wi-Fi定位可以在室內和室外、城市和郊區以極其省電的方式獲取精確的位置信息。這是對全球導航衛星
基于 SSID 的 Wi-Fi 定位:與其他定位服務的性能比較
,與 nRF91 系列蜂窩物聯網模組配合使用,可實現基于 SSID 的 Wi-Fi 定位。Nordic基于SSID的Wi-Fi定位可以在室內和室外、城市和郊區以極其省電的方式獲取精確的位置信息。這是對全球
發表于 08-31 21:01
LitePoint Wi-Fi測試軟件減輕客戶設計負擔
自Wi-Fi 7于一年多前獲得Wi-Fi聯盟認證以來,作為最新一代通信技術,Wi-Fi正逐步成為用戶實現無所不在無線連接的新選擇。隨著每一代Wi-F
【HarmonyOS 5】金融應用開發鴻蒙組件實踐
原生鴻蒙操作系統星河版,面向開發者開放申請,余承東宣布鴻蒙生態設備數達 8 億臺;建設銀行、郵儲銀行等完成鴻蒙原生應用 Beta 版本開發。 2024 年 10 月 22 日:
基于 Wi-Fi 的定位服務
以下捕獲使用 location_wifi_get 函數請求 Wi-Fi 定位服務。該事件的總功耗為 125.85mC,日志顯示精確度為 30.0m。
Got location:
method
發表于 04-17 15:16
nRF Cloud Wi-Fi 定位服務
中實現高性能和超低功耗。對于 Wi-Fi 定位請求,nRF Cloud 可借助 Wi-Fi 數據庫計算設備位置,該數據庫包含不同 Wi-Fi 網絡的坐標。然后,設備位置將從 nRF C
發表于 04-17 15:07
Wi-Fi 定位服務
的 Wi-Fi 網絡數據庫進行比較。
Wi-Fi 定位系統包含以下關鍵組件:
用戶設備中的 Wi-Fi 無線電設備,用于檢測附近的網絡。
將 MAC 地址等
發表于 04-17 15:01
推出了期待已久的 nRF7002 低功耗Wi-Fi 6
系統級芯片(SoC)以及nRF91?系列蜂窩物聯網系統級封裝(SiP)一起使用。nRF7002 還可以與非Nordic主機設備結合使用。
nRF7002是我們獨特的Wi-Fi產品組合中的第一款設備,它將
發表于 03-26 11:00
nRF7002是我們獨特的Wi-Fi產品組合中的第一款設備
?和nRF53?系列藍牙系統級芯片(SoC)以及nRF91?系列蜂窩物聯網系統級封裝(SiP)一起使用。nRF7002 還可以與非Nordic主機設備結合使用。
nRF7002是我們獨特的Wi-Fi
發表于 03-10 15:42
【HarmonyOS HiSpark Wi-Fi IoT 套件試用連載】基于鴻蒙操作系統的單個按鍵長按、短按的實現
評論