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

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

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


转载于:https://my.oschina.net/u/2345008/blog/1633174

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些关于 stm32 按键短按双击的实现方法。 对于单片机的按键处理,常见的方法是轮询法和中断法。轮询法是在主循环中不断读取按键状态,判断按键是否按下或者释放,并进行相应的处理;中断法则是通过外部中断或者定时器中断来响应按键事件。 对于按、短按和双击事件的处理,一种常见的方法是使用状态机。状态机包括多种状态和转移条件,用于描述按键事件的不同状态和状态之间的转移过程。通过按键状态的变化,可以判断出按键事件的类型,并进行相应的处理。 具体实现方法可以参考以下步骤: 1. 读取按键状态,并判断按键是否按下或者释放。 2. 根据按键状态的变化,更新状态机的状态,并记录按键的按下时间和释放时间。 3. 根据状态机的状态,判断按键事件的类型,并进行相应的处理。例如,当状态机处于“按下”状态时,如果按键持续按下的时间超过一定阈值,则判断为按事件;如果按键持续按下的时间不足阈值,则判断为短按事件;如果在一定时间内连续按下两次按键,则判断为双击事件。 4. 根据按键事件的类型,执行相应的操作。例如,按事件可以用于开启或关闭某个功能短按事件可以用于切换不同的模式;双击事件可以用于执行快速操作。 总之,实现按键短按双击需要结合具体的硬件平台和软件环境进行综合考虑,根据实际需求选择合适的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值