溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

純C語言實現(xiàn)的按鍵驅動Button_drive的實例用法

發(fā)布時間:2021-09-04 09:37:58 來源:億速云 閱讀:153 作者:chen 欄目:互聯(lián)網(wǎng)科技

這篇文章主要講解了“純C語言實現(xiàn)的按鍵驅動Button_drive的實例用法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“純C語言實現(xiàn)的按鍵驅動Button_drive的實例用法”吧!

Button_drive簡介

Button_drive是一個小巧的按鍵驅動,支持單擊、雙擊、長按、連續(xù)觸發(fā)等(后續(xù)可以在按鍵控制塊中添加觸發(fā)事件),理論上可無限量擴展Button,Button_drive采用按鍵觸發(fā)事件回調方式處理業(yè)務邏輯,支持在RTOS中使用,我目前僅在RT-Thread上測試過。 寫按鍵驅動的目的是想要將用戶按鍵邏輯與按鍵處理事件分離,用戶無需處理復雜麻煩的邏輯事件。

Button_drive使用效果

  1. 單擊與長按

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2nhPnwqF-1571148176402)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/1.png?raw=true)]

  1. 雙擊

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-wtGvjTjq-1571148176403)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/2.png?raw=true)]

  1. 連按

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-QUypOh3s-1571148176403)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/3.png?raw=true)]

  1. 連按釋放

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LfsbuM1W-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/4.png?raw=true)]

使用方法

  1. 創(chuàng)建按鍵句柄

Button_t Button1;
Button_t Button2;
  1. 創(chuàng)建按鍵,初始化按鍵信息,包括按鍵名字、按鍵電平檢測函數(shù)接口、按鍵觸發(fā)電平。

  Button_Create("Button1",				//按鍵名字
                &Button1, 				//按鍵句柄
                Read_Button1_Level, 	//按鍵電平檢測函數(shù)接口
                BTN_TRIGGER);		   	//觸發(fā)電平
                
                ......
  1. 按鍵觸發(fā)事件與事件回調函數(shù)鏈接映射,當按鍵事件被觸發(fā)的時候,自動跳轉回調函數(shù)中處理業(yè)務邏輯。

  Button_Attach(&Button1,BUTTON_DOWM,Btn2_Dowm_CallBack);		//按鍵單擊
  Button_Attach(&Button1,BUTTON_DOUBLE,Btn2_Double_CallBack);	//雙擊
  Button_Attach(&Button1,BUTTON_LONG,Btn2_Long_CallBack);		//長按
				
				.......
  1. 周期調用回調按鍵處理函數(shù)即可,建議調用周期20-50ms。

Button_Process();     //需要周期調用按鍵處理函數(shù)

需要用戶實現(xiàn)的 2 個函數(shù):

  • 按鍵電平檢測接口:

uint8_t Read_Button1_Level(void)
{
  return GPIO_ReadInputDataBit(BTN1_GPIO_PORT,BTN1_GPIO_PIN);
}

uint8_t Read_Button2_Level(void)
{
  return GPIO_ReadInputDataBit(BTN2_GPIO_PORT,BTN2_GPIO_PIN);
}

// 這是我在stm32上簡單測試的偽代碼,以實際源碼為準
  • 按鍵邏輯處理

void Btn1_Dowm_CallBack(void *btn)
{
  PRINT_INFO("Button1 單擊!");
}

void Btn1_Double_CallBack(void *btn)
{
  PRINT_INFO("Button1 雙擊!");
}

void Btn1_Long_CallBack(void *btn)
{
  PRINT_INFO("Button1 長按!");
  
  Button_Delete(&Button2);
  PRINT_INFO("刪除Button1");
  Search_Button();
}

特點

Button_drive開放源碼,按鍵控制塊采用數(shù)據(jù)結構方式,按鍵事件采用枚舉類型,確保不會重復,也便于添加用戶需要邏輯,采用宏定義方式定義消抖時間、連按觸發(fā)時間、雙擊時間間隔、長按時間等,便于修改。 同時所有被創(chuàng)建的按鍵采用單鏈表方式連擊,用戶只管創(chuàng)建,無需理會按鍵處理,只需調用Button_Process()即可,在函數(shù)中會自動遍歷所有被創(chuàng)建的按鍵。 支持按鍵刪除操作,用戶無需在代碼中刪除對應的按鍵創(chuàng)建于映射鏈接代碼,也無需刪除關于按鍵的任何回調事件處理函數(shù),只需調用Button_Delete()函數(shù)即可,這樣子,就不會處理關于被刪除按鍵的任何狀態(tài)。當然目前按鍵內存不會釋放,如果使用os的話,建議釋放按鍵內存。

按鍵控制塊
/*
	每個按鍵對應1個全局的結構體變量。
	其成員變量是實現(xiàn)消抖和多種按鍵狀態(tài)所必須的
*/
typedef struct button
{
	/* 下面是一個函數(shù)指針,指向判斷按鍵手否按下的函數(shù) */
	uint8_t (*Read_Button_Level)(void); /* 讀取按鍵電平函數(shù),需要用戶實現(xiàn) */
  
  char Name[BTN_NAME_MAX];
  	
  uint8_t Button_State              :   4;	  /* 按鍵當前狀態(tài)(按下還是彈起) */
  uint8_t Button_Last_State         :   4;	  /* 上一次的按鍵狀態(tài),用于判斷雙擊 */
  uint8_t Button_Trigger_Level      :   2;    /* 按鍵觸發(fā)電平 */
  uint8_t Button_Last_Level         :   2;    /* 按鍵當前電平 */
  
  uint8_t Button_Trigger_Event;     /* 按鍵觸發(fā)事件,單擊,雙擊,長按等 */
  
  Button_CallBack CallBack_Function[number_of_event];
  uint8_t Button_Cycle;	           /* 連續(xù)按鍵周期 */
  
  uint8_t Timer_Count;			/* 計時 */
  uint8_t Debounce_Time;		/* 消抖時間 */
  
  uint8_t Long_Time;		  /* 按鍵按下持續(xù)時間 */
  
  struct button *Next;
  
}Button_t;
觸發(fā)事件
typedef enum {
  BUTTON_DOWM = 0,
  BUTTON_UP,
  BUTTON_DOUBLE,
  BUTTON_LONG,
  BUTTON_CONTINUOS,
  BUTTON_CONTINUOS_FREE,
  BUTTON_ALL_RIGGER,
  number_of_event, /* 觸發(fā)回調的事件 */
  NONE_TRIGGER
}Button_Event;
宏定義選擇
#define BTN_NAME_MAX  32     //名字最大為32字節(jié)

/* 按鍵消抖時間40ms, 建議調用周期為20ms
 只有連續(xù)檢測到40ms狀態(tài)不變才認為有效,包括彈起和按下兩種事件
*/

#define CONTINUOS_TRIGGER             0  //是否支持連續(xù)觸發(fā),連發(fā)的話就不要檢測單雙擊與長按了	

/* 是否支持單擊&雙擊同時存在觸發(fā),如果選擇開啟宏定義的話,單雙擊都回調,只不過單擊會延遲響應,
   因為必須判斷單擊之后是否觸發(fā)了雙擊否則,延遲時間是雙擊間隔時間 BUTTON_DOUBLE_TIME。
   而如果不開啟這個宏定義,建議工程中只存在單擊/雙擊中的一個,否則,在雙擊響應的時候會觸發(fā)一次單擊,
   因為雙擊必須是有一次按下并且釋放之后才產(chǎn)生的 */
#define SINGLE_AND_DOUBLE_TRIGGER     1 

/* 是否支持長按釋放才觸發(fā),如果打開這個宏定義,那么長按釋放之后才觸發(fā)單次長按,
   否則在長按指定時間就一直觸發(fā)長按,觸發(fā)周期由 BUTTON_LONG_CYCLE 決定 */
#define LONG_FREE_TRIGGER             0 

#define BUTTON_DEBOUNCE_TIME 	  2   //消抖時間      (n-1)*調用周期
#define BUTTON_CONTINUOS_CYCLE  1	  //連按觸發(fā)周期時間  (n-1)*調用周期  
#define BUTTON_LONG_CYCLE       1	  //長按觸發(fā)周期時間  (n-1)*調用周期 
#define BUTTON_DOUBLE_TIME      15 	//雙擊間隔時間  (n-1)*調用周期  建議在200-600ms
#define BUTTON_LONG_TIME 	      50		/* 持續(xù)n秒((n-1)*調用周期 ms),認為長按事件 */

#define TRIGGER_CB(event)   \
        if(btn->CallBack_Function[event]) \
          btn->CallBack_Function[event]((Button_t*)btn)
例子
  Button_Create("Button1",
              &Button1, 
              Read_KEY1_Level, 
              KEY_ON);
  Button_Attach(&Button1,BUTTON_DOWM,Btn1_Dowm_CallBack);                       //單擊
  Button_Attach(&Button1,BUTTON_DOUBLE,Btn1_Double_CallBack);                   //雙擊
  Button_Attach(&Button1,BUTTON_CONTINUOS,Btn1_Continuos_CallBack);             //連按  
  Button_Attach(&Button1,BUTTON_CONTINUOS_FREE,Btn1_ContinuosFree_CallBack);    //連按釋放  
  Button_Attach(&Button1,BUTTON_LONG,Btn1_Long_CallBack);                       //長按


  Button_Create("Button2",
              &Button2, 
              Read_KEY2_Level, 
              KEY_ON);
  Button_Attach(&Button2,BUTTON_DOWM,Btn2_Dowm_CallBack);                     //單擊
  Button_Attach(&Button2,BUTTON_DOUBLE,Btn2_Double_CallBack);                 //雙擊
  Button_Attach(&Button2,BUTTON_CONTINUOS,Btn2_Continuos_CallBack);           //連按
  Button_Attach(&Button2,BUTTON_CONTINUOS_FREE,Btn2_ContinuosFree_CallBack);  //連按釋放
  Button_Attach(&Button2,BUTTON_LONG,Btn2_Long_CallBack);                     //長按

  Get_Button_Event(&Button1);
  Get_Button_Event(&Button2);

后續(xù)

流光大佬的要求,讓我玩一玩RTT的rtkpgs,打算用Button_drive練一練手吧。

ButtonDrive在env使用

目前我已將按鍵驅動做成軟件包(packages),如果使用RT-Thread操作系統(tǒng)的話,可以在env中直接配置使用!

步驟如下:

  1. 選擇在線軟件包

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-gG59d3Yn-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/5.png?raw=true)]

  1. 選擇軟件包屬性為外設相關

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-amGYFH8P-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/6.png?raw=true)]

  1. 選擇button_drive

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-O0a0wqdi-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/7.png?raw=true)]

  1. 進入驅動的選項配置(自帶默認屬性)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-O5sGP0CE-1571148176405)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/8.png?raw=true)]

  1. 如果不懂按鍵的配置是什么意思,按下“shift+?”,即可有解釋

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EYxByBVm-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/9.png?raw=true)]

  1. 編譯生成mdk/iar工程

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-e0pdTFhz-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/10.png?raw=true)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-lXNX8VeJ-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/11.png?raw=true)]

關于rtkpgs

簡介 (English)

buildpkg 是用于生成 RT-Thread package 的快速構建工具。

一個優(yōu)秀的 package 應該是這樣的:

  1. 代碼優(yōu)雅, 規(guī)范化。

  2. examples 例程,提供通俗易懂的使用例程。

  3. SConscript 文件,用于和 RT-Thread 環(huán)境一起進行編譯。

  4. README.md 文檔,向用戶提供必要的功能說明。

  5. docs 文件夾, 放置除了 README 之外的其他細節(jié)文檔。

  6. license 許可文件,版權說明。

為了方便快速的生成 RT-Thread package 規(guī)范化模板 以及 減輕開源倉庫遷移 RT-Thread 的前期準備工作的負擔,基于此目的的 buildpkg 應運而生,為開發(fā) Rt-Thread 的 package 的開發(fā)者提供輔助開發(fā)工具。

序號支持功能描述
1構建 package 模板創(chuàng)建指定名稱 package , 自動添加 readme /版本號/ github ci腳本/demo/開源協(xié)議文件
2遷移開源倉庫從指定 git 倉庫構建 package , 自動添加readme/版本號/ github ci腳本/demo/開源協(xié)議文件, 但是遷移的倉庫需要用戶自己按照實際情況修改
3更新 package生成package后可以再次更新之前設定的版本號,開源協(xié)議或者scons腳本等

使用說明

1. 構建package

buildpkg.exe make pkgdemo

2. 遷移開源倉庫

buildpkg.exe make cstring https://github.com/liu2guang/cstring.git

3. 更新package

buildpkg.exe update pkgname

4. 可選配置

長參數(shù)短參數(shù)描述
--version=v1.0.0-v v1.0.0設置 package 的版本
--license=MIT-l MIT設置 package 所遵循的版權協(xié)議
--submodule-s刪除 git 子模塊

Windows10 及 Linux 平臺的演示動圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-CT6Hxh38-1571148176408)(/figures/buildpkg.gif)]

測試平臺

序號測試平臺測試結果
1win10exe測試通過, py測試通過
2win7exe待測試, py待測試
3macpy腳本不知道是否兼容, 沒有測試條件, 后面維護下
4linuxpy腳本不知道是否兼容, 沒有測試條件, 后面維護下

感謝各位的閱讀,以上就是“純C語言實現(xiàn)的按鍵驅動Button_drive的實例用法”的內容了,經(jīng)過本文的學習后,相信大家對純C語言實現(xiàn)的按鍵驅動Button_drive的實例用法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI