看了他的ESP32实现双击和单击识别,太复杂了。
https://blog.csdn.net/xiaolongba/article/details/80791148
看看我的原创,如果您觉得我写的有意思,麻烦点赞,让我更有动力写更好的代码。
代码下载地址:
https://download.csdn.net/download/qq_31806069/11541239
1、 初始化GPIO
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
if (gpio_num ==GPIO_INPUT_IO_0 && 0 == gpio_get_level(GPIO_INPUT_IO_0))
{
my_time_start(true);
}
}
void my_gpio_init(void)
{
static gpio_config_t io_conf;
//interrupt of rising edge
io_conf.intr_type = GPIO_INTR_ANYEDGE;
//bit mask of the pins, use GPIO4/5 here
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
//set as input mode
io_conf.mode = GPIO_MODE_INPUT;
//enable pull-up mode
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
//install gpio isr service
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_0, gpio_isr_handler, (void*) GPIO_INPUT_IO_0);
//hook isr handler for specific gpio pin
gpio_isr_handler_add(GPIO_INPUT_IO_1, gpio_isr_handler, (void*) GPIO_INPUT_IO_1);
printf("caicai hello world\n");
}
2、 设置定时器
static void periodic_timer_callback(void* arg)
{
#define MY_BUTTON_ERROR_FALG 0xff;
key_work_time +=TIME_INTER_MS;
//printf("key_work_time:%d\n",key_work_time);
//printf("key_state:%d-%d\n",key_state,key_work_time/1000);
switch(key_state)
{
case 0x00://after 20ms
if ( 0 == gpio_get_level(GPIO_INPUT_IO_0) )//press button
{
key_state = 1;
key_press_times++;
key_neg_time+=TIME_INTER_MS;
}else
{
key_press_times = MY_BUTTON_ERROR_FALG;
goto time_error;
}
break;
case 0x01:
if ( 0 == gpio_get_level(GPIO_INPUT_IO_0) )//press button
{
key_neg_time+=TIME_INTER_MS;
}else
{
key_neg_time = 0;
key_pos_time+=TIME_INTER_MS;
key_state = 2;
}
if(key_neg_time > TIME_NEG_TIMEOU_MS)
{
key_press_times = MY_BUTTON_ERROR_FALG;
goto time_error;
}
break;
case 0x02:
if ( 0 == gpio_get_level(GPIO_INPUT_IO_0) )
{
key_neg_time+=TIME_INTER_MS;
if (key_neg_time > 20)
{
key_state= 0x01;
key_press_times++;
key_pos_time =0;
}
}else
{
key_pos_time+=TIME_INTER_MS;
}
if(key_pos_time > TIME_POS_TIMEOU_MS)
{
//over
goto time_error;
}
break;
}
return;
time_error:
printf("--->key_press_times:%d\n",key_press_times);
xQueueSendFromISR(gpio_evt_queue, &key_press_times, NULL);
key_work_time =0;
key_pos_time = 0;
key_neg_time = 0;
key_press_times =0;
key_state = 0;
my_time_start(false);
}
void my_time_init(void)
{
const esp_timer_create_args_t periodic_timer_args = {
.callback = &periodic_timer_callback,
/* name is optional, but may help identify the timer when debugging */
.name = "periodic"
};
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
}
void my_time_start(bool is_start)
{
static bool my_time_state = false;
if (my_time_state == is_start) return;
my_time_state = is_start;
//printf("my time open:%d\r\n",is_start);
if (is_start)
{
/* Start the timers */
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, TIME_INTER_MS));
}else
{
ESP_ERROR_CHECK(esp_timer_stop(periodic_timer));
}
}
3、 主函数
static xQueueHandle gpio_evt_queue = NULL;
#define GPIO_INPUT_IO_0 4
#define GPIO_INPUT_IO_1 5
#define GPIO_INPUT_PIN_SEL ((1ULL<<GPIO_INPUT_IO_0) | (1ULL<<GPIO_INPUT_IO_1))
#define ESP_INTR_FLAG_DEFAULT 0
#define TIME_INTER_MS (20*1000)
#define TIME_WORK_TIMEOU_MS (250*1000)
#define TIME_NEG_TIMEOU_MS (250*1000)
#define TIME_POS_TIMEOU_MS (150*1000)
uint32_t key_work_time =0;
uint32_t key_pos_time = 0;
uint32_t key_neg_time = 0;
uint32_t key_press_times =0;
uint8_t key_state = 0;
esp_timer_handle_t periodic_timer;
void my_time_start(bool is_start);
void app_main()
{
//create a queue to handle gpio event from isr
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
my_gpio_init();
my_time_init();
uint32_t show_key_times;
while(1)
{
if(xQueueReceive(gpio_evt_queue, &show_key_times, portMAX_DELAY)) {
printf("press key times %d\n", show_key_times);
}
}
}
效果图:
能识别出单击、双击、三击、。。。。
牛逼!