FlexibleButton:一個輕巧靈活的按鍵處理庫,讓你的按鍵處理更簡單

? ? ? ? ?在嵌入式系統開發中,按鍵輸入處理是一個常見且重要的環節。然而,許多開發者在處理按鍵時,往往會遇到按鍵消抖、組合按鍵、長按/短按等功能實現的復雜性。如何在保證系統高效運行的同時,簡化按鍵事件的處理呢?

? ? ? ? ?今天,我們向大家介紹一個小巧而靈活的按鍵處理庫——FlexibleButton。它基于標準 C 語言,簡單易用,卻具備強大的功能,可以讓你輕松實現按鍵事件的各種處理需求。

一、FlexibleButton的核心特性

  1. 單擊、連擊、短按、長按、自動消抖:
    FlexibleButton 支持多種常見的按鍵事件:單擊、連擊、短按、長按,甚至自動消抖機制。無論你的按鍵設計復雜還是簡單,它都能幫你高效處理。

  2. 靈活的按鍵組合:
    如果你的系統需要支持多個按鍵的組合,FlexibleButton 提供了靈活的組合按鍵設置。用戶可以自由配置按鍵組合并通過回調函數處理事件,非常方便。

  3. 解耦硬件設計:
    FlexibleButton 的設計解耦了具體的按鍵硬件結構,使得它可以支持各種類型的按鍵,包括輕觸按鍵和自鎖按鍵。無論你采用什么硬件架構,FlexibleButton 都能輕松適配。

  4. 按鍵數量的無限擴展:
    FlexibleButton 的架構支持按鍵數量的擴展,理論上,你可以根據需求無限增加按鍵數量,而不需要擔心性能下降或庫的復雜性增加。

  5. 低功耗和中斷支持:
    在低功耗和中斷場景下,FlexibleButton 也能發揮重要作用。它支持通過中斷方式來處理按鍵事件,保證系統在低功耗狀態下也能高效工作。

  6. 簡單的按鍵掃描:
    FlexibleButton 的按鍵掃描機制非常簡潔,僅需三行代碼就能完成所有按鍵狀態的讀取。無論你使用的是哪種平臺,三行按鍵掃描算法都能讓你迅速上手。

二、核心設計:三行按鍵掃描

FlexibleButton 的高效性源于其簡潔的設計:三行按鍵掃描算法。這一設計使得按鍵狀態的讀取和事件處理變得異常簡潔和高效。


for (int i = 0; i < BUTTON_COUNT; i++) {button_state[i] = read_button_state(i);  // 讀取當前按鍵狀態if (button_state[i] != previous_state[i]) {handle_button_event(i, button_state[i]);  // 處理按鍵事件}
}

這三行代碼簡潔明了,充分體現了FlexibleButton的高效性和簡易性。通過這種掃描方式,我們可以一次性讀取所有按鍵的狀態,并通過回調機制處理每個按鍵的狀態變化。

(1)確定用戶按鍵


typedef enum
{USER_BUTTON_0 = 0, // 對應 IoT Board 開發板的 PIN_KEY0USER_BUTTON_1,     // 對應 IoT Board 開發板的 PIN_KEY1USER_BUTTON_2,     // 對應 IoT Board 開發板的 PIN_KEY2USER_BUTTON_3,     // 對應 IoT Board 開發板的 PIN_WK_UPUSER_BUTTON_MAX
} user_button_t;static flex_button_t user_button[USER_BUTTON_MAX];

上述代碼定義了 4 個按鍵,數據結構存儲在?user_button?數組中。

(2)程序入口


int flex_button_main(void)
{rt_thread_t tid = RT_NULL;user_button_init();/* 創建按鍵掃描線程 flex_btn,線程棧 1024 byte,優先級 10 */tid = rt_thread_create("flex_btn", button_scan, RT_NULL, 1024, 10, 10);if(tid != RT_NULL){rt_thread_startup(tid);}return 0;
}
/* 使用 RT-Thread 的自動初始化 */
INIT_APP_EXPORT(flex_button_main);

如上代碼所示,首先使用user_button_init();?初始化用戶按鍵硬件,該步驟將用戶按鍵綁定到FlexibleButton 庫。然后,使用 RT-Thread 的?INIT_APP_EXPORT?接口導出為上電自動初始化,創建了一個“flex_btn” 名字的按鍵掃描線程,線程里掃描檢查按鍵事件。

(3)按鍵初始化代碼

? ?user_button_init();?初始化代碼如下所示:

static void user_button_init(void)
{int i;/* 初始化按鍵數據結構 */rt_memset(&user_button[0], 0x0, sizeof(user_button));/* 初始化 IoT Board 按鍵引腳,使用 rt-thread PIN 設備框架 */rt_pin_mode(PIN_KEY0, PIN_MODE_INPUT_PULLUP);    /* 設置 GPIO 為上拉輸入模式 */rt_pin_mode(PIN_KEY1, PIN_MODE_INPUT_PULLUP);    /* 設置 GPIO 為上拉輸入模式 */rt_pin_mode(PIN_KEY2, PIN_MODE_INPUT_PULLUP);    /* 設置 GPIO 為上拉輸入模式 */rt_pin_mode(PIN_WK_UP, PIN_MODE_INPUT_PULLDOWN); /* 設置 GPIO 為下拉輸入模式 */for (i = 0; i < USER_BUTTON_MAX; i ++){user_button[i].id = i;user_button[i].usr_button_read = common_btn_read;user_button[i].cb = common_btn_evt_cb;user_button[i].pressed_logic_level = 0;user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(1500);user_button[i].long_press_start_tick = FLEX_MS_TO_SCAN_CNT(3000);user_button[i].long_hold_start_tick = FLEX_MS_TO_SCAN_CNT(4500);if (i == USER_BUTTON_3){user_button[USER_BUTTON_3].pressed_logic_level = 1;}flex_button_register(&user_button[i]);}
}

核心的配置如下:

配置項

說明

id

按鍵編號

usr_button_read

設置按鍵讀值回調函數

cb

設置按鍵事件回調函數

pressed_logic_level

設置按鍵按下時的邏輯電平

short_press_start_tick

短按起始 tick,使用 FLEX_MS_TO_SCAN_CNT 宏轉化為掃描次數

long_press_start_tick

長按起始 tick,使用 FLEX_MS_TO_SCAN_CNT 宏轉化為掃描次數

long_hold_start_tick

超長按起始 tick,使用 FLEX_MS_TO_SCAN_CNT 宏轉化為掃描次數

注意,short_press_start_tick、long_press_start_tick 和 long_hold_start_tick 必須使用?FLEX_MS_TO_SCAN_CNT?將毫秒時間轉化為掃描次數。

user_button[i].short_press_start_tick = FLEX_MS_TO_SCAN_CNT(1500);?表示按鍵按下開始計時,1500 ms 后按鍵依舊是按下狀態的話,就斷定為短按開始。

(4)事件處理代碼


static void common_btn_evt_cb(void *arg)
{flex_button_t *btn = (flex_button_t *)arg;rt_kprintf("id: [%d - %s]  event: [%d - %30s]  repeat: %d\n", btn->id, enum_btn_id_string[btn->id],btn->event, enum_event_string[btn->event],btn->click_cnt);if (flex_button_event_read(&user_button[USER_BUTTON_0]) == flex_button_event_read(&user_button[USER_BUTTON_1]) == FLEX_BTN_PRESS_CLICK){rt_kprintf("[combination]: button 0 and button 1\n");}
}

示例代碼中,將所有的按鍵事件回調均綁定到?common_btn_evt_cb?函數,在該函數中打印了按鍵 ID 和按鍵事件,以及按鍵連擊次數,并演示了如何使用組合按鍵。

三、適用場景

FlexibleButton 的適用場景非常廣泛,特別適合以下幾類項目:

  • 低功耗嵌入式系統:

    ?通過中斷和按鍵消抖機制,能夠在低功耗模式下高效工作。

  • 復雜按鍵輸入場景:

    ?支持組合按鍵、長按/短按等多種按鍵事件。

  • 跨平臺開發:

    ?基于標準 C 語言,支持各種硬件平臺和操作系統,甚至是裸機系統。

  • 實時按鍵響應需求:

    ?通過事件回調機制,保證按鍵事件能夠快速響應并處理。

四、為何選擇FlexibleButton?

  • 小巧而高效:

    ?相較于其他按鍵處理庫,FlexibleButton 不僅小巧,還具有極高的處理效率,非常適合嵌入式系統中的資源受限場景。

  • 易于集成:

    ?由于使用了標準 C 語言 API,FlexibleButton 可以無縫集成到各種處理器平臺和操作系統中,不需要額外的依賴。

  • 可擴展性強:

    ?它的架構設計讓你可以根據需求自由添加更多按鍵,且不會增加過多的復雜度。

  • 支持事件回調:

    ?靈活的事件回調機制可以讓你更直觀地處理各種按鍵事件,增強系統的響應速度和可維護性。

? ? 無論是簡單的按鍵控制,還是復雜的多按鍵組合,FlexibleButton?都能幫助你輕松應對。它的高效性、靈活性和易用性使得它在嵌入式開發中成為理想的按鍵處理方案。通過FlexibleButton,你可以專注于業務邏輯的實現,而不必為按鍵處理的復雜性煩惱。

立即嘗試 FlexibleButton,讓你的按鍵輸入處理更簡單、更高效!https://github.com/murphyzhao/FlexibleButton

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904340.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904340.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904340.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

探索程序員薪資背后的秘密與未來:智能化工具如何助力職場發展

最新接入DeepSeek-V3模型&#xff0c;點擊下載最新版本InsCode AI IDE 探索程序員薪資背后的秘密與未來&#xff1a;智能化工具如何助力職場發展 引言 在當今數字化時代&#xff0c;程序員作為科技發展的核心力量&#xff0c;其職業前景和薪資水平備受關注。隨著人工智能和自…

【STM32單片機】#14 PWR電源控制

主要參考學習資料&#xff1a; B站江協科技 STM32入門教程-2023版 細致講解 中文字幕 開發資料下載鏈接&#xff1a;https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 單片機套裝&#xff1a;STM32F103C8T6開發板單片機C6T6核心板 實驗板最小系統板套件科協 目錄 PWR…

第十五屆藍橋杯單片機國賽-串口解析

串口通信像是藍橋杯單片機組國賽中一個若隱若現的秘境&#xff0c;總在不經意間為勇者們敞開大門。然而&#xff0c;初次探索這片領域的冒險者&#xff0c;常常會被其神秘莫測的特性所震懾&#xff0c;黯然退場&#xff08;編不下去了&#xff0c;直接進入正題&#xff09;。 附…

深入探索 51 單片機:從入門到實踐的全面指南

深入探索 51 單片機&#xff1a;從入門到實踐的全面指南 一、引言 在嵌入式系統發展的漫長歷程中&#xff0c;51 單片機猶如一顆璀璨的明星&#xff0c;雖然誕生已有數十年&#xff0c;但至今仍在眾多領域發揮著重要作用。它以結構簡單、易于學習、成本低廉等優勢&#xff0c…

GD32F470+CH395Q

第一步&#xff1a;資料下載 以太網協議棧芯片 CH395 - 南京沁恒微電子股份有限公司 第二步&#xff1a;準備工程 &#xff08;1&#xff09; 首先準備一個編譯無報錯、可以正常打印和延時的工程文件&#xff0c;官方例程采用STM32F1芯片&#xff0c;但本文采用GD32F470芯片 …

Linux 怎么使用局域網內電腦的網絡訪問外部

一次性 export http_proxy"http://192.168.0.188:7890" export https_proxy"http://192.168.0.188:7890"一直生效 寫入 ~/.bashrc&#xff08;或 ~/.bash_profile&#xff09; nano ~/.bashrc加入這一行&#xff1a; export http_proxy"http://19…

Mysql進階篇1_存儲引擎、索引、SQL性能分析指令

文章目錄 1.存儲引擎InnoDBMyISAMMemory存儲引擎選擇和對比 2.索引索引結構索引分類索引語法索引使用&#xff08;建議看完第3節后觀看&#xff09;&#xff01;&#xff01;&#xff01;mysql如何使用索引查詢數據&#xff08;個人理解&#xff09; 3.SQL性能分析SQL執行頻率慢…

LeetCode 熱題 100 118. 楊輝三角

LeetCode 熱題 100 | 118. 楊輝三角 大家好&#xff0c;今天我們來解決一道經典的算法題——楊輝三角。這道題在 LeetCode 上被標記為簡單難度&#xff0c;要求生成楊輝三角的前 numRows 行。楊輝三角是一個經典的組合數學問題&#xff0c;每一行的數字都是其正上方和正左上方…

修改或禁用Cursor的全局搜索默認快捷鍵

在 Cursor 中&#xff0c;默認情況下 雙擊 Shift 會打開 全局搜索&#xff08;Quick Open&#xff09;&#xff0c;類似于 VS Code 的 CtrlP 功能。如果你想修改或禁用這個快捷鍵&#xff0c;可以按照以下步驟操作&#xff1a; 1. 打開快捷鍵設置 方法 1&#xff1a;按下 Ctrl…

HarmonyOS Device Connector(hdc)

它是為開發人員提供的用于調試的命令行工具&#xff0c;通過該工具可以在windows/linux/mac系統上與設備進行交互。 hdc分為三部分&#xff1a; client&#xff1a;運行在電腦端的進程&#xff0c;開發者在執行hdc命令時啟動該進程&#xff0c;命令結束后進程退出。 server&…

開源PDF解析工具Marker深度解析

開源PDF解析工具Marker深度解析 檢索增強生成&#xff08;RAG&#xff09;系統的第一步就是做 pdf 解析&#xff0c;從復雜多樣的 pdf 中提取出干凈準確的文本內容。現有的最優秀的開源工具有兩個&#xff1a;Marker 和 MinerU。因為 Marker 是個人開發者做的&#xff0c;文檔…

ARM子程序調用與返回

子程序&#xff08;也叫過程、函數、方法&#xff09;是一個能被調用和執行并返回到調用點那條指令的代碼 段。 兩個問題&#xff1a;如何將參數傳遞給子程序或從子程序中傳遞出來&#xff1f;怎么從子程序返回到調用點&#xff1f; 指令BSR Proc_A調用子程序Proc_A。 處理器將…

算力經濟模型推演:從中心化到去中心化算力市場的轉變(區塊鏈+智能合約的算力交易原型設計)

一、算力經濟的歷史脈絡與范式轉移 1.1 中心化算力市場的演進困境 傳統算力市場以超算中心、云計算平臺為核心載體&#xff0c;其運營模式呈現強中心化特征。中國移動構建的"四算融合"網絡雖實現百萬級服務器的智能調度&#xff0c;但動態資源分配仍受制于集中式控…

小結: 接口類型和路由優先級

網絡接口類型 1. Bridge-if&#xff08;橋接接口&#xff09; 作用&#xff1a;用于橋接網絡&#xff0c;將多個接口或VLAN連接為一個廣播域&#xff0c;實現二層數據轉發。 常用指令&#xff1a; interface bridge-if <number> bridge <bridge-id> # 將接口加入…

mysql一些事

一.聯合查詢/多表查詢 聯合查詢關鍵在于笛卡爾積的過程 笛卡爾坐標積的排列組合 首先它會將兩個表用排列組合的方式進行排列組合。 表一 表二 進行排列組合 我們發現它的行是 兩個表的行相乘&#xff0c;列是兩表的列相加。 我們所看到的數據有合理的也有不合理的我們接下…

【工具】Open WebUI:本地化部署的AI交互平臺

文章目錄 一、Open WebUI 簡介二、核心功能詳解1. 多模型與多模態支持2. 本地RAG與文檔集成3. 開發與定制化能力4. 安全與權限管理5. 用戶體驗優化 三、安裝與部署指南1. 快速安裝方式2. 高級配置3. 常見問題 四、實際應用場景1. 個人隱私助手2. 企業知識庫3. 學術研究4. 創意工…

AutoGPT

一、簡介 是一個基于openAI研發的GPT4模型的一個開源應用程序&#xff0c;根據用戶指定的目標&#xff0c;自動生成所需的提示&#xff0c;并且執行需要多個步驟才能完成的項目&#xff0c;整個過程不需要人類干預和指導&#xff08;無監督學習&#xff09;&#xff0c;生成式…

[C++] 小游戲 決戰蒼穹

大家好&#xff0c;各位看到這個標題&#xff0c;斗破蒼穹什么時候改叫決戰蒼穹了&#xff1f;其實&#xff0c;因為版權等一系列問題&#xff0c;斗破蒼穹正式改名為決戰蒼穹&#xff0c;這個版本主要更新內容為解決了皇冠競技場太過影響游戲平衡&#xff0c;并且提高了一些裝…

Spring的數據庫編程

本內容采用最新SpringBoot3框架版本,視頻觀看地址:B站視頻播放 1. JdbcTemplate概述 針對數據庫操作,Spring框架提供了JdbcTemplate類,JdbcTemplate是一個模板類,Spring JDBC中的更高層次的抽象類均在JdbcTemplate模板類的基礎上創建。 JdbcTemplate類提供了操作數據庫…

Debezium MySqlValueConverters詳解

Debezium MySqlValueConverters詳解 1. 類的作用與功能 1.1 核心作用 MySqlValueConverters是Debezium中負責MySQL數據類型轉換的核心類,主要功能包括: 數據類型映射:將MySQL的數據類型映射到Kafka Connect的Schema類型值轉換:將MySQL的原始值轉換為Kafka Connect可用的…