国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【嵌入式開(kāi)源庫(kù)】MultiButton的使用,簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊

這篇具有很好參考價(jià)值的文章主要介紹了【嵌入式開(kāi)源庫(kù)】MultiButton的使用,簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

簡(jiǎn)介

MultiButton 是一個(gè)小巧簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊,可無(wú)限量擴(kuò)展按鍵,按鍵事件的回調(diào)異步處理方式可以簡(jiǎn)化你的程序結(jié)構(gòu),去除冗余的按鍵處理硬編碼,讓你的按鍵業(yè)務(wù)邏輯更清晰。

本章使用環(huán)境:

正點(diǎn)原子stm32F4探索者
代碼工程使用正點(diǎn)原子HAL庫(kù)實(shí)驗(yàn)三-按鍵輸入實(shí)驗(yàn)

下載

GIthub地址:https://github.com/0x1abin/MultiButton
【嵌入式開(kāi)源庫(kù)】MultiButton的使用,簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊
配有g(shù)it環(huán)境可以使用以下命令進(jìn)行下載

git clone https://github.com/0x1abin/MultiButton.git

使用介紹

MultiButton 使用C語(yǔ)言實(shí)現(xiàn),基于面向?qū)ο蠓绞皆O(shè)計(jì)思路,每個(gè)按鍵對(duì)象單獨(dú)用一份數(shù)據(jù)結(jié)構(gòu)管理:

struct Button {
	uint16_t ticks;
	uint8_t  repeat: 4;
	uint8_t  event : 4;
	uint8_t  state : 3;
	uint8_t  debounce_cnt : 3;
	uint8_t  active_level : 1;
	uint8_t  button_level : 1;
	uint8_t  button_id;
	uint8_t  (*hal_button_Level)(uint8_t  button_id_);
	BtnCallback  cb[number_of_event];
	struct Button* next;
};

這樣每個(gè)按鍵使用單向鏈表相連,依次進(jìn)入 button_handler(struct Button* handle) 狀態(tài)機(jī)處理,所以每個(gè)按鍵的狀態(tài)彼此獨(dú)立。

按鍵事件

事件 說(shuō)明
PRESS_DOWN 按鍵按下,每次按下都觸發(fā)
PRESS_UP 按鍵彈起,每次松開(kāi)都觸發(fā)
PRESS_REPEAT 重復(fù)按下觸發(fā),變量repeat計(jì)數(shù)連擊次數(shù)
SINGLE_CLICK 單擊按鍵事件
DOUBLE_CLICK 雙擊按鍵事件
LONG_PRESS_START 達(dá)到長(zhǎng)按時(shí)間閾值時(shí)觸發(fā)一次
LONG_PRESS_HOLD 長(zhǎng)按期間一直觸發(fā)

工程移植

我們將下載好的MultiButton源碼中的multi_button.c和multi_button.h文件拷貝到stm32工程目錄下的handware中的key文件夾下
【嵌入式開(kāi)源庫(kù)】MultiButton的使用,簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊

然后我們?cè)趉eil中添加該文件
【嵌入式開(kāi)源庫(kù)】MultiButton的使用,簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊

代碼分析

#define TICKS_INTERVAL    5	//ms     輪詢間隔時(shí)間,也就是時(shí)間片
#define DEBOUNCE_TICKS    3	//MAX 8	 雙擊間隔時(shí)間片
#define SHORT_TICKS       (300 /TICKS_INTERVAL)	// 短按時(shí)間片
#define LONG_TICKS        (1000 /TICKS_INTERVAL) // 長(zhǎng)按時(shí)間片

然后我們可以看到輪詢的函數(shù)中是不斷的遍歷鏈表

void button_ticks()
{
	struct Button* target;
	for(target=head_handle; target; target=target->next) {
		button_handler(target);
	}
}

根據(jù)代碼我們可以看出來(lái)button_start函數(shù)就是添加鏈表節(jié)點(diǎn)的函數(shù)(那相應(yīng)的button_stop就是刪除鏈表節(jié)點(diǎn)的功能)

int button_start(struct Button* handle)
{
	struct Button* target = head_handle; // 頭節(jié)點(diǎn)
	while(target) {
		if(target == handle) return -1;	//already exist.
		target = target->next; // 遍歷到最后一個(gè)節(jié)點(diǎn)
	}
	handle->next = head_handle;// 環(huán)形結(jié)構(gòu)的鏈表頭尾相連
	head_handle = handle;
	return 0;
}

void button_stop(struct Button* handle)
{
	struct Button** curr;
	for(curr = &head_handle; *curr; ) {
		struct Button* entry = *curr;
		if (entry == handle) {
			*curr = entry->next;
//			free(entry);
			return;//glacier add 2021-8-18
		} else
			curr = &entry->next;
	}
}

按鍵事件驅(qū)動(dòng)枚舉

typedef enum {
	PRESS_DOWN = 0, // 按下信號(hào)
	PRESS_UP,		// 彈起信號(hào)
	PRESS_REPEAT,	// 重復(fù)按下計(jì)數(shù),在button結(jié)構(gòu)體變量中repeat存儲(chǔ)次數(shù)
	SINGLE_CLICK,	// 單擊信號(hào)
	DOUBLE_CLICK,	// 雙擊信號(hào)
	LONG_PRESS_START,	// 長(zhǎng)安信號(hào)
	LONG_PRESS_HOLD,	// 長(zhǎng)按期間會(huì)重復(fù)觸發(fā)
	number_of_event,	
	NONE_PRESS			// 未按下
}PressEvent;
typedef struct Button {
	uint16_t ticks;			
	uint8_t  repeat : 4;	// 單機(jī)次數(shù)記錄
	uint8_t  event : 4;		// 事件
	uint8_t  state : 3;		// 狀態(tài)
	uint8_t  debounce_cnt : 3;	
	uint8_t  active_level : 1;  // 觸發(fā)電平
	uint8_t  button_level : 1;	// 當(dāng)前按鍵電平 
	uint8_t  button_id;			// 按鍵id
	uint8_t  (*hal_button_Level)(uint8_t button_id_);	// 按鍵狀態(tài)讀取函數(shù)通過(guò)指針數(shù)組保存
	BtnCallback  cb[number_of_event];	// 回調(diào)函數(shù)數(shù)組(注冊(cè)的回調(diào)函數(shù)會(huì)存在這里,輪詢會(huì)通過(guò)該數(shù)組調(diào)用)
	struct Button* next;		// 指向下一個(gè)按鍵的指針(鏈表)
}Button;

由上分析得知注冊(cè)按鍵第一個(gè)參數(shù)為按鍵節(jié)點(diǎn),第二個(gè)為參數(shù)為讀取按鍵電平的函數(shù),第三個(gè)為按鍵觸發(fā)電平,第四個(gè)為按鍵id定義

void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level, uint8_t button_id);

觸發(fā)事件注冊(cè),第一個(gè)參數(shù)為按鍵節(jié)點(diǎn),第二個(gè)參數(shù)為按鍵事件枚舉值,第三個(gè)為回調(diào)觸發(fā)函數(shù)

void button_attach(struct Button* handle, PressEvent event, BtnCallback cb);

返回該按鍵節(jié)點(diǎn)的觸發(fā)類型,當(dāng)我們不使用回調(diào)函數(shù)方法時(shí)可以輪詢?cè)摵瘮?shù)判斷按鍵事件信號(hào)

PressEvent get_button_event(struct Button* handle);

multi_button.c文件中還有一個(gè)button_handler函數(shù)也就是我們tick函數(shù)輪詢判斷的函數(shù),該函數(shù)為實(shí)現(xiàn)按鍵各個(gè)事件實(shí)現(xiàn)的方法,大家可以自行閱讀學(xué)習(xí)

完整使用流程

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"

#include "multi_button.h"

enum Button_IDs {
	btn1_id,
	btn2_id,
};

struct Button btn1;
struct Button btn2;

uint8_t read_button_GPIO(uint8_t button_id)
{
	// you can share the GPIO read function with multiple Buttons
	switch(button_id)
	{
		case btn1_id:
			return HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4);
		case btn2_id:
			return HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_3);
		default:
			return 0;
	}
}

void BTN1_PRESS_DOWN_Handler(void* btn)
{
	//do something...
    printf("btn1 press down\r\n");
}

void BTN1_PRESS_UP_Handler(void* btn)
{
	//do something...
    printf("btn2 press up\r\n");
}

void BTN2_LONG_PRESS_START_Handler(void* btn)
{
	//do something...
    printf("btn2 press down\r\n");
}

void BTN2_DOUBLE_Click_Handler(void* btn)
{
	//do something...
    printf("btn2 press up\r\n");
}

int main(void)
{
    HAL_Init();                    	//初始化HAL庫(kù)    
    Stm32_Clock_Init(336,8,2,7);  	//設(shè)置時(shí)鐘,168Mhz
	delay_init(168);               	//初始化延時(shí)函數(shù)
    uart_init(115200);              //初始化串口
	LED_Init();						//初始化LED	
    KEY_Init();                     //初始化按鍵
    
    printf("MultiButton Test...\r\n");

	button_init(&btn1, read_button_GPIO, 0, btn1_id);
	button_init(&btn2, read_button_GPIO, 0, btn2_id);

	// 這里只注冊(cè)了按下和談起信號(hào),其余的信號(hào)也可以自己實(shí)驗(yàn)以下
	button_attach(&btn1, PRESS_DOWN,       BTN1_PRESS_DOWN_Handler);
	button_attach(&btn1, PRESS_UP,         BTN1_PRESS_UP_Handler);

	button_attach(&btn2, LONG_PRESS_START, BTN2_LONG_PRESS_START_Handler);
	button_attach(&btn2, DOUBLE_CLICK,     BTN2_DOUBLE_Click_Handler);

	button_start(&btn1);
	button_start(&btn2);
	
    while(1)
    {
        button_ticks();
        delay_ms(5);
	}
}

實(shí)驗(yàn)效果

【嵌入式開(kāi)源庫(kù)】MultiButton的使用,簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊
我這里使用的方法是回調(diào)函數(shù)觸發(fā),還有一個(gè)方式也就是上面說(shuō)的通過(guò)get_button_event來(lái)判斷按鍵事件狀態(tài)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-431899.html

while(1)
	{
		if(btn1_event_val != get_button_event(&btn1)) {
			btn1_event_val = get_button_event(&btn1);

			if(btn1_event_val == PRESS_DOWN) {
				//do something
			} else if(btn1_event_val == PRESS_UP) {
				//do something
			} else if(btn1_event_val == LONG_PRESS_HOLD) {
				//do something
			}
		}
	}

到了這里,關(guān)于【嵌入式開(kāi)源庫(kù)】MultiButton的使用,簡(jiǎn)單易用的事件驅(qū)動(dòng)型按鍵驅(qū)動(dòng)模塊的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • ARM簡(jiǎn)單程序設(shè)計(jì)【嵌入式系統(tǒng)】

    ARM簡(jiǎn)單程序設(shè)計(jì)【嵌入式系統(tǒng)】

    2023-4-6 20:26:54 以下內(nèi)容源自《【嵌入式系統(tǒng)】》 僅供學(xué)習(xí)交流使用 Keil 4 安裝教程及簡(jiǎn)單使用【嵌入式系統(tǒng)】 新建工程xxx 芯片:ARM7 (Little Endian) 設(shè)置工程屬性 Build結(jié)果必須是0Error的 如果是下圖看配置是否正確 注意這個(gè): 1.每一次修改代碼就需要重寫(xiě)B(tài)uild 2.READWRITE區(qū)變量初始

    2023年04月20日
    瀏覽(105)
  • 帶你了解LVGL:一個(gè)開(kāi)源的嵌入式圖形庫(kù)

    帶你了解LVGL:一個(gè)開(kāi)源的嵌入式圖形庫(kù)

    嵌入式系統(tǒng)是一種將計(jì)算機(jī)硬件和軟件集成在一個(gè)特定的應(yīng)用中的系統(tǒng),例如智能手機(jī)、智能手表、汽車儀表盤(pán)等。嵌入式系統(tǒng)通常需要與用戶進(jìn)行交互,因此需要一個(gè)友好和易用的圖形用戶界面(GUI)。然而,開(kāi)發(fā)一個(gè)高質(zhì)量的GUI并不容易,因?yàn)榍度胧较到y(tǒng)通常有限的資源

    2024年02月09日
    瀏覽(22)
  • (內(nèi)存池) 基于嵌入式指針的簡(jiǎn)單內(nèi)存池

    內(nèi)存池_百度百科 (baidu.com) (Memory Pool)是一種內(nèi)存分配方式,又被稱為 固定大小區(qū)塊規(guī)劃(fixed-size-blocks allocation) 。通常我們習(xí)慣直接使用new、malloc等API申請(qǐng)分配內(nèi)存,這樣做的缺點(diǎn)在于:由于所申請(qǐng)內(nèi)存塊的大小不定,當(dāng)頻繁使用時(shí)會(huì)造成大量的內(nèi)存碎片并進(jìn)而降低性能。

    2024年02月11日
    瀏覽(19)
  • 嵌入式系統(tǒng)(embedded systems)-配置文件解析-開(kāi)源庫(kù)minIni

    嵌入式系統(tǒng)(embedded systems)-配置文件解析-開(kāi)源庫(kù)minIni

    minIni開(kāi)源庫(kù)的介紹 minIni是一個(gè)用于在嵌入式系統(tǒng)中讀寫(xiě)“INI”文件的程序庫(kù)。minIni占用很少的資源,具有確定的內(nèi)存占用,并且可以為各種類型的文件I/O庫(kù)配置。 gitee 鏈接:link https://gitee.com/resetlove/minIni github 鏈接:link https://github.com/compuphase/minIni.git minlni是一個(gè)可移植和可配置

    2024年02月03日
    瀏覽(16)
  • 嵌入式軟件測(cè)試筆記11 | 測(cè)試設(shè)計(jì)技術(shù)簡(jiǎn)單說(shuō)明

    嵌入式軟件測(cè)試筆記11 | 測(cè)試設(shè)計(jì)技術(shù)簡(jiǎn)單說(shuō)明

    即分析測(cè)試基礎(chǔ),明確每一個(gè)測(cè)試需要的情形; 例如: 需要測(cè)試的情形包含所有的條件,true、false、有效值、無(wú)效值等。 測(cè)試情形被轉(zhuǎn)換為測(cè)試用例; 邏輯測(cè)試用例課能就是測(cè)試情形; 邏輯測(cè)試用例即描述的測(cè)試情形的類型,不需要為相關(guān)參數(shù)賦確定的值就可以被覆蓋到

    2024年02月16日
    瀏覽(24)
  • 從何著手OpenHarmony?從這里開(kāi)始認(rèn)識(shí)嵌入式開(kāi)源鴻蒙操作系統(tǒng)

    從何著手OpenHarmony?從這里開(kāi)始認(rèn)識(shí)嵌入式開(kāi)源鴻蒙操作系統(tǒng)

    首先,我們需要知道HarmonyOS與OpenHarmony是不同的概念,我們需要知道它們的區(qū)別: ????????HarmonyOS是華為獨(dú)家開(kāi)發(fā)的,但華為在2020、2021年分兩次 將HarmonyOS的基礎(chǔ)能力全部捐獻(xiàn)給了開(kāi)放原子開(kāi)源基金會(huì),形成了OpenHarmony開(kāi)源項(xiàng)目 ,華為對(duì)開(kāi)源鴻蒙沒(méi)有控制權(quán),當(dāng)然華為仍將

    2024年02月04日
    瀏覽(24)
  • 嵌入式-stm32-基于HAL庫(kù)的感應(yīng)開(kāi)關(guān)蓋垃圾桶項(xiàng)目(開(kāi)源)

    嵌入式-stm32-基于HAL庫(kù)的感應(yīng)開(kāi)關(guān)蓋垃圾桶項(xiàng)目(開(kāi)源)

    網(wǎng)盤(pán)資料: 《嵌入式-stm32-基于HAL庫(kù)的感應(yīng)開(kāi)關(guān)蓋垃圾桶項(xiàng)目(開(kāi)源)》 鏈接:https://pan.baidu.com/s/1kFk09nMKPDvLwIUqMT9q3w 提取碼:og66 –來(lái)自百度網(wǎng)盤(pán)超級(jí)會(huì)員V6的分享 一:項(xiàng)目概述 二:材料準(zhǔn)備 三:細(xì)節(jié)分析(重點(diǎn)) 四:Stm32CubeMx操作步驟以及實(shí)現(xiàn)細(xì)節(jié) 五:Keil5業(yè)務(wù)邏輯代碼編

    2024年02月03日
    瀏覽(89)
  • 嵌入式畢設(shè)分享 stm32的人體健康狀態(tài)檢測(cè)系統(tǒng)(項(xiàng)目開(kāi)源)

    嵌入式畢設(shè)分享 stm32的人體健康狀態(tài)檢測(cè)系統(tǒng)(項(xiàng)目開(kāi)源)

    ?? 這兩年開(kāi)始畢業(yè)設(shè)計(jì)和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點(diǎn),往往達(dá)不到畢業(yè)答辯的要求,這兩年不斷有學(xué)弟學(xué)妹告訴學(xué)長(zhǎng)自己做的項(xiàng)目系統(tǒng)達(dá)不到老師的要求。 為了大家能夠順利以及最少的精力通過(guò)畢設(shè),學(xué)長(zhǎng)分享優(yōu)質(zhì)畢業(yè)設(shè)計(jì)項(xiàng)目,今天

    2024年03月22日
    瀏覽(93)
  • 畢設(shè)開(kāi)源 基于stm32的智能平衡小車 - 單片機(jī) 物聯(lián)網(wǎng)嵌入式

    畢設(shè)開(kāi)源 基于stm32的智能平衡小車 - 單片機(jī) 物聯(lián)網(wǎng)嵌入式

    文章目錄 0 前言 1 項(xiàng)目背景 2 設(shè)計(jì)思路 3 硬件設(shè)計(jì) 4 軟件設(shè)計(jì) 4.2 直立控制程序設(shè)計(jì) 4.3 速度控制程序設(shè)計(jì) 4.4 方向控制程序設(shè)計(jì) 4.5 關(guān)鍵代碼 5 最后 ?? 這兩年開(kāi)始畢業(yè)設(shè)計(jì)和畢業(yè)答辯的要求和難度不斷提升,傳統(tǒng)的畢設(shè)題目缺少創(chuàng)新和亮點(diǎn),往往達(dá)不到畢業(yè)答辯的要求,這

    2024年02月22日
    瀏覽(30)
  • 【嵌入式學(xué)習(xí)】網(wǎng)絡(luò)通信基礎(chǔ)-項(xiàng)目篇:簡(jiǎn)單UDP聊天室

    【嵌入式學(xué)習(xí)】網(wǎng)絡(luò)通信基礎(chǔ)-項(xiàng)目篇:簡(jiǎn)單UDP聊天室

    源碼已在GitHub開(kāi)源:0clock/LearnEmbed-projects/chat 客戶端功能: 上線發(fā)送登錄的用戶名[yes] 發(fā)送消息和接收消息[yes] quit退出 服務(wù)器端功能: 統(tǒng)計(jì)用戶上線信息,放入鏈表中[yes] 接收用戶信息并給其他用戶發(fā)送消息[yes] 服務(wù)器也支持給所有用戶群發(fā)消息[yes] 接收下線提醒

    2024年01月25日
    瀏覽(88)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包