最近在使用安信可esp8266_12F做一个oled显示时间,然后按键调整时间,虽然SDK有按键的驱动,但他不适用于调整时间,基于sdk里给的key,自己封装了用于调整时间的按键驱动,由于esp8266按键少,使用了GPIO16。GPIO0用于++,GPIO2用于–,GPIO16用于切换,GPIO16引脚使用3.3k电阻上拉。
- user_main.c
void ICACHE_FLASH_ATTR
user_rf_pre_init(void)
{
}
void ICACHE_FLASH_ATTR
K1_long_func(void)
{
os_printf("K1_long_func!\n");
}
void ICACHE_FLASH_ATTR
K1_short_func(void)
{
os_printf("K1_short_func!\n");
}
void ICACHE_FLASH_ATTR
K2_long_func(void)
{
os_printf("K2_long_func!\n");
}
void ICACHE_FLASH_ATTR
K2_short_func(void)
{
os_printf("K2_short_func!\n");
}
void ICACHE_FLASH_ATTR
K3_shift_func(void)//shift
{
os_printf("K3_short_func!\n");
}
void ICACHE_FLASH_ATTR
Key_Init(void)
{
LOCAL struct keys_param key;//按键的参数
LOCAL struct single_key_param *psingle_key[2];//单一按键的参数
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(2),PERIPHS_IO_MUX_GPIO2_U,FUNC_GPIO2,K2_long_func,K2_short_func);
key.key_num = 2;
key.shift_press= K3_shift_func;
key.single_key = &psingle_key[0];
key_init(&key);
}
void ICACHE_FLASH_ATTR
user_init(void)
{
Key_Init();
}
- key.c
#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 os_timer_t key_timer;
uint8 Trg=0,Cont=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;
}
/******************************************************************************
* FunctionName : key_init
* Description : init keys
* Parameters : key_param *keys - keys parameter, which inited by key_init_single
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
timer_Callback(struct keys_param *keys)
{
uint8 ReadData=((gpio16_input_get()|(uint8)gpio_input_get())&0x85)^0x85;
Trg=ReadData&(ReadData^Cont);
Cont=ReadData;
if(ReadData!=0x00){
switch(Trg){
case 0x01:{//K1
keys->single_key[0]->short_press();
break;
}
case 0x04:{//K2
keys->single_key[1]->short_press();
break;
}
case 0x80:{//shift
keys->shift_press();
break;
default :{
if(Long_Cont>15){
Long_Cont=0;
switch(Cont){
case 0x01: {
keys->single_key[0]->long_press();
break;
}
case 0x04: {
keys->single_key[1]->long_press();
break;
default : return;
}
}
}
Long_Cont++;
return;
}
}
}
}
else {
Long_Cont=0;
return;
}
}
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为输入模式
}
gpio16_input_conf();//将GPIO16配置为输入模式
//使用一个软件定时器来检测长按短按
os_timer_disarm (&key_timer);//关闭second_timer
os_timer_setfn(&key_timer,(os_timer_func_t *)timer_Callback,keys);//设置定时器回调函数
os_timer_arm(&key_timer,50,1);//使能毫秒定时器
ETS_GPIO_INTR_ENABLE();//开GPIO中断
}
- GPIO16.c
这里用到了GPIO16的输入,要改下下面的这里
uint8 ICACHE_FLASH_ATTR
gpio16_input_get(void)
{
return (READ_PERI_REG(RTC_GPIO_IN_DATA)<<7);
}