本帖最后由 田裕中 于 2021-11-20 14:32 編輯
按鍵的多功能觸發
概述
本文所介紹的按鍵是基于STM32F系列獨立按鍵模式,目的是使單個按鍵具備多種按鍵效果。常見的有單擊、長按等功能。為拓展功能多樣性,對按鍵驅動進行設計,實現按鍵功能的多樣性,本設計已達到的功能包括單擊、長按、雙擊、三擊、四擊......等,剩余可由用戶自行添加。按鍵消息通過消息隊列進行傳遞。
按鍵對象封裝 類似于面向對象中類的封裝,該結構體包含按鍵觸發函數、硬件接口、計數器及按鍵狀態標記。 typedef void (*KEYFUNC) (uint16_t tick_cnt_ptr);
該定義為:聲明一個函數指針,指向一個參數為uint16_t 類型的變量的函數。
typedef struct
{
KEYFUNC key_function;
KEYFUNC fast_key_fun;
GPIO_TypeDef* GPIOx;
uint16_t Pin;
uint16_t key_cnt;
uint16_t Status;
} KEYSTATUS;
按鍵事件注冊 注冊按鍵的觸發函數、初始狀態State、按鍵初始化等。聲明兩個枚舉變量進行按鍵的開啟與關閉(DISABLE_KEY、GENERAL_KEY)。 enum
{
DISABLE_KEY,
GENERAL_KEY
};申明一個map對象,為每個按鍵引用驅動類:
KEYSTATUS io_key_map[IOKEY_NUM];在此函數開啟之前確保按鍵引腳已成功初始化。
void ap_peripheral_key_register(INT8U type)
{
io_key_num = 0;
switch(type)
{
case DISABLE_KEY:
{
//disable all key
}
break;
case GENERAL_KEY:
{
#if IO_KEY
io_key_map[io_key_num].GPIOx = KEY_Pin_GPIO_Port;
io_key_map[io_key_num].Pin = KEY_Pin_Pin;
io_key_map[io_key_num].key_function = ap_peripheral_io_key_exe;
//io_key_map[io_key_num].fast_key_fun = ap_peripheral_io_fast_key_exe;
io_key_map[io_key_num].key_cnt = 0;
io_key_map[io_key_num++].Status = 0;
#endif
#if CHARGE
io_key_map[io_key_num].GPIOx = STAT_CHG_GPIO_Port;
io_key_map[io_key_num].Pin = STAT_CHG_Pin;
io_key_map[io_key_num].key_function = ap_peripheral_charge_exe;
io_key_map[io_key_num].key_cnt = 0;
io_key_map[io_key_num++].Status = 0;
#endif
#if IO_USB
io_key_map[io_key_num].GPIOx = USB_CH_GPIO_Port;
io_key_map[io_key_num].Pin = USB_CH_Pin;
io_key_map[io_key_num].key_function = ap_peripheral_io_usb_exe;
io_key_map[io_key_num].key_cnt = 0;
io_key_map[io_key_num++].Status = 0;
#endif
}
break;
default:
ap_peripheral_key_register(DISABLE_KEY);
break;
}
}
按鍵回調函數 按鍵事件注冊后,每個按鍵引腳功能編寫對應的回調函數,為事件注冊使用。說明:按鍵消息是基于消息隊列進行消息傳遞,可根據用戶的需求自行設計回調函數功能! 第一個按鍵回調函數: void ap_peripheral_io_key_exe(INT16U tick_cnt_ptr)
{
if(tick_cnt_ptr >= LONG_KEY_TIME)
{
msgQSend(APQ, MSG_APQ_LONG_KEY,MSG_PRI_NORMAL);
}
else if(tick_cnt_ptr == TWO_KEY_VALUE)
{
msgQSend(APQ, MSG_APQ_TWO_KEY,MSG_PRI_NORMAL);
}
else if(tick_cnt_ptr == THREE_KEY_VALUE)
{
msgQSend(APQ, MSG_APQ_THREE_KEY,MSG_PRI_NORMAL);
}
else if(tick_cnt_ptr == FOUR_KEY_VALUE)
{
msgQSend(APQ, MSG_APQ_FOUR_KEY,MSG_PRI_NORMAL);
}
else if(tick_cnt_ptr == FIVE_KEY_VALUE)
{
msgQSend(APQ, MSG_APQ_FIVE_KEY,MSG_PRI_NORMAL);
}
else
{
msgQSend(APQ, MSG_APQ_CLICK_KEY,MSG_PRI_NORMAL);
}
}
其他按鍵的回調函數與其相似,可自行設計......
按鍵掃描 按鍵掃描通過定時器中斷進行掃描,優點是有穩定的掃描時間,可計算按鍵的持續時間及消抖,本設計是20ms掃描一次。此函數中,由按鍵事件注冊函數提供一個io_key_num為其提供掃描范圍: 總結 該獨立按鍵的多種功能設計,目的是實現單個按鍵實現多種功能,就好比遙控器的上、下、左、右、確定、返回等,通過單個按鍵就可實現其所有功能。該按鍵功能的實現,依賴于消息隊列進行按鍵消息傳遞,項目引入消息隊列后,極大方便了按鍵回調函數的設計實現。 個人筆記總結,若有問題,歡迎留言、批評指正! 公眾號為個人資料總結,內有資料文檔!
|