日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

STM32F7xx —— 输入

發(fā)布時間:2023/12/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 STM32F7xx —— 输入 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? STM32F7xx —— 輸入

?

目錄

STM32F7xx —— 輸入

一、輸入配置

二、輸入掃描

三、輸入處理


一、輸入配置

為了靈活使用,我們將輸入的有效電平設(shè)置成可配置。同樣是列表表示所有IO口。

// 配置有效電平 typedef enum {KEY_INIT_IS_ACTIVE = 0,KEY_LOW_IS_ACTIVE = 1,KEY_HIGH_IS_ACTIVE = 2, } key_active_t;#define KEY_CONFIG(gpio, pin) GPIOConfig(gpio, pin, GPIO_MODE_INPUT, GPIO_PULLUP) #define KEY_READ(gpio, pin) HAL_GPIO_ReadPin(gpio, pin)#define KEY1_PORT GPIOH #define KEY1_PIN GPIO_PIN_3#define KEY2_PORT GPIOH #define KEY2_PIN GPIO_PIN_2#define KEY3_PORT GPIOC #define KEY3_PIN GPIO_PIN_13 // demo代碼 只傳遞思想static void key_gpio_config(GPIO_TypeDef *gpio, uint16_t pin) {KEY_CONFIG(gpio, pin); }typedef struct {GPIO_TypeDef *gpio;uint16_t pin; } key_port_t;static key_port_t key_entries[] = {{KEY1_PORT, KEY1_PIN},{KEY2_PORT, KEY2_PIN},{KEY3_PORT, KEY3_PIN}, };void KeyInit(void) {uint32_t i, mask = 1;for(i = 0; i < ARRAY_SIZE(key_entries); ++i){if(0xFFFFFFFF & mask){key_gpio_config(key_entries[i].gpio, key_entries[i].pin);#if(CONFIG_KEY_TEST == 1) // 測試時使用 //config.key.total_switch = KEY_MODE_OPEN;//config.key.sub_switch[i] = KEY_MODE_OPEN;config.key.active_tag[i] = KEY_LOW_IS_ACTIVE; #endif}mask <<= 1;} }// 輸入是否可用 static uint8_t key_is_enable(uint8_t index) {// 這里可以寫成可配置 配置IO口可用或者不可用(類似一個總開關(guān))return 1; }// 有輸入到來 static uint8_t key_is_pressed(uint8_t index) {if(key_is_enable(index)){if(KEY_LOW_IS_ACTIVE == config.key.active_tag[index]){if(KEY_READ(key_entries[index].gpio, key_entries[index].pin) == 0){return 1;}}else if(KEY_HIGH_IS_ACTIVE == config.key.active_tag[index]){if(KEY_READ(key_entries[index].gpio, key_entries[index].pin) == 1){return 1;}}}return 0; }// 按鍵被按下 uint8_t Key1IsDown(void) {return key_is_pressed(0); }uint8_t Key2IsDown(void) {return key_is_pressed(1); }uint8_t Key3IsDown(void) {return key_is_pressed(2); }

二、輸入掃描

// 按鍵的狀態(tài)機結(jié)構(gòu)定義 // 按鍵狀態(tài) typedef enum {KEY_STATE_INIT, // 缺省按鍵狀態(tài)KEY_STATE_UP, // 按鍵彈起狀態(tài)KEY_STATE_DOWN, // 按鍵按下狀態(tài)KEY_STATE_LONG, // 按鍵長按狀態(tài)KEY_STATE_AUTO, // 按鍵自動連發(fā)狀態(tài) } key_state_t;// 按鍵濾波時間20ms, 單位10ms。 // 只有連續(xù)檢測到20ms狀態(tài)不變才認為有效,包括彈起和按下兩種事件 // 即使按鍵電路不做硬件濾波,該濾波機制也可以保證可靠地檢測到按鍵事件 #define KEY_FILTER_TIME 2 // 濾波消抖 #define KEY_LONG_TIME 100 // 單位10ms 持續(xù)1秒,認為長按事件 #define KEY_REPEAT_TIME 100 // 單位10ms 持續(xù)1秒,自動連發(fā)typedef uint8_t (*key_cb)(void); typedef struct {uint8_t state; // 按鍵當(dāng)前狀態(tài)(按下還是彈起)uint8_t last; // 上一次按鍵的狀態(tài)uint8_t count; // 濾波消抖計數(shù)器uint16_t long_time; // 按鍵按下持續(xù)時間, 0表示不檢測長按uint16_t long_count; // 長按計數(shù)器uint8_t repeat_speed; // 連續(xù)按鍵周期uint8_t repeat_count; // 連續(xù)按鍵計數(shù)器key_cb is_down_func; // 按鍵按下的判斷函數(shù),1表示按下 } key_t;static key_t key_items[] = {{KEY_STATE_INIT, KEY_STATE_INIT, KEY_FILTER_TIME, KEY_LONG_TIME, 0, KEY_REPEAT_TIME, 0, Key1IsDown},{KEY_STATE_INIT, KEY_STATE_INIT, KEY_FILTER_TIME, KEY_LONG_TIME, 0, KEY_REPEAT_TIME, 0, Key2IsDown},{KEY_STATE_INIT, KEY_STATE_INIT, KEY_FILTER_TIME, KEY_LONG_TIME, 0, KEY_REPEAT_TIME, 0, Key3IsDown}, }; // 按鍵狀態(tài)機key_scan // 配置限制條件在這個函數(shù)里面加 static void key_scan_ext(key_t *entry, uint8_t i) {switch(entry->state){case KEY_STATE_INIT:case KEY_STATE_UP:{entry->state = KEY_STATE_DOWN; // 按鍵被按下break;}case KEY_STATE_DOWN:{if(entry->long_time > 0){if(entry->long_count < entry->long_time){if(++entry->long_count >= entry->long_time){entry->state = KEY_STATE_LONG;}}}break;}case KEY_STATE_LONG:{if(entry->repeat_speed > 0) // 自動連發(fā)時間到 自動連發(fā)事件{if(++entry->repeat_count >= entry->repeat_speed){entry->repeat_count = 0;// 長按觸發(fā)}}break;}}entry->last = entry->state; // 最新的按鍵狀態(tài) }static void key_scan(uint8_t i) {key_t *entry = &key_items[i];uint8_t key;if(entry->is_down_func()){if(entry->count < KEY_FILTER_TIME) // 消抖{++entry->count;}else{key_scan_ext(entry, i); // 按鍵掃描狀態(tài)機}}else{if(entry->count > KEY_FILTER_TIME){entry->count = KEY_FILTER_TIME;}else if(entry->count > 0){--entry->count;}else{if(KEY_STATE_DOWN == entry->last) // 一次完整的按鍵到這里就彈起了{// 按鍵按下之后可以加入到隊列中,這里的隊列可以自己寫;如果帶系統(tǒng)可以使用系統(tǒng)的消息隊列等方式。// key = i + 1;// xQueueSend(os_key_queue, &key, 10); }entry->last = KEY_STATE_UP;entry->state = KEY_STATE_UP; // 按鍵彈起狀態(tài)}entry->long_count = 0;entry->repeat_count = 0; // 清空計數(shù)器} }

三、輸入處理

// 按鍵按下之后,會將值加入到隊列中,我們讀取隊列數(shù)據(jù),然后掃描列表匹配功能 static void key1_cb(void); static void key2_cb(void); static void key3_cb(void);#define KEY1_CMD 1 #define KEY2_CMD 2 #define KEY3_CMD 3typedef struct {uint8_t cmd;void (* key_handle_cb)(void); } key_handle_t;static const key_handle_t key_entries[] = {{KEY1_CMD, key1_cb},{KEY2_CMD, key2_cb},{KEY3_CMD, key3_cb},{0xFF, NULL }, };// 按鍵的通用功能 static void key_func(uint8_t func) {}static void key1_cb(void) {}static void key2_cb(void) {}static void key3_cb(void) {}static void key_process(uint8_t event) {const key_handle_t *entry;for(entry = key_entries; entry->key_handle_cb; ++entry){if(event == entry->cmd){entry->key_handle_cb();break;}} }

裸機:按鍵掃描20ms執(zhí)行一次,按鍵處理直接丟在主函數(shù)中。(自己寫隊列)

系統(tǒng):在任務(wù)中執(zhí)行按鍵掃描和按鍵處理。(系統(tǒng)自帶隊列或者郵箱)

?

?

總結(jié)

以上是生活随笔為你收集整理的STM32F7xx —— 输入的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。