這篇文章主要講解了“純C語言實(shí)現(xiàn)的按鍵驅(qū)動Button_drive的實(shí)例用法”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“純C語言實(shí)現(xiàn)的按鍵驅(qū)動Button_drive的實(shí)例用法”吧!
十載的瑞金網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。全網(wǎng)營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整瑞金建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“瑞金網(wǎng)站設(shè)計(jì)”,“瑞金網(wǎng)站推廣”以來,每個客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
Button_drive是一個小巧的按鍵驅(qū)動,支持單擊、雙擊、長按、連續(xù)觸發(fā)等(后續(xù)可以在按鍵控制塊中添加觸發(fā)事件),理論上可無限量擴(kuò)展Button,Button_drive采用按鍵觸發(fā)事件回調(diào)方式處理業(yè)務(wù)邏輯,支持在RTOS中使用,我目前僅在RT-Thread上測試過。 寫按鍵驅(qū)動的目的是想要將用戶按鍵邏輯與按鍵處理事件分離,用戶無需處理復(fù)雜麻煩的邏輯事件。
單擊與長按
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-2nhPnwqF-1571148176402)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/1.png)]
雙擊
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-wtGvjTjq-1571148176403)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/2.png)]
連按
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-QUypOh3s-1571148176403)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/3.png)]
連按釋放
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-LfsbuM1W-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/4.png)]
創(chuàng)建按鍵句柄
Button_t Button1; Button_t Button2;
創(chuàng)建按鍵,初始化按鍵信息,包括按鍵名字、按鍵電平檢測函數(shù)接口、按鍵觸發(fā)電平。
Button_Create("Button1", //按鍵名字 &Button1, //按鍵句柄 Read_Button1_Level, //按鍵電平檢測函數(shù)接口 BTN_TRIGGER); //觸發(fā)電平 ......
按鍵觸發(fā)事件與事件回調(diào)函數(shù)鏈接映射,當(dāng)按鍵事件被觸發(fā)的時(shí)候,自動跳轉(zhuǎn)回調(diào)函數(shù)中處理業(yè)務(wù)邏輯。
Button_Attach(&Button1,BUTTON_DOWM,Btn2_Dowm_CallBack); //按鍵單擊 Button_Attach(&Button1,BUTTON_DOUBLE,Btn2_Double_CallBack); //雙擊 Button_Attach(&Button1,BUTTON_LONG,Btn2_Long_CallBack); //長按 .......
周期調(diào)用回調(diào)按鍵處理函數(shù)即可,建議調(diào)用周期20-50ms。
Button_Process(); //需要周期調(diào)用按鍵處理函數(shù)
需要用戶實(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上簡單測試的偽代碼,以實(shí)際源碼為準(zhǔn)
按鍵邏輯處理
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ù)結(jié)構(gòu)方式,按鍵事件采用枚舉類型,確保不會重復(fù),也便于添加用戶需要邏輯,采用宏定義方式定義消抖時(shí)間、連按觸發(fā)時(shí)間、雙擊時(shí)間間隔、長按時(shí)間等,便于修改。 同時(shí)所有被創(chuàng)建的按鍵采用單鏈表方式連擊,用戶只管創(chuàng)建,無需理會按鍵處理,只需調(diào)用Button_Process()
即可,在函數(shù)中會自動遍歷所有被創(chuàng)建的按鍵。 支持按鍵刪除操作,用戶無需在代碼中刪除對應(yīng)的按鍵創(chuàng)建于映射鏈接代碼,也無需刪除關(guān)于按鍵的任何回調(diào)事件處理函數(shù),只需調(diào)用Button_Delete()
函數(shù)即可,這樣子,就不會處理關(guān)于被刪除按鍵的任何狀態(tài)。當(dāng)然目前按鍵內(nèi)存不會釋放,如果使用os的話,建議釋放按鍵內(nèi)存。
/* 每個按鍵對應(yīng)1個全局的結(jié)構(gòu)體變量。 其成員變量是實(shí)現(xiàn)消抖和多種按鍵狀態(tài)所必須的 */ typedef struct button { /* 下面是一個函數(shù)指針,指向判斷按鍵手否按下的函數(shù) */ uint8_t (*Read_Button_Level)(void); /* 讀取按鍵電平函數(shù),需要用戶實(shí)現(xiàn) */ char Name[BTN_NAME_MAX]; uint8_t Button_State : 4; /* 按鍵當(dāng)前狀態(tài)(按下還是彈起) */ uint8_t Button_Last_State : 4; /* 上一次的按鍵狀態(tài),用于判斷雙擊 */ uint8_t Button_Trigger_Level : 2; /* 按鍵觸發(fā)電平 */ uint8_t Button_Last_Level : 2; /* 按鍵當(dāng)前電平 */ uint8_t Button_Trigger_Event; /* 按鍵觸發(fā)事件,單擊,雙擊,長按等 */ Button_CallBack CallBack_Function[number_of_event]; uint8_t Button_Cycle; /* 連續(xù)按鍵周期 */ uint8_t Timer_Count; /* 計(jì)時(shí) */ uint8_t Debounce_Time; /* 消抖時(shí)間 */ uint8_t Long_Time; /* 按鍵按下持續(xù)時(shí)間 */ struct button *Next; }Button_t;
typedef enum { BUTTON_DOWM = 0, BUTTON_UP, BUTTON_DOUBLE, BUTTON_LONG, BUTTON_CONTINUOS, BUTTON_CONTINUOS_FREE, BUTTON_ALL_RIGGER, number_of_event, /* 觸發(fā)回調(diào)的事件 */ NONE_TRIGGER }Button_Event;
#define BTN_NAME_MAX 32 //名字最大為32字節(jié) /* 按鍵消抖時(shí)間40ms, 建議調(diào)用周期為20ms 只有連續(xù)檢測到40ms狀態(tài)不變才認(rèn)為有效,包括彈起和按下兩種事件 */ #define CONTINUOS_TRIGGER 0 //是否支持連續(xù)觸發(fā),連發(fā)的話就不要檢測單雙擊與長按了 /* 是否支持單擊&雙擊同時(shí)存在觸發(fā),如果選擇開啟宏定義的話,單雙擊都回調(diào),只不過單擊會延遲響應(yīng), 因?yàn)楸仨毰袛鄦螕糁笫欠裼|發(fā)了雙擊否則,延遲時(shí)間是雙擊間隔時(shí)間 BUTTON_DOUBLE_TIME。 而如果不開啟這個宏定義,建議工程中只存在單擊/雙擊中的一個,否則,在雙擊響應(yīng)的時(shí)候會觸發(fā)一次單擊, 因?yàn)殡p擊必須是有一次按下并且釋放之后才產(chǎn)生的 */ #define SINGLE_AND_DOUBLE_TRIGGER 1 /* 是否支持長按釋放才觸發(fā),如果打開這個宏定義,那么長按釋放之后才觸發(fā)單次長按, 否則在長按指定時(shí)間就一直觸發(fā)長按,觸發(fā)周期由 BUTTON_LONG_CYCLE 決定 */ #define LONG_FREE_TRIGGER 0 #define BUTTON_DEBOUNCE_TIME 2 //消抖時(shí)間 (n-1)*調(diào)用周期 #define BUTTON_CONTINUOS_CYCLE 1 //連按觸發(fā)周期時(shí)間 (n-1)*調(diào)用周期 #define BUTTON_LONG_CYCLE 1 //長按觸發(fā)周期時(shí)間 (n-1)*調(diào)用周期 #define BUTTON_DOUBLE_TIME 15 //雙擊間隔時(shí)間 (n-1)*調(diào)用周期 建議在200-600ms #define BUTTON_LONG_TIME 50 /* 持續(xù)n秒((n-1)*調(diào)用周期 ms),認(rèn)為長按事件 */ #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);
流光大佬的要求,讓我玩一玩RTT的rtkpgs,打算用Button_drive練一練手吧。
目前我已將按鍵驅(qū)動做成軟件包(packages),如果使用RT-Thread操作系統(tǒng)的話,可以在env中直接配置使用!
步驟如下:
選擇在線軟件包
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-gG59d3Yn-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/5.png)]
選擇軟件包屬性為外設(shè)相關(guān)
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-amGYFH8P-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/6.png)]
選擇button_drive
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-O0a0wqdi-1571148176404)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/7.png)]
進(jìn)入驅(qū)動的選項(xiàng)配置(自帶默認(rèn)屬性)
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-O5sGP0CE-1571148176405)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/8.png)]
如果不懂按鍵的配置是什么意思,按下“shift+?”,即可有解釋
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-EYxByBVm-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/9.png)]
編譯生成mdk/iar工程
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-e0pdTFhz-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/10.png)]
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-lXNX8VeJ-1571148176407)(https://github.com/jiejieTop/ButtonDrive/blob/master/png/11.png)]
buildpkg 是用于生成 RT-Thread package 的快速構(gòu)建工具。
一個優(yōu)秀的 package 應(yīng)該是這樣的:
代碼優(yōu)雅, 規(guī)范化。
examples 例程,提供通俗易懂的使用例程。
SConscript 文件,用于和 RT-Thread 環(huán)境一起進(jìn)行編譯。
README.md 文檔,向用戶提供必要的功能說明。
docs 文件夾, 放置除了 README 之外的其他細(xì)節(jié)文檔。
license 許可文件,版權(quán)說明。
為了方便快速的生成 RT-Thread package 規(guī)范化模板 以及 減輕開源倉庫遷移 RT-Thread 的前期準(zhǔn)備工作的負(fù)擔(dān),基于此目的的 buildpkg 應(yīng)運(yùn)而生,為開發(fā) Rt-Thread 的 package 的開發(fā)者提供輔助開發(fā)工具。
序號 | 支持功能 | 描述 |
---|---|---|
1 | 構(gòu)建 package 模板 | 創(chuàng)建指定名稱 package , 自動添加 readme /版本號/ github ci腳本/demo/開源協(xié)議文件 |
2 | 遷移開源倉庫 | 從指定 git 倉庫構(gòu)建 package , 自動添加readme/版本號/ github ci腳本/demo/開源協(xié)議文件, 但是遷移的倉庫需要用戶自己按照實(shí)際情況修改 |
3 | 更新 package | 生成package后可以再次更新之前設(shè)定的版本號,開源協(xié)議或者scons腳本等 |
buildpkg.exe make pkgdemo
buildpkg.exe make cstring https://github.com/liu2guang/cstring.git
buildpkg.exe update pkgname
長參數(shù) | 短參數(shù) | 描述 |
---|---|---|
--version=v1.0.0 | -v v1.0.0 | 設(shè)置 package 的版本 |
--license=MIT | -l MIT | 設(shè)置 package 所遵循的版權(quán)協(xié)議 |
--submodule | -s | 刪除 git 子模塊 |
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-CT6Hxh38-1571148176408)(/figures/buildpkg.gif)]
序號 | 測試平臺 | 測試結(jié)果 |
---|---|---|
1 | win10 | exe測試通過, py測試通過 |
2 | win7 | exe待測試, py待測試 |
3 | mac | py腳本不知道是否兼容, 沒有測試條件, 后面維護(hù)下 |
4 | linux | py腳本不知道是否兼容, 沒有測試條件, 后面維護(hù)下 |
感謝各位的閱讀,以上就是“純C語言實(shí)現(xiàn)的按鍵驅(qū)動Button_drive的實(shí)例用法”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對純C語言實(shí)現(xiàn)的按鍵驅(qū)動Button_drive的實(shí)例用法這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!