key.h
/*
* key.h
*
* Created on: 2018年12月24日
* Author: 王杰龙
*/
#ifndef APP_INCLUDE_USER_DRIVER_KEY_H_
#define APP_INCLUDE_USER_DRIVER_KEY_H_
#include "c_types.h"
//使用的GPIO口:GPIO5、GPIO4、GPIO0
#define key_range 0x31 //使用GPIO那个口将对应的为写一
#define K1_longtrg 15 //K1长按触发时间
#define K2_longtrg 15 //K2长按触发时间
#define K3_longtrg 100 //K3长按触发时间
#define timer_time 30 //定时器扫描时间(ms)
typedef void (* key_function)(void);//定义一个指向void (* key_function)(void)类型的指针函数
/********************存储单个按键相关配置数据***************************/
struct single_key_param {
uint8 key_level; //按键处理流程标号
uint8 gpio_id; //GPIO引脚号(0-15)
uint8 gpio_func; //GPIO 功能
uint32 gpio_name; //GPIO MUX寄存器
key_function short_press; //按键短按处理程序
key_function long_press; //按键长按处理程序
};
/************************end*******************************/
/************************存储全部按键参数*************************/
struct keys_param {
uint8 key_num; //按键的数量
struct single_key_param **single_key; //按键的相关信息,用来存储数组的地址
};
/************************end*******************************/
/************************函数声明*******************************/
struct single_key_param *key_init_single(uint8 gpio_id, uint32 gpio_name, uint8 gpio_func, key_function long_press, key_function short_press);
void key_init(struct keys_param *key);
void key_timer_arm(void);//按键定时器开
void key_timer_disarm(void);//按键定时器关
/************************end*******************************/
#endif /* APP_INCLUDE_USER_DRIVER_KEY_H_ */
key.c
/*
* key_v1.0.c
*
* Created on: 2018年12月24日
* Author: 王杰龙
*/
#include "ets_sys.h"
#include "os_type.h"
#include "osapi.h"
#include "mem.h"
#include "gpio.h"
#include "user_interface.h"
#include "user_driver/key.h"
LOCAL os_timer_t key_timer;//使用一个定时器用来扫描按键
uint8 Flag=0,key_value=0,Long_Cont=0;//定义三个参数用来保存按键的状态
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;
}
LOCAL void ICACHE_FLASH_ATTR
timer_Callback(struct keys_param *keys)
{
uint8 ReadData=((uint8)gpio_input_get()&key_range)^key_range;
if(ReadData!=0x00){
if(Flag<50) {
Flag++;
key_value=ReadData;
}
else {
switch(ReadData){
case 0x01:
if(Long_Cont>K1_longtrg){
keys->single_key[0]->long_press();
Long_Cont=0;
}
break;
case 0x10:
if(Long_Cont>K2_longtrg){
keys->single_key[1]->long_press();
Long_Cont=0;
}
break;
case 0x20:
if(Long_Cont>K3_longtrg){
keys->single_key[2]->long_press();
Long_Cont=0;
}
break;
default : break;
}
Long_Cont++;
key_value=0;
}
}
else{
switch(key_value){
case 0x01://K1
keys->single_key[0]->short_press();
break;
case 0x10://K2
keys->single_key[1]->short_press();
break;
case 0x20://K2
keys->single_key[2]->short_press();
break;
default :break;
}
Flag=0;
key_value=0;
}
}
void ICACHE_FLASH_ATTR
key_timer_arm(void){//按键定时器开
os_timer_arm(&key_timer,timer_time,1);//使能毫秒定时器
}
void ICACHE_FLASH_ATTR
key_timer_disarm(void){//按键定时器关
os_timer_disarm (&key_timer);//关闭毫秒定时器
}
/******************************************************************************
* 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_DISABLE();//关GPIO中断
for (i = 0; i < keys->key_num; i++) {
PIN_FUNC_SELECT(keys->single_key[i]->gpio_name, keys->single_key[i]->gpio_func);//配置管脚为GPIO模式
gpio_output_set(0, 0, 0, GPIO_ID_PIN(keys->single_key[i]->gpio_id));//配置GPIO为输入模式
PIN_PULLUP_EN(keys->single_key[i]->gpio_name);//使能内部上拉
//关于 GPIO 的上电IO 口默认状态为:除了 SDIO6根线 +GPIO4+GPIO5+GPIO16 上电 IO 默认无上拉,其他的GPIO 口均有上拉。
}
//使用一个软件定时器来检测长按短按
os_timer_disarm (&key_timer);//关闭second_timer
os_timer_setfn(&key_timer,(os_timer_func_t *)timer_Callback,keys);//设置定时器回调函数
ETS_GPIO_INTR_ENABLE();//开GPIO中断
}
key_init
/************************按键初始化************************/
void ICACHE_FLASH_ATTR
Key_Init(void)
{
LOCAL struct keys_param key;//按键的参数
LOCAL struct single_key_param *psingle_key[3];//单一按键的参数
psingle_key[0] =//K1用作++
key_init_single(GPIO_ID_PIN(0),PERIPHS_IO_MUX_GPIO0_U,FUNC_GPIO0,K1_long_func,K1_short_func);
psingle_key[1] =//K2用作--
key_init_single(GPIO_ID_PIN(4),PERIPHS_IO_MUX_GPIO4_U,FUNC_GPIO4,K2_long_func,K2_short_func);
psingle_key[2] =//K3
key_init_single(GPIO_ID_PIN(5),PERIPHS_IO_MUX_GPIO5_U,FUNC_GPIO5,K3_long_func,K3_short_func);
key.key_num = 3;
key.single_key = &psingle_key[0];
key_init(&key);
}