Key polling algorithm (including short press and long press functions)

Button polling algorithm, including long press and short press function, this algorithm needs to use the software timer algorithm released before to obtain the system time.

  • 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);
}


Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324519219&siteId=291194637