久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

一個應(yīng)用于單片機的按鍵處理模塊

 新用戶0118F7lQ 2023-10-03 發(fā)布于山東


key_board介紹

key_board用于單片機中的小巧多功能按鍵支持,軟件采用了分層的思想,,并且做到了與平臺無關(guān),,用戶只需要提供按鍵的基本信息和讀寫io電平的函數(shù)即可,,非常方便移植,同時支持多個矩陣鍵盤及多個單io控制鍵盤,。

目前已實現(xiàn)按下觸發(fā),、彈起觸發(fā)、長按自動觸發(fā),、長按彈起觸發(fā),、多擊觸發(fā)、連續(xù)觸發(fā)等功能,,并且能夠隨意組合(支持狀態(tài)的同一時間軸和非同一時間軸),,后續(xù)還會添加更多的功能。

使用說明

  1. 初始化相關(guān)的硬件資源,。
  2. 提供一個1ms的定時器,,用于周期性的調(diào)用'key_check'函數(shù)。
  3. 提供按鍵的描述及讀寫io的函數(shù),。
  4. 將鍵盤注冊到系統(tǒng),。
  5. 具體的操作參考提供的stm32例程。
  6. 因為程序默認使用了堆內(nèi)存,,當發(fā)現(xiàn)程序運行結(jié)果不正常時,,嘗試增大你的程序堆空間,或者注冊調(diào)試接口查看原因,。
  7. 更詳細的使用教程見詳細使用說明或者提供的stm32例程,。

已支持的鍵盤

  1. 矩陣鍵盤
圖片
矩陣鍵盤
  1. 單io按鍵
圖片
單io按鍵

詳細使用說明

key_board.ckey_board.h,,key_board_config.h放進key_board文件夾中并包含進你的工程,,添加頭文件路徑,。

基礎(chǔ)功能移植(以stm32矩陣鍵盤為例)

首先需要一個可使用的定時器(如果不想使用定時器也可直接放到主循環(huán)中,但不推薦,,會導(dǎo)致時基不準確),,固定為1ms觸發(fā)一次;

準備待檢測的按鍵的基本信息,,可參考key_board_sample.c文件中的struct key_pin_t結(jié)構(gòu)體,,如:

struct key_pin_t {
    GPIO_TypeDef *port;     //按鍵端口號
    uint16_t pin;           //按鍵的引腳號
    GPIO_PinState valid;    //按鍵的有效電平(即按鍵按下時的電平)
    GPIO_PinState invalid;  //按鍵的無效電平(即按鍵空閑時的電平)
    /*
    可添加你的其它參數(shù)
    */

};

定義待檢測的按鍵信息,可參考key_board_sample.c文件中的const struct key_pin_t key_pin_sig[]結(jié)構(gòu)體數(shù)組,,對應(yīng)頭文件為key_board_sample.h,,如:

//全局變量
const struct key_pin_t key_pin_sig[] = {
    {
        .port = KEY_PORT_J12,
        .pin = KEY_PIN_J12,
        .valid = KEY_PRESS_LEVEL_J12,
        .invalid = KEY_RELEASE_LEVEL_J12
    },
    {
        .port = KEY_PORT_J34,
        .pin = KEY_PIN_J34,
        .valid = KEY_PRESS_LEVEL_J34,
        .invalid = KEY_RELEASE_LEVEL_J34
    },
    {
        .port = KEY_PORT_J56,
        .pin = KEY_PIN_J56,
        .valid = KEY_PRESS_LEVEL_J56,
        .invalid = KEY_RELEASE_LEVEL_J56
    },
};

如果為矩陣鍵盤還需要定義控制io的相關(guān)信息,可參考key_board_sample.c文件中的const struct key_pin_t key_pin_ctrl[]結(jié)構(gòu)體數(shù)組,,對應(yīng)頭文件為key_board_sample.h,,如:

const struct key_pin_t key_pin_ctrl[] = {
    {
        .port = KEY_PORT_J135,
        .pin = KEY_PIN_J135,
        .valid = KEY_CTL_LINE_ENABLE,
        .invalid = KEY_CTL_LINE_DISABLE
    },
    {
        .port = KEY_PORT_J246,
        .pin = KEY_PIN_J246,
        .valid = KEY_CTL_LINE_ENABLE,
        .invalid = KEY_CTL_LINE_DISABLE
    },
};

實現(xiàn)按鍵io的電平讀取函數(shù),可參考key_board_sample.c文件中的pin_level_get函數(shù),,如:

static inline bool pin_level_get(const void *desc)
{
    struct key_pin_t *pdesc;

    pdesc = (struct key_pin_t *)desc;
    return HAL_GPIO_ReadPin(pdesc->port, pdesc->pin) == pdesc->valid;
}

如果為矩陣鍵盤還需要實現(xiàn)按鍵io的電平寫入函數(shù),,可參考key_board_sample.c文件中的pin_level_set函數(shù),如:

static inline void pin_level_set(const void *desc, bool flag)
{
    struct key_pin_t *pdesc;

    pdesc = (struct key_pin_t *)desc;
    HAL_GPIO_WritePin(pdesc->port, pdesc->pin, flag ? pdesc->valid : pdesc->invalid);
}

定義按鍵的id及功能結(jié)構(gòu)體struct key_public_sig_t,,可參考key_board_sample.c文件中的const struct key_public_sig_t key_public_sig[]結(jié)構(gòu)體數(shù)組,,對應(yīng)頭文件key_board.h,如:

const struct key_public_sig_t key_public_sig[] = {
    KEY_PUBLIC_SIG_DEF(KEY_UP, &key_pin_sig[0], pin_level_get, KEY_FLAG_NONE),
    KEY_PUBLIC_SIG_DEF(KEY_LEFT, &key_pin_sig[1], pin_level_get, KEY_FLAG_NONE),
    KEY_PUBLIC_SIG_DEF(KEY_DOWN, &key_pin_sig[2], pin_level_get, KEY_FLAG_NONE),
    //下面的是因為使用的矩陣鍵盤而擴展出來的三個按鍵
    KEY_PUBLIC_SIG_DEF(KEY_ENTER, &key_pin_sig[0], pin_level_get, KEY_FLAG_NONE),
    KEY_PUBLIC_SIG_DEF(KEY_RIGHT, &key_pin_sig[1], pin_level_get, KEY_FLAG_NONE),
    KEY_PUBLIC_SIG_DEF(KEY_EXIT, &key_pin_sig[2], pin_level_get, KEY_FLAG_NONE),
};

如果為矩陣鍵盤還需要定義控制io的id及功能結(jié)構(gòu)體struct key_public_ctrl_t,,可參考key_board_sample.c文件中的const struct key_public_ctrl_t key_public_ctrl[]結(jié)構(gòu)體數(shù)組,,對應(yīng)頭文件key_board.h,如:

const struct key_public_ctrl_t key_public_ctrl[] = {
    KEY_PUBLIC_CTRL_DEF(&key_pin_ctrl[0], pin_level_set),
    KEY_PUBLIC_CTRL_DEF(&key_pin_ctrl[1], pin_level_set),
};

初始化鍵盤,,可參考key_board_sample.c文件中的GPIO_Key_Board_Init函數(shù),,如:

void GPIO_Key_Board_Init(void)
{
    //硬件io的初始化
    GPIO_InitTypeDef GPIO_InitStruct;
    unsigned int i;

    RCC_KEY_BOARD_CLK_ENABLE();

    GPIO_InitStruct.Pull  = GPIO_PULLUP;
    GPIO_InitStruct.Mode  = GPIO_MODE_INPUT;
    for(i = 0;i < ARRAY_SIZE(key_pin_sig);i++)
    {
        GPIO_InitStruct.Pin   = key_pin_sig[i].pin;
        HAL_GPIO_Init(key_pin_sig[i].port, &GPIO_InitStruct);
    }

    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Pull  = GPIO_NOPULL;
    GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
    for(i = 0;i < ARRAY_SIZE(key_pin_ctrl);i++)
    {
        GPIO_InitStruct.Pin   = key_pin_ctrl[i].pin;
        HAL_GPIO_Init(key_pin_ctrl[i].port, &GPIO_InitStruct);
    }

    //初始化鍵盤
    key_board_init();
    //注冊鍵盤到系統(tǒng)中(矩陣鍵盤)
    key_board_register(KEY_BOARD_MATRIX, key_public_sig, ARRAY_SIZE(key_public_sig), key_public_ctrl, ARRAY_SIZE(key_public_ctrl));
}

主流程偽代碼框架,更多例子參考main_test.c文件:

int main(void)
{
    //初始化硬件io,,并注冊鍵盤
    GPIO_Key_Board_Init();
    //初始化定時器,,用于按鍵掃描(1ms)
    init_tmr();

    for(;;)
    {
        if(key_check_state(KEY_UP, KEY_RELEASE))
        {
            PRINTF('KEY_UP KEY_RELEASE\r\n');
        }
        if(key_check_state(KEY_UP, KEY_PRESS))
        {
            PRINTF('KEY_UP KEY_PRESS\r\n');
        }
    }
}

//定時器到期回調(diào)處理函數(shù)
void tmr_irq_callback(void)
{
    //調(diào)用按鍵掃描核心函數(shù)
    key_check();
}

擴展功能長按的使用

首先確保key_board_config.h文件中宏KEY_LONG_SUPPORT已處于使能狀態(tài),并且正確設(shè)置了宏KEY_DEFAULT_LONG_TRRIGER_TIME的值,;

設(shè)置按鍵功能需要對長按進行檢測,如:

KEY_PUBLIC_SIG_DEF(KEY_UP, &key_pin_sig[0], pin_level_get, KEY_FLAG_PRESS_LONG | KEY_FLAG_RELEASE_LONG)

使用例程:

if(key_check_state(KEY_UP, KEY_PRESS_LONG))
{
    PRINTF('KEY_UP KEY_PRESS_LONG\r\n');
}
if(key_check_state(KEY_UP, KEY_RELEASE_LONG))
{
    PRINTF('KEY_UP KEY_RELEASE_LONG\r\n');
}

擴展功能連按的使用

首先確保key_board_config.h文件中宏KEY_CONTINUOUS_SUPPORT已處于使能狀態(tài),,并且正確設(shè)置了宏KEY_DEFAULT_CONTINUOUS_INIT_TRRIGER_TIMEKEY_DEFAULT_CONTINUOUS_PERIOD_TRRIGER_TIME的值,;

設(shè)置按鍵功能需要對連按進行檢測,如:

KEY_PUBLIC_SIG_DEF(KEY_UP, &key_pin_sig[0], pin_level_get, KEY_FLAG_PRESS_CONTINUOUS)

使用例程:

if(key_check_state(KEY_UP, KEY_PRESS_CONTINUOUS))
{
    PRINTF('KEY_UP KEY_PRESS_CONTINUOUS\r\n');
}

擴展功能多擊的使用

首先確保key_board_config.h文件中宏KEY_MULTI_SUPPORT已處于使能狀態(tài),,并且正確設(shè)置了宏KEY_DEFAULT_MULTI_INTERVAL_TIME的值,;

設(shè)置按鍵功能需要多擊進行檢測,如:

KEY_PUBLIC_SIG_DEF(KEY_UP, &key_pin_sig[0], pin_level_get, KEY_FLAG_PRESS_MULTI | KEY_FLAG_RELEASE_MULTI)

使用例程:

unsigned int res;
res = key_check_state(KEY_UP, KEY_PRESS_MULTI);
if(res)
{
    PRINTF('KEY_UP KEY_PRESS_MULTI:%d\r\n', res);
}
res = key_check_state(KEY_UP, KEY_RELEASE_MULTI);
if(res)
{
    PRINTF('KEY_UP KEY_RELEASE_MULTI:%d\r\n', res);
}

擴展功能組合狀態(tài)(同一時間軸)

使用例程:

unsigned int key_down_release_long, key_up_release_long;
key_down_release_long = key_check_state(KEY_DOWN, KEY_RELEASE_LONG);
key_up_release_long = key_check_state(KEY_UP, KEY_RELEASE_LONG);
if(key_down_release_long && key_up_release_long)
{
    PRINTF('KEY_DOWN KEY_RELEASE_LONG && KEY_UP KEY_RELEASE_LONG\n');
}

擴展功能組合狀態(tài)(非同一時間軸)

首先確保key_board_config.h文件中宏KEY_COMBINE_SUPPORT已處于使能狀態(tài),,并且正確設(shè)置了宏KEY_DEFAULT_COMBINE_INTERVAL_TIME的值,;

使用例程:

//用于保存注冊后的組合狀態(tài)id
static unsigned int test_id1, test_id2;

//定義要檢測的狀態(tài)
const struct key_combine_t test_combine1[] = {
    { .id = KEY_UP,     .state = KEY_PRESS },
    { .id = KEY_DOWN,   .state = KEY_PRESS_LONG },
    { .id = KEY_UP,     .state = KEY_PRESS },
};
//注冊組合狀態(tài)
test_id1 = key_combine_register(test_combine1, ARRAY_SIZE(test_combine1));

const struct key_combine_t test_combine2[] = {
    { .id = KEY_UP,     .state = KEY_PRESS },
    { .id = KEY_DOWN,   .state = KEY_PRESS },
    { .id = KEY_UP,     .state = KEY_PRESS },
    { .id = KEY_DOWN,   .state = KEY_PRESS },
};
test_id2 = key_combine_register(test_combine2, ARRAY_SIZE(test_combine2));

if(key_check_combine_state(test_id1))
{
    PRINTF('combine test_id1\r\n');
}

if(key_check_combine_state(test_id2))
{
    PRINTF('combine test_id2\r\n');
}

原文:https:///wei513723/key_board

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多