一份按键驱动框架

简介

这份是我在实际工作中摸索并逐步形成的一个比较好与可扩展性比较稳定的按键驱动框架,自己已经在51和ARM中都运行过,无论是普通实体按键还是触摸按键皆可采用,主要实现了长按和短按功能,按键是嵌入式中一个不可忽视和必须掌握的功能,故分享之。

参考代码
//1.实体按键,以STM32F0(Cotex_M0)芯片为例
//api function:
void Button_getValue(keyEvent_st *keyEvent_me);//键值获取函数
void Button_scanEvent(keyEvent_st *keyEvent_me);//按键扫描函数
void Button_trigEvent(keyEvent_st *keyEvent_me);//按键单按事件
void Button_holdEvent(keyEvent_st *keyEvent_me);//按键长按事件

//----------------------------按键相关数据结构---------------------------------
typedef enum
{
  KEY_NULL=0,
  KEY_1,
  KEY_2,
  //...
}keyId_em;

typedef struct
{
  unsigned char now; //按键当前状态
  unsigned char last;//按键前次状态
}keyStatus_st;

typedef struct
{
  keyStatus_st status; //按键状态
  keyId_em tirg_id;  //按键触发量id(唯一性)
  keyId_em hold_id;  //按键保持量id(唯一性) 
  unsigned char value;  //按键键值(包含组合键值)
  unsigned int  hold_rtimer; //按下计时器(公共性)
}keyEvent_st;

keyEvent_st  keyEvent;

//--------------------------按键硬接口宏定义---------------------------------
#define  BUTTON_PORT     GPIOA
#define  BUTTON_1_PIN    GPIO_Pin_1
#define  BUTTON_1_PIN    GPIO_Pin_2

#define  KEY1()           GPIO_ReadInputDataBit(BUTTON_PORT,BUTTON_1_PIN)
#define  KEY2()           GPIO_ReadInputDataBit(BUTTON_PORT,BUTTON_2_PIN)
#define  KEY_ACTION      (KEY1()&&KEY2())

//---------------------------按键运行元时间---------------------------------
#define KEY_SLICE_TIME 10  
//---------------------------键值获取函数-------------------------------------
void Button_getValue(keyEvent_st *keyEvent_me)
{
	if(RESET==KEY_ACTION) //有按键按下(在本硬件上,RESET:按下;SET:弹起)
	{
		if(RESET==KEY1())
		{
			keyEvent_me->value=1; //键值1
		}
		else if(RESET==KEY2())
		{
			keyEvent_me->value=2;//键值2
		}
		 //....以此类推
	}
	else //无按键按下
	{
	   keyEvent_me->value=NULL;//无键值
	}
}

//-----------按键扫描函数-------
void Button_actionEvent(keyEvent_st *keyEvent_me)
{
	Button_getValue(keyEvent_me);//扫描按键
	if(NULL!=keyEvent_me->value)//有键值
	{
		keyEvent_me->status.now=1;//状态置位
	}
	else
	{
		keyEvent_me->status.now=NULL;
	}
   //-----------------按键动作--------------
	if(keyEvent_me->status.now)//有按下
	{
		keyEvent_me->hold_rtimer++;//长按计时
		if(keyEvent_me->status.last!=keyEvent_me->status.now)//按键有变化
		{
			if(keyEvent_me->status.now)//为按下动作
			{
			    keyEvent_me->hold_id=(keyId_em)keyEvent_me->value;
				keyEvent_me->trig_id=(keyId_em)keyEvent_me->value;
			}
		}
	}
	else  //没有按下
	{
		keyEvent_me->hold_rtimer=0;//
	}
	keyEvent_me->status.last=keyEvent_me->status.now;//记录当前按键末态状态
}

//-----------触发型处理函数【用于点(短)按事件处理】-----
void Button_trigEvent(keyEvent_st *keyEvent_me)
{
  switch(keyEvent_me->trig_id)
  {
     case KEY_1:
     //相关处理函数
     break;
     case KEY_2:
     //相关处理函数         
     break; 
     //...以此类推
     default:
     break;    
  }
  keyEvent_me->tirg_id=NULL;//用完立即释放
}

//-----------保持型处理函数【用于按住不放事件的处理】-----
void Button_holdEvent(keyEvent_st *keyEvent_me)
{

#define KEY1_HOLD_TIME1  (100/KEY_SLICE_TIME) //长按时间数
#define KEY2_HOLD_TIME1  (300/KEY_SLICE_TIME) //长按时间数

 switch(keyEvent_me->hold_id)
 {
	 case KEY_1:
	 //for example
	 if(KEY1_HOLD_TIME1<keyEvent_me->hold_rtimer)
	 {
		 //相关处理函数 
	 } 
	 break;
	 case KEY_2:
	 if(KEY2_HOLD_TIME1<keyEvent_me->hold_rtimer)
	 {
		 //相关处理函数 
	 }          
	 break; 
	 //...以此类推
	 default:
	 break;       
 }
}

//----------------放置在定时时间片内运行----------------------
void Button_Thread(void)
{
   Button_actionEvent(&keyEvent);
   Button_trigEvent(&keyEvent);
   Button_holdEvent(&keyEvent);
}

该驱动框架结构多有不合理之处,为此做了优化,可移步该文按键驱动框架优化鉴阅。


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值