打印

乐鑫的这个按键处理程序也不错。

[复制链接]
1585|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
keer_zu|  楼主 | 2017-9-13 13:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
乐鑫的也不错:
中断方式,回调函数。

可以很方便完成某个按键的短按功能和长按功能等等。

/*
* ESPRESSIF MIT License
*
* Copyright (c) 2016 <ESPRESSIF SYSTEMS (SHANGHAI) PTE LTD>
*
* Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case,
* it is free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished
* to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "gpio.h"
#include "user_interface.h"

#include "driver/key.h"

LOCAL void key_intr_handler(void *arg);

/******************************************************************************
* FunctionName : key_init_single
* Description  : init single key's gpio and register function
* Parameters   : uint8 gpio_id - which gpio to use
*                uint32 gpio_name - gpio mux name
*                uint32 gpio_func - gpio function
*                key_function long_press - long press function, needed to install
*                key_function short_press - short press function, needed to install
* Returns      : single_key_param - single key parameter, needed by key init
*******************************************************************************/
struct single_key_param *ICACHE_FLASH_ATTR
key_init_single(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func, key_function long_press, key_function short_press)
{
    struct single_key_param *single_key = (struct single_key_param *)os_zalloc(sizeof(struct single_key_param));
       
        //os_printf("+++ %s         single_key: 0x%x       gpio_id:%d   gpio_name:%d    gpio_func:%d     lone_press:0x%x      short_press : 0x%x \n",__FUNCTION__,single_key,gpio_id,gpio_name,gpio_func,long_press,short_press);

    single_key->gpio_id = gpio_id;
    single_key->gpio_name = gpio_name;
    single_key->gpio_func = gpio_func;
    single_key->long_press = long_press;
    single_key->short_press = short_press;

    return single_key;
}

/******************************************************************************
* FunctionName : key_init
* Description  : init keys
* Parameters   : key_param *keys - keys parameter, which inited by key_init_single
* Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
key_init(struct keys_param *keys)
{
    uint8 i;

    ETS_GPIO_INTR_ATTACH(key_intr_handler, keys);

    ETS_GPIO_INTR_DISABLE();

        os_printf("+++ %s    key_num: %d \n",__FUNCTION__,keys->key_num);
       
    for (i = 0; i < keys->key_num; i++) {
        keys->single_key[i]->key_level = 1;

        PIN_FUNC_SELECT(keys->single_key[i]->gpio_name, keys->single_key[i]->gpio_func);

        gpio_output_set(0, 0, 0, GPIO_ID_PIN(keys->single_key[i]->gpio_id));

        gpio_register_set(GPIO_PIN_ADDR(keys->single_key[i]->gpio_id), GPIO_PIN_INT_TYPE_SET(GPIO_PIN_INTR_DISABLE)
                          | GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_DISABLE)
                          | GPIO_PIN_SOURCE_SET(GPIO_AS_PIN_SOURCE));

        //clear gpio14 status
        GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, BIT(keys->single_key[i]->gpio_id));

        //enable interrupt
        gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_NEGEDGE);
    }

    ETS_GPIO_INTR_ENABLE();
}

/******************************************************************************
* FunctionName : key_5s_cb
* Description  : long press 5s timer callback
* Parameters   : single_key_param *single_key - single key parameter
* Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
key_5s_cb(struct single_key_param *single_key)
{
        os_printf("\n\n+++++++++++++++++      %s\n\n\n",__FUNCTION__);
    os_timer_disarm(&single_key->key_5s);

       

    // low, then restart
    if (0 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))) {
        if (single_key->long_press) {
            single_key->long_press();

                        os_printf("\n\n+++++++++++++++++     0 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))  %s\n\n\n",__FUNCTION__);
        }
    }
}

/******************************************************************************
* FunctionName : key_50ms_cb
* Description  : 50ms timer callback to check it's a real key push
* Parameters   : single_key_param *single_key - single key parameter
* Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
key_50ms_cb(struct single_key_param *single_key)
{
        os_printf("\n\n+++++++++++++++++      %s\n\n\n",__FUNCTION__);
    os_timer_disarm(&single_key->key_50ms);
       
    // high, then key is up
    if (1 == GPIO_INPUT_GET(GPIO_ID_PIN(single_key->gpio_id))) {
        os_timer_disarm(&single_key->key_5s);
        single_key->key_level = 1;
        gpio_pin_intr_state_set(GPIO_ID_PIN(single_key->gpio_id), GPIO_PIN_INTR_NEGEDGE);

        if (single_key->short_press) {
            single_key->short_press();
        }
    } else {
        gpio_pin_intr_state_set(GPIO_ID_PIN(single_key->gpio_id), GPIO_PIN_INTR_POSEDGE);
    }
}

/******************************************************************************
* FunctionName : key_intr_handler
* Description  : key interrupt handler
* Parameters   : key_param *keys - keys parameter, which inited by key_init_single
* Returns      : none
*******************************************************************************/
LOCAL void
key_intr_handler(void *arg)
{
    uint8 i;
    uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
    struct keys_param *keys = (struct keys_param *)arg;

        //os_printf("+++++++++++++++++      %s      gpio_status:%d     key_num: %d\n",__FUNCTION__,gpio_status,keys->key_num);

    for (i = 0; i < keys->key_num; i++) {
                //os_printf("+++++++++++++++++    gpio_status:%d      keys->single_key[%d]->gpio_id:%d     BIT(keys->single_key[ %d ]->gpio_id) : %d      \n",gpio_status,i,keys->single_key[i]->gpio_id,i,BIT(keys->single_key[i]->gpio_id));
        if (gpio_status & BIT(keys->single_key[i]->gpio_id)) {
                        //os_printf("+++++++++++++++++      i: %d    \n",i);


            //disable interrupt
            gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_DISABLE);

            //clear interrupt status
            GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, gpio_status & BIT(keys->single_key[i]->gpio_id));

            if (keys->single_key[i]->key_level == 1) {
                // 5s, restart & enter softap mode
                os_timer_disarm(&keys->single_key[i]->key_5s);
                os_timer_setfn(&keys->single_key[i]->key_5s, (os_timer_func_t *)key_5s_cb, keys->single_key[i]);
                os_timer_arm(&keys->single_key[i]->key_5s, 5000, 0);
                keys->single_key[i]->key_level = 0;
                gpio_pin_intr_state_set(GPIO_ID_PIN(keys->single_key[i]->gpio_id), GPIO_PIN_INTR_POSEDGE);
            } else {
                // 50ms, check if this is a real key up
                os_timer_disarm(&keys->single_key[i]->key_50ms);
                os_timer_setfn(&keys->single_key[i]->key_50ms, (os_timer_func_t *)key_50ms_cb, keys->single_key[i]);
                os_timer_arm(&keys->single_key[i]->key_50ms, 50, 0);
            }


        }

    }

}






timer中断函数:
LOCAL os_timer_t timer;
char zt = 1;

void timer_callback(){
        //if(GPIO_INPUT_GET(FUNC_GPIO2)){
               
        //} else {
        //        os_printf("GPIO2 is 0");
        //}

        unsigned int status=GPIO_INPUT_GET(FUNC_GPIO2);
        //os_printf("GPIO2 is : %d\n",status);
        if(status){
                os_printf("------GPIO2 is : %d\n",status);
        } else {
                os_printf("********%d    %d   \n",0x55,0x55);
        }
       
        if(zt == 1){
                //GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 0);
                zt = 0;
        }else{
                //GPIO_OUTPUT_SET(GPIO_ID_PIN(2), 1);
                zt = 1;
        }
}






回调函数:

void key_down50ms_func(void)
{
        os_printf("\n\n+++++++++++++++++      %s\n\n\n",__FUNCTION__);
        os_printf("key down 50ms!\n");
}

void key_down5s_func(void)
{
        os_printf("+++++++++++++++++      %s\n",__FUNCTION__);
        os_printf("start smartconfig............!\n");
       
        smartconfig_set_type(SC_TYPE_ESPTOUCH); //SC_TYPE_ESPTOUCH,SC_TYPE_AIRKISS,SC_TYPE_ESPTOUCH_AIRKISS
        wifi_set_opmode(STATION_MODE);
        smartconfig_start(smartconfig_done);
       
}



按键的初始化:
struct keys_param key;
struct single_key_param* single_key[1];


void my_key_init(void)
{
        struct single_key_param *psingle_key;// = //&single_key[0];
        psingle_key =
                        key_init_single(GPIO_ID_PIN(2),PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2,key_down5s_func,key_down50ms_func);
        key.key_num = 1;
        //key.single_key = key_init_single(2,2,(key_function)NULL,(key_function)NULL,(key_function)NULL);
        single_key[0] = psingle_key;
        key.single_key = single_key;//&psingle_key;

        key_init(&key);
}



相关帖子

沙发
coody| | 2017-9-13 14:56 | 只看该作者
看过好多键盘代码,各有优点。

我的键盘代码一般都很简单,仅仅是扫描按键,提供键码,仅此而已。
键码可以是按下、释放、重键、双击、长按,等等,根据需要取舍。键盘程序跟应用层无关,是以一个底层驱动程序存在的。

使用特权

评论回复
板凳
山东电子小菜鸟| | 2017-9-14 12:04 | 只看该作者
我看到的最好的代码是三条语句,长安 短按 双击 全部搞定

使用特权

评论回复
地板
ailingg| | 2017-12-10 11:34 | 只看该作者
struct single_key_param
这结构的定义在哪儿?

使用特权

评论回复
5
ifxz0123| | 2017-12-11 09:04 | 只看该作者

使用特权

评论回复
6
zqx1000| | 2018-4-10 23:38 | 只看该作者
kankan

使用特权

评论回复
7
天命风流| | 2018-5-10 13:41 | 只看该作者
还不错

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1334

主题

12336

帖子

53

粉丝