乐鑫Esp32学习之旅⑦ esp32上利用GPIO中断做一个按键的短按和长按的回调事件,再也无须担心触发源。(附带Demo)
Posted on 2018-05-31 15:13 CoreHouse 阅读(1298) 评论(0) 收藏 举报- 本系列博客学习由非官方人员 半颗心脏 潜心所力所写,仅仅做个人技术交流分享,不做任何商业用途。如有不对之处,请留言,本人及时更改。
 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。
二.代码思维图;
上图看的逻辑也是比较清晰了,那么我这里用的是中断和
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秒以上才算长按,那么可以修改这个数值!
串口打印:
本硬件的代码下载:https://download.csdn.net/download/xh870189248/10450163
esp32汇总工程,欢迎star,收到第一更新信息:https://github.com/xuhongv/StudyInEsp32
 
                    
                     
                    
                 
                    
                 
 
         
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号