乐鑫Esp32学习之旅⑦ esp32上利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。(附带Demo)


  • 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。

1、 爬坑学习新旅程,虚拟机搭建esp32开发环境,打印 “Hellow World”。
2、 巧用eclipes编辑器,官方教程在在Windows下搭建esp32开发环境,打印 “Hellow World”。
3、 认识基本esp32的GPIO接口,开始点亮您的第一盏 LED和中断回调实现按键功能 。
4、体会esp32的强大的定时器功能, 实现定时2s闪烁一盏LED灯。
5、接触实践esp32的pwm宽度脉冲功能, 实现呼吸效果闪烁一盏LED灯。
6、smartConfig和微信airKiss在esp32的实现,一键配网轻松快捷连接路由器。
7、利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。
8、esp32上实现本地 UDP 客户端和服务端角色,在局域网内实现通讯。
9、esp32上实现本地 TCP 客户端和服务端角色,可断线重连原路返回数据。
10、乐鑫esp32 SDK编程利用rmt驱动ws2812七彩灯,实现彩虹渐变效果。
11、入门 乐鑫esp-adf 音频框架开发,esp32造一个蓝牙耳机,实现切换歌曲,获取歌曲信息等功能。
12、开源一个微信公众号airkiss配网esp32以及局域网发现功能的工程,分享一个airkiss配网小工具。
13、esp32 内置 dns 服务器,无需外网访问域名返回指定网页。
14、esp32 sdk编程实现门户强制认证,连接esp32热点之后,自动强制弹出指定的登录界面。
15、认识本地离线语音唤醒识别框架 esp-skainet ,实现较低成本的硬件语音本地识别控制。
16、学习本地语音唤醒离线识别框架 esp-skainet ,如何修改唤醒词? 如何自定义命令词?如何做意图动作?
17、全网首发,乐鑫esp32 sdk直连京东微联·小京鱼 · IoT开放平台,实现叮咚音响语音智能控制。


一. 前言;


  • 说到按键的短按和长按,很多人都是直接用while(1)死循环不断去读取按键和消抖,通过读取时间的间隔来确定是长按还是短按!这种方法比较常用,今天的话,小徐给大家带来的是:esp32上利用GPIO中断做一个按键的短按和长按的回调事件!更高级,更深入去了解esp32

乐鑫Esp32学习之旅⑦ esp32上利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。(附带Demo)_第1张图片


二.代码思维图;


乐鑫Esp32学习之旅⑦ esp32上利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。(附带Demo)_第2张图片


上图看的逻辑也是比较清晰了,那么我这里用的是中断和freeRtos任务切换来实现:


二.代码;


  • 第一步:先初始化GPIO,注意配置为下降沿和上升沿触发中断,这样就可以在按下和抬起之间来发送消息给消息队列了!
    //配置GPIO,下降沿和上升沿触发中断
	gpio_config_t io_conf;
	io_conf.intr_type = GPIO_INTR_ANYEDGE;
	io_conf.pin_bit_mask = 1 << key_gpio_pin;
	io_conf.mode = GPIO_MODE_INPUT;
	io_conf.pull_up_en = 1;
	gpio_config(&io_conf);

	gpio_set_intr_type(key_gpio_pin, GPIO_INTR_ANYEDGE);
	gpio_evt_queue = xQueueCreate(2, sizeof(uint32_t));
    //注册中断服务
	gpio_install_isr_service(0);
	gpio_isr_handler_add(key_gpio_pin, gpio_isr_handler, (void *) key_gpio_pin);

  • 第二步:新建一个任务不断去接收任务送来的中断回调信息,其代码如下!

	uint32_t io_num;
	BaseType_t press_key = pdFALSE;
	BaseType_t lift_key = pdFALSE;
	int backup_time = 0;

	while (1) {

		//接收从消息队列发来的消息
		xQueueReceive(gpio_evt_queue, &io_num, ticks_to_wait);

		//记录下用户按下按键的时间点
		if (gpio_get_level(io_num) == 0) {
			press_key = pdTRUE;
			backup_time = system_get_time();
			//如果当前GPIO口的电平已经记录为按下,则开始减去上次按下按键的时间点
		} else if (press_key) {
			//记录抬升时间点
			lift_key = pdTRUE;
			backup_time = system_get_time() - backup_time;
		}

		//仅仅当按下标志位和按键弹起标志位都为1时候,才执行回调
		if (press_key & lift_key) {
			press_key = pdFALSE;
			lift_key = pdFALSE;

			//如果大于1s则回调长按,否则就短按回调
			if (backup_time > 1000000) {
				return KEY_LONG_PRESS;
			} else {
				return KEY_SHORT_PRESS;
			}
		}
	}

  • 第三步:看看我们的回调事件,其代码如下!
	esp_err_t ret = 0;
	KeyInit(KEY_GPIO);

	while (1) {
		ret = alink_key_scan(portMAX_DELAY);
		//如果错误则跳出任务
		if (ret == -1)
			vTaskDelete(NULL);

		switch (ret) {
		case KEY_SHORT_PRESS:
			printf("短按触发回调 ... \r\n");
			break;

		case KEY_LONG_PRESS:
			printf("长按触发回调 ... \r\n");
			break;

		default:
			break;
		}
	}

三.其他;


上面代码的1000000是指1s,如果您要改变长按2秒以上才算长按,那么可以修改这个数值!


串口打印:

乐鑫Esp32学习之旅⑦ esp32上利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。(附带Demo)_第3张图片


本硬件的代码下载:https://download.csdn.net/download/xh870189248/10450163

esp32汇总工程,欢迎star,收到第一更新信息:https://github.com/xuhongv/StudyInEsp32

你可能感兴趣的:(乐鑫Esp32,乐鑫Esp32学习之旅)