文档章节

按键轮询算法(含短按和长按功能)

猎人嘻嘻哈哈的
 猎人嘻嘻哈哈的
发布于 2018/03/12 09:26
字数 401
阅读 193
收藏 0

按键轮询算法,含长按短按功能,本算法需要使用到之前发布的软件定时器算法来获取系统时间。

  • commKey.h
#ifndef _COMM_KEY_H_
#define _COMM_KEY_H_


#include "timer_callback.h"

#define COMM_KEY_UP 1
#define COMM_KEY_DOWN 0

typedef int(*key_callback_func)(void*);

typedef enum {
	COMM_KEY_IDLE_STATUS =4,
	COMM_KEY_DOWN_STATUS =0,
	COMM_KEY_DOWN_SURE_STATUS =5,
	COMM_KEY_UP_STATUS =6,
	COMM_KEY_UP_SURE_STATUS =1,
	COMM_KEY_SHORT_PRESS =2,
	COMM_KEY_LONG_PRESS =3
}comm_key_status;

typedef struct{
	/*获取按键状态*/
	key_callback_func key_status_get_func;
	/*短按回调函数*/
	key_callback_func key_short_press_func;
	/*长按回调函数*/
	key_callback_func key_long_press_func;
	/*短按时间*/
	unsigned int short_press_time;
	/*长按时间*/
	unsigned int long_press_time;
	/*消抖时间*/
	unsigned int shake_time;
	/*消抖计时器*/
	TICK shake_timer;
	/*按下计时器*/
	TICK key_timer;
	/*按键号*/
	unsigned char key_index;
	/*按键状态*/
	comm_key_status key_status;
}comm_key_info;


typedef struct comm_key_list{
	comm_key_info key;
	struct comm_key_list* key_next;
}comm_key_list;



u8 commKeyAdd(comm_key_list* key);
void commKeyTask(void);
void keyTest(void);


#endif


  • comm_key.c
#include "comm_key.h"
#include "stdlib.h"
#include "board.h"


comm_key_list* key_head=NULL;

typedef enum {
	COMM_KEY_OK=0,
	COMM_KEY_NO_SPACE=1,
	COMM_KEY_NO_KEY=2
}func_return;

u8 commKeyAdd(comm_key_list* key)
{
	comm_key_list* tpk;
	tpk = key_head;
    if(key_head==NULL)
    {
        key_head=(comm_key_list*)malloc(sizeof(comm_key_list));
			  if(key_head==NULL)
				return COMM_KEY_NO_SPACE;
        *key_head=*key;
        key_head->key_next=NULL;
        return COMM_KEY_OK;
    }
	while(tpk->key_next!=NULL)
    {
        tpk=tpk->key_next;
    }
    tpk->key_next=(comm_key_list*)malloc(sizeof(comm_key_list));
		if(tpk->key_next==NULL)
			return COMM_KEY_NO_SPACE;
    *(tpk->key_next)=*key;
    tpk->key_next->key_next=NULL;
		return COMM_KEY_OK;
}
void commKeyMove(comm_key_list* key)
{
}
unsigned char commKeyGetNum(void)
{
	return 1;
}

void commKeyTask(void)
{
	comm_key_list* tpk=key_head;
	
	while(tpk!=NULL)
	{	
		GET_TICK(tpk->key.shake_timer.tick_temp);
		if((tpk->key.shake_timer.tick_temp-tpk->key.shake_timer.tick_begin)>tpk->key.shake_time)
		{
			switch (tpk->key.key_status)
			{
				case COMM_KEY_IDLE_STATUS:
					if(COMM_KEY_DOWN==tpk->key.key_status_get_func(NULL))
					{
						tpk->key.key_status=COMM_KEY_DOWN_SURE_STATUS;
						/*开始去抖动*/
						GET_TICK(tpk->key.shake_timer.tick_begin);
					}
					break;			
				case COMM_KEY_DOWN_SURE_STATUS:
					if(COMM_KEY_DOWN==tpk->key.key_status_get_func(NULL))
					{
						tpk->key.key_status=COMM_KEY_UP_STATUS;
						/*开始计时按下时间*/
						GET_TICK(tpk->key.key_timer.tick_begin);
					}
					else
					{
						tpk->key.key_status=COMM_KEY_IDLE_STATUS;
					}
					break;
				case COMM_KEY_UP_STATUS:
					if(COMM_KEY_UP==tpk->key.key_status_get_func(NULL))
					{
						tpk->key.key_status=COMM_KEY_UP_STATUS;
						GET_TICK(tpk->key.key_timer.tick_temp);
						
						if((tpk->key.key_timer.tick_temp-tpk->key.key_timer.tick_begin)>tpk->key.long_press_time)
						{
							if(tpk->key.key_long_press_func!=NULL)
							tpk->key.key_long_press_func(NULL);
						}
						else
						{
							if(tpk->key.key_short_press_func!=NULL)
							tpk->key.key_short_press_func(NULL);
						}
						tpk->key.key_status=COMM_KEY_IDLE_STATUS;
					}
					break;
				default:
					break;
			}
		}
		tpk=tpk->key_next;
	}
	
}



void keyTest(void)
{
//	comm_key_list key;
//	key.key_next=NULL;
//	key.key.key_index=0;
//	key.key.key_long_press_func=NULL;
//	key.key.key_short_press_func=keyLongPress;
//	key.key.key_status=COMM_KEY_IDLE_STATUS;
//	key.key.key_status_get_func=getKeyStatus;
//	key.key.long_press_time=5000;
//	key.key.shake_time=10;
//	key.key.short_press_time=200;
//	commKeyAdd(&key);
}


© 著作权归作者所有

猎人嘻嘻哈哈的
粉丝 4
博文 8
码字总数 4150
作品 0
荆州
程序员
私信 提问
C程序实现监听长按物理power键3秒关机功能

要实现的功能:在android Framework层被裁剪掉的情况下,实现监听长按的物理power按键,实现长按3秒后关机功能; 思路:使用event epoll,非阻塞式IO操作,同时避免无差别轮询,做到避免忙轮...

楼中望月
2017/11/13
0
0
基于状态转移的独立按键程序设计

从网上搜集而来,出处不可考。感谢原作者。 对于按键处理讲得很透彻。 从这一章开始,我们步入按键程序设计的殿堂。在基于单片机为核心构成的应用系统中,用户输入是必不可少的一部分。输入可...

memorybox
2012/08/19
542
0
单片机中按键的短按,长按,单击,多击的驱动程序实现

接触过的按键驱动中,大部分是使用延时函数消抖,或者是在扫描到按键状态之后,直接就在按键扫描程序内部对事件进行处理。一直在思考一个不使用延时函数同时兼容性和移植性较强的按键驱动程序...

cheerk
2018/04/12
0
0
AndroidFm模块学习之四源码解析(十一)

接上一篇,接下来看看androidvendorqcomopensourcefmfmapp2srccomcaffmradioFmTags.java 当点击FMRadio.java菜单的全部频道选项,跳转到FmTags.java类 定义了一个ListView控件和一个简单适配...

天王盖地虎626
01/08
20
0
Android7.0 PowerManagerService(4) Power按键流程

版权声明:转载请注明:http://blog.csdn.net/gaugamela/article https://blog.csdn.net/Gaugamela/article/details/52912382 按键的处理主要由InputManagerService负责,属于Android输入系统......

ZhangJianIsAStark
2016/10/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

mac下redis安装、设置、启动停止

常用命令说明 redis服务器:redis-server redis客户端:redis-cli redis性能测试工具:redis-benchmark AOF文件修复工具:redis-check-aof RDB文件修复工具:redis-check-rd redis设置临时密...

botkenni
8分钟前
3
0
好程序员web前端分享HTML5常见面试题集锦四

好程序员web前端分享HTML5常见面试题集锦四 1、为什么要初始化CSS样式? 答案:因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对CSS初始化往往会出现浏览器之间的页面...

好程序员官方
9分钟前
2
0
CDN的网络架构是什么?

CDN网络架构主要由两大部分,分为中心和边缘两部分,中心指CDN网管中心和DNS重定向解析中心,负责全局负载均衡,设备系统安装在管理中心机房,边缘主要指异地节点,CDN分发的载体,主要由Cac...

云漫网络Ruan
10分钟前
2
0
pandas入门07---可视化

01 入门 制作提供信息的可视化是数据分析的重要任务之一。首先介绍一下matplotlib库。 import matplotlib.pyplot as pltimport numpy as npdata = np.arange(10)print(data)plt.plot(da...

筠初
11分钟前
2
0
201_PyTorch中文教程:Torch与Numpy互操作

201_PyTorch中文教程:Torch与Numpy互操作 更多参考: https://morvanzhou.github.io/tutorials/ 油管频道:https://www.youtube.com/user/MorvanZhou 依赖软件包: torch numpy Torch的更多数......

openthings
11分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部