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