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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言连发器,GPIO按键的长按、短按、连发——C程序

發布時間:2024/1/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言连发器,GPIO按键的长按、短按、连发——C程序 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

不借助GPIO中斷,采用輪詢的方式,實現按鍵的長按、短按、連發

參考:https://blog.csdn.net/qq_31151689/article/details/85228441

百度快照:http://cache.baiducontent.com/c?m=9d78d513d99603f405fa950e1a66d571695297134dc0a46468d5e35fe3654c324171e2cb30521213a3c36b6671b83958fd814765367337c799dff84ccabae27938895723061d913666c46facdc3023d567d004e6f55fa1f8b12592ddcfce8f0a0e9f44050dd1b1dd061714bd33a7522ca0e58e4f615e13b9ea3361f5526a7adf651be719aefd643941d2ad831d51c92dd0611b91a936&p=85769a479d8211a05bed9362544f97&newp=90759a46d6c416e04ea4f82d02148f231610db2151d7d31f6b82c825d7331b001c3bbfb423261403d7cf7d6604af4f5beef7307237012ba3dda5c91d9fb4c57479df68223970&user=baidu&fm=sc&query=gpio%B0%B4%BC%FC%B3%A4%B0%B4%B6%CC%B0%B4C%D3%EF%D1%D4&qid=a2d95b6400011865&p1=8

#include #include // 定義長按鍵的TICK數, 以及連發間隔的TICK數, 單位是毫秒ms

#define KEY_DEBOUNCE_PERIOD 20 // 延時消抖時間

#define KEY_LONG_PERIOD 1000

#define KEY_CONTINUE_PERIOD 200

#define TRUE 1

#define FALSE 0

typedef unsigned int Bool;

typedef enum {

LOW = 0,

HIGH

} KEY_LEVEL_E;

typedef enum

{

KEY1 = 0,

KEY2,

KEY3,

KEY4,

KEY_MAX_NUM

} KEY_NUM_E;

// 定義按鍵返回值狀態(按下,長按,連發,釋放,無動作)

typedef enum {

KEY_NULL = 0,

KEY_DOWN,

KEY_LONG,

KEY_CONTINUE,

KEY_UP

} KEY_VALUE_E;

typedef enum {

KEY_STATE_INIT = 0,

KEY_STATE_WOBBLE,

KEY_STATE_PRESS,

KEY_STATE_LONG,

KEY_STATE_CONTINUE,

KEY_STATE_RELEASE

} KEY_STATE_E;

typedef struct

{

KEY_NUM_E eKeyId;

KEY_LEVEL_E eKeyLevel; //key level(low or high)

unsigned int downTick;

unsigned int upTick;

KEY_STATE_E eKeyCurState; //key cur state(fsm)

KEY_STATE_E eKeyLastState; //key last state(fsm)

Bool bStateChangedFlag; //state changed flag

KEY_VALUE_E eLastKeyValue; //key value

} KEY_HANDLE_T;

typedef void (*pf)(void);

typedef struct

{

pf keyDownAction;

pf keyLongAction;

pf keyContinueAction;

pf keyUpAction;

} KEY_FUNCTION_T;

KEY_HANDLE_T keyList[KEY_MAX_NUM] =

{

{KEY1, LOW, 0, 0, KEY_STATE_INIT, KEY_STATE_INIT, FALSE, KEY_NULL},

{KEY2, LOW, 0, 0, KEY_STATE_INIT, KEY_STATE_INIT, FALSE, KEY_NULL},

{KEY3, LOW, 0, 0, KEY_STATE_INIT, KEY_STATE_INIT, FALSE, KEY_NULL},

{KEY4, LOW, 0, 0, KEY_STATE_INIT, KEY_STATE_INIT, FALSE, KEY_NULL}

};

// 用于獲取當前時間, 單位是毫秒ms

unsigned int getTime0(void)

{

struct timespec time;

clock_gettime(CLOCK_MONOTONIC, &time);

return ((time.tv_sec * 1000) + (time.tv_nsec/1000000));

}

unsigned int timeDiffFromNow(unsigned int time0)

{

unsigned int cur = 0;

struct timespec time;

clock_gettime(CLOCK_MONOTONIC, &time);

cur = (time.tv_sec * 1000) + (time.tv_nsec/1000000);

return cur - time0;

}

void keyScan(KEY_HANDLE_T* key)

{

// gpioReadPin()需根據你的平臺來寫

if(HIGH == gpioReadPin(key->eKeyId))

{

// 根據原理圖, HIGH代表松開

key->eKeyLevel = HIGH;

}

else

{

// 根據原理圖, LOW代表按下

key->eKeyLevel = LOW;

}

// 獲取當前key是按下還是松開

KEY_LEVEL_E level = key->eKeyLevel;

key->eLastKeyValue = KEY_NULL;

switch(key->eKeyCurState)

{

case KEY_STATE_INIT:

if(LOW == level)

{

key->downTick = getTime0();

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_WOBBLE;

}

break;

case KEY_STATE_WOBBLE:

if(LOW == level)

{

if(timeDiffFromNow(key->downTick) >= KEY_DEBOUNCE_PERIOD)

{

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_PRESS;

}

}

else

{

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_INIT;

}

break;

case KEY_STATE_PRESS:

if(TRUE == key->bStateChangedFlag)

{

key->bStateChangedFlag = FALSE;

key->eLastKeyValue = KEY_DOWN;

}

if(LOW == level)

{

if(timeDiffFromNow(key->downTick) >= KEY_LONG_PERIOD)

{

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_LONG;

}

}

else

{

key->upTick = getTime0();

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_RELEASE;

}

break;

case KEY_STATE_LONG:

if(TRUE == key->bStateChangedFlag)

{

key->bStateChangedFlag = FALSE;

key->eLastKeyValue = KEY_LONG;

}

if(LOW == level)

{

if(timeDiffFromNow(key->downTick) >= (KEY_LONG_PERIOD + KEY_CONTINUE_PERIOD))

{

key->downTick = getTime0();

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_CONTINUE;

}

}

else

{

key->upTick = getTime0();

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_RELEASE;

}

break;

case KEY_STATE_CONTINUE:

if(TRUE == key->bStateChangedFlag)

{

key->bStateChangedFlag = FALSE;

key->eLastKeyValue = KEY_CONTINUE;

}

if(LOW == level)

{

if(timeDiffFromNow(key->downTick) >= KEY_CONTINUE_PERIOD)

{

key->downTick = getTime0();

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_CONTINUE;

}

}

else

{

key->upTick = getTime0();

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_RELEASE;

}

break;

case KEY_STATE_RELEASE:

if(timeDiffFromNow(key->upTick) >= KEY_DEBOUNCE_PERIOD) // 松開按鍵也來個消抖

{

if(TRUE == key->bStateChangedFlag)

{

key->bStateChangedFlag = FALSE;

key->eLastKeyValue = KEY_UP;

}

key->bStateChangedFlag = TRUE;

key->eKeyCurState = KEY_STATE_INIT;

}

else

{

if(LOW == level)

{

key->eKeyCurState = key->eKeyLastState;

}

}

break;

default:

break;

}

key->eKeyLastState = key->eKeyCurState;

}

void key1DownAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key1LongAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key1ContinueAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key1UpAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key2DownAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key2LongAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key2ContinueAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key2UpAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key3DownAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key3LongAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key3ContinueAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key3UpAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key4DownAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key4LongAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key4ContinueAction(void)

{

printf("%s\n", __FUNCTION__);

}

void key4UpAction(void)

{

printf("%s\n", __FUNCTION__);

}

KEY_FUNCTION_T keyMapList[KEY_MAX_NUM] =

{

{key1DownAction, key1LongAction, key1ContinueAction, key1UpAction}, //KEY1

{key2DownAction, key2LongAction, key2ContinueAction, key2UpAction}, //KEY2

{key3DownAction, key3LongAction, key3ContinueAction, key3UpAction}, //KEY3

{key4DownAction, key4LongAction, key4ContinueAction, key4UpAction}, //KEY4

};

void keyMapHandle(KEY_HANDLE_T *key, KEY_FUNCTION_T *keyMap)

{

unsigned char keyValue = key->eLastKeyValue;

if(KEY_NULL == keyValue)

{

return;

}

else

{

switch(keyValue)

{

case KEY_DOWN:

if(keyMap->keyDownAction != NULL)

{

keyMap->keyDownAction();

}

break;

case KEY_LONG:

if(keyMap->keyLongAction != NULL)

{

keyMap->keyLongAction();

}

break;

case KEY_CONTINUE:

if(keyMap->keyContinueAction != NULL)

{

keyMap->keyContinueAction();

}

break;

case KEY_UP:

if(keyMap->keyUpAction != NULL)

{

keyMap->keyUpAction();

}

break;

default:

break;

}

}

}

int main(void)

{

KEY_NUM_E keyId = KEY_MAX_NUM;

while(1)

{

for(keyId=KEY1; keyId

總結

以上是生活随笔為你收集整理的c语言连发器,GPIO按键的长按、短按、连发——C程序的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。