ESP8266 RTOS SDK学习之 Key应用

写在前面: 

本文章旨在总结备份、方便以后查询,由于是个人总结,如有不对,欢迎指正;另外,内容大部分来自网络、书籍、和各类手册,如若侵权请告知,马上删帖致歉。

虽然现在拿来学习的是 ESP8266 RTOS SDK,但是在 ESP8266 NONOS SDK中,我们可以拿一些过来应用,毕竟这两个的 SDK没有太大不同,所以我们可以直接拿来用,毕竟学会灵活应用才是最重要,好了,不说了直接贴代码分析

/*
 * ESPRSSIF MIT License
 *
 * Copyright (c) 2015 <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 "esp_common.h"

#include "key.h"


LOCAL void key_intr_handler(struct keys_param *keys);

/******************************************************************************
 * 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));

    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;
    GPIO_ConfigTypeDef *pGPIOConfig;

    pGPIOConfig = (GPIO_ConfigTypeDef*)zalloc(sizeof(GPIO_ConfigTypeDef));

    /* 配置GPIO中断的中断服务函数 */
    gpio_intr_handler_register(key_intr_handler, keys);

    ETS_GPIO_INTR_DISABLE();

    for (i = 0; i < keys->key_num; i++) {
        keys->single_key[i]->key_level = 1;

        pGPIOConfig->GPIO_IntrType = GPIO_PIN_INTR_NEGEDGE;				//enable interrupt
        pGPIOConfig->GPIO_Pullup = GPIO_PullUp_EN;						//enable GPIO pullup
        pGPIOConfig->GPIO_Mode = GPIO_Mode_Input;						//input mode
        pGPIOConfig->GPIO_Pin = (1 << keys->single_key[i]->gpio_id);	//set gpio pin for switch
        gpio_config(pGPIOConfig);

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

    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_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();
        }
    }
}

/******************************************************************************
 * 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_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(struct keys_param *keys)
{
    uint8 i;
    uint32 gpio_status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);

    for (i = 0; i < keys->key_num; i++) {
        if (gpio_status & BIT(keys->single_key[i]->gpio_id)) {
            //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) {
            	/* 启动按键长按检测定时器 */
                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 {
            	/* 启动按键短按检测定时器 */
                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);
            }
        }
    }
}

以上就是在 ESP8266 NONOS SDK的 key.c文件里面粘贴过来并分析的代码;官方的基础代码有了,接着就是弄一个个人用户接口了

/*
 * bsp_key.c
 *
 *  Created on: 2019年9月2日
 *      Author: liziyuan
 */

#include "esp_common.h"

#include "bsp_key.h"


struct single_key_param *single_key[USER_KEY_NUM];
struct keys_param keys;

/******************************************************************************
 * FunctionName : key_short_press
 * Description  : 短按处理
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR key_short_press(void)
{

}

/******************************************************************************
 * FunctionName : key_long_press
 * Description  : 长按处理
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR key_long_press(void)
{

}

/******************************************************************************
 * FunctionName : user_Key_Init
 * Description  : 按键初始化
 * Parameters   : none
 * Returns      : none
*******************************************************************************/
void ICACHE_FLASH_ATTR user_Key_Init(void)
{
	single_key[0] = key_init_single(USER_KEY1_GPIO_ID, USER_KEY1_GPIO_PER,
			USER_KEY1_GPIO_FUN, key_long_press, key_short_press);

    keys.key_num = USER_KEY_NUM;
    keys.single_key = single_key;
    key_init(&keys);
}


/*------------------------------- END OF FILE -------------------------------*/


/*
 * bsp_key.h
 *
 *  Created on: 2019年9月2日
 *      Author: liziyuan
 */

#ifndef __BSP_KEY_H
#define __BSP_KEY_H


#include "../../../include/user_config.h"
#include "../../../include/key.h"

#define USER_KEY_NUM		1		// 按键数

#define USER_KEY1_GPIO_ID  			4
#define USER_KEY1_GPIO_FUN 			FUNC_GPIO4
#define USER_KEY1_GPIO_PER			PERIPHS_IO_MUX_GPIO4_U

void ICACHE_FLASH_ATTR user_Key_Init(void);


#endif /* __BSP_KEY_H */


/*------------------------------- END OF FILE -------------------------------*/


这样,我们就可以在 bsp_key.c自己的文件里添加自己想要的功能,而不会看起来混乱

发布了31 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_42992084/article/details/102967373
今日推荐