关于NRF52810 实现按键的长按及单双击

NRF52810 实现按键的长按及单双击
在做nordic nrf52810的芯片的项目中要用到按键的长按以及单双击,实现的过程主要是通过库文件的一些函数,对一些要用到的函数内容进行稍加改动完成的,库文件为bsp.c文件,下面主要是实现的流程:
1.首先我们要对按键进行配置

app_button_cfg_t app_buttons[BUTTONS_NUMBER] = {{BSP_BUTTON_0,false,BUTTON_PULL,bsp_button_event_handler},};

这里只是对BUTTON0进行了配置;
2.然后实现按键的事件函数
(bsp_button_event_handler(uint8_t pin_no,uint8_t button_action)),按键中主要有三个事件:按键按下、按键释放以及长按;
(1)当按键按下时,就会开启两个定时器,一个用来判断是否为长按还是短按,另一个为判断单双击;
判断长按短按:当按键按下时,超过一秒还没有释放按键我们就认定为长按,在超时函数中设置按键为长按事件,一秒内释放认定为短按;
判断单双击:当按键按下时,在没有超时的时间内,每按下一次标志位 click_count 就加一,然后在超时函数中清零标志位,执行回调函数,最后在此按键下通过标志位的值来判断单双击。
(2)当按键释放时,要停止判断长按的定时器,然后把按键释放的事件赋值给event
(3)当按键为长按时,会把长按事件赋值给event;
最后就会执行回调函数。
下图为函数的实现过程

void bsp_button_event_handler(uint8_t pin_no,uint8_t button_action)
{
	bsp_event_t event = BSP_EVENT_NOTHING;
	uint32_t button = 0;
	uint32_t err_code;
	static uint8_t current_long_push_pin_no;
	static bsp_event_t release_event_at_push[BUTTONS_NUMBER];
	button = bsp_board_pin_to_button_idx(pin_no);
	if(button<BUTTONS_NUMBER)
	{
	   switch(button_action)
	   {
	     case APP_BUTTON_PUSH: //按键按下事件
	       if(m_events_list[button].long_push_event != BSP_EVENT_NOTHING)
	       {
	         app_timer_start(click_button_id,BUTTON_CLICK_INTERAL,NULL);//判断单双击
	         app_timer_start(bsp_button_id,APP_TIMER_TICKS(BSP_LONG_PUSH_TIMER),NULL);//判断长按短按
	         if(err_code == NRF_SUCCESS)
	         {
	           current_log_push_pin_no = pin_no;
	         }
	         click_count++;
	       }
	       break;
	      case APP_BUTTON_RELEASE://按键释放事件
	         app_timer_stop(bsp_button_id);
	         if(release_event_at_push[button] == m_events_list[button].release_event)
	         {
	           event = m_events_list[button].release_event;
	         } 
	         break;
	        case BSP_BUTTON_ACTION_LONG_PUSH://长按事件
	          event = m_events_list[button].release_event;
	          release_event_at_push[button] = m_event_list[button].long_push_event;
	   }
    }
    if((event != BSP_EVENT_NOTHING) && (m_registerd_callback != NULL))
    {
      m_registered_callback(event); //执行回调函数 
    }
}

3. 修改bsp_init 函数
在bsp_init 函数中主要修改事件分配函数,使之对应不同的按键及事件;

uint32_t bsp_init(uint32_t type,bsp_event_callback_t callback)
{
	uint32_t err_code = NRF_SUCCESS;
	#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
	m_indication_type = type;
	#endif

    #if BUTTONS_NUMBER > 0 && !(defined BSP_SIMPLE)
	m_registered_callback = callback;
	#endif
	if(type & BSP_INIT_BUTTONS)
	{
	  uint32_t num;
	  for(num=0;((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS));num++)
	  {
	    err_code = bsp_event_to_button_action_assign1(num,BSP_BUTTON_ACTION_PUSH,BSP_EVENT_DEFAULT);//事件分配函数
	    err_code = bsp_event_to_button_action_assign1(num,BSP_BUTTON_ACTION_RELEASE,BSP_EVENT_DEFAULT);//事件分配函数
	    err_code = bsp_event_to_button_action_assign2(num,BSP_BUTTON_ACTION_LONG_PUSH,BSP_EVENT_DEFAULT);//事件分配函数
	  }
	}
	if(err_code == NRF_SUCCESS)
	{
	  err_code = app_button_init((app_button_cfg_t*)app_buttons,BUTTONS_NUMBER,APP_TIMER_TICKS(50)); //消抖
	}
	if(err_code == NRF_SUCCESS)
	{
	  err_code = app_button_enable();//使能按键
	}
	if(err_code == NRF_SUCCESS)
	{
	  err_code = app_timer_create(&bsp_button_id,APP_TIMER_MODE_SINGLE_SHOT,button_timerout_handler);
	}
}
uint32_t bsp_event_to_button_action_assign1(uint32_t button,bsp_button_action_t action, bsp_event_t event)
{
 uint32_t err_code = NRF_SUCCESS;
 #if BUTTONS_NUMBER > 0
 if(button < BUTTONS_NUMBER)
 {
   if(event == BSP_EVENT_DEFAULT)
   {
    event = (bsp_event_t)(BSP_EVENT_KEY_0 + button);
   }
   switch(action)
   {
     case BSP_BUTTON_ACTION_PUSH:
       m_events_list[button].push_event = event;
       break;
      case BSP_BUTTON_ACTION_LONG_PUSH:
        m_event_list[button].long_push+event = event;
        break;
      case BSP_BUTTON_ACTION_RELEASE:
        m_event_list[button].release_event = event;
        break;
      default:
         err_code = NRF_ERROR_INVALID_PARAM;
         break;
    }
  }
  else
  {
     err_code = NRF_ERROR_INVALID_PARAM; 
  }
  #else
   err_code = NRF_ERROR_INVALID_PARAM;
  #endif
    return err_code;
}

BSP_EVENT_KEY_0代表按键0的短按,在函数bsp_event_to_button_action_assign2中修改BSP_EVENT_KEY_0为BSP_EVENT_KEY_C0代表按键0的长按;
这样在bsp.c文件中的函数就设置完了,接下来主要是实现一个按键的事件函数和按键的初始化
4. 初始化按键

void button_init()
    {
              ret_code_t err_code;
               err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS,button_event_handler)APP_ERROR_CHECK(err_code)}

5.实现按键事件回调函数

 void button_event_handler(bsp_event_t event)
 {
   switch((uint8_t)event)
   {
      case BSP_EVENT_KEY_0:
             if(click_flag == 1) 单击
              {...........}
             else if(click_flag == 2) 双击
             {............}
             break;
      case BSP_EVENT_KEY_C0: 长按
       ......
       break;
   }
}

这就是实现按键单双击及长按的主要流程,其中还有一些细节以及定时器超时函数中的实现内容这里没有给出,但也都提到了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值