ZigBee TI ZStack CC2530 5.6 实例(三)多功能按键01-实现

【配套源码文档软件硬件等资源,入口见文末

本节将讲述如何实现基于系统时钟的多功能按键,主要是关于如何根据“按键时间持续的长短”来决定按键操作,实现单一按键的多功能化。从本节开始,所有的程序均在“ZStack-CC2530-2.5.1a-20170924_1020.zip”的基础往下进行!(详见“\ZigBee_CC2530\代码:完整工程”该网盘目录下的《程序版本说明20170924_1033.txt》)

一、应用举例(“华为荣耀xSport AM61运动蓝牙耳机”)

一般实际项目开发中,经常会使用多功能按键,比如我自己正在使用的“AM61蓝牙耳机”,如下图所示:

这个多功能按键确实功能非常丰富!我这里截取了京东的售货页面上关于这个多功能按键的部分说明:

通过本节的学习,我们自己也可以开发处类似的多功能按键!

二、Z-Stack中基于系统时钟实现多功能按键的原理

1、按键中断模式

在了解多功能按键的实现原理之前,建议大家先回顾一下《ZigBee CC2530 Z-Stack 15 按键驱动移植及使用1-轮询模式与中断模式》和《ZigBee CC2530 Z-Stack 16 按键驱动移植及使用2-驱动移植》这两节,尤其是其中关于按键中断模式的讲解。

2、系统时钟——osal_systemClock

在OSAL_Timers.c文件中,有一个名为osal_GetSystemClock()的函数,其定义如下:

/*********************************************************************
 * @fn      osal_GetSystemClock()
 *
 * @brief   Read the local system clock.
 *
 * @param   none
 *
 * @return  local clock in milliseconds
 */
uint32 osal_GetSystemClock( void )
{
  return ( osal_systemClock );
}

可见函数中仅仅是直接返回osal_systemClock的值,该变量的定义也在同一个文件中:

// Milliseconds since last reboot
static uint32 osal_systemClock;

可见该变量的值的范围是毫秒,更多关于这个变量信息请自行查阅Z-Stack中相关代码。这里唯一需要说明的是,该值的范围是0~(2^32-1),系统一上电,该值就从0开始每毫秒增1。所以我们可以通过调用osal_GetSystemClock()函数直接获取系统时钟osal_systemClock的值,这是我们基于系统时钟的多功能按键实现的基本原理。

3、基于osal_systemClock的多功能按键

基于系统时钟的多功能按键,关键就是获取“按键时间持续的长短”,根据按键时间长短划分成不同的时间段,就实现了单一按键的多功能化。获取按键时间的基本思想为(以ZB502底板上的KEY1为例,下降沿触发):

(1)对KEY1做好基本IO初始化(上拉输入),以及相关中断初始化(下降沿触发);

(2)按下按键的一瞬间,会由于“下降沿”触发而第一次进入中断,此时获取当前系统时钟,存在我们定义的全局变量HAL_KEY_starting_time中:

HAL_KEY_starting_time = osal_GetSystemClock();

退出中断前,将触发模式切换为“上升沿”触发:

PICTL ^= HAL_KEY_SW_1_EDGEBIT; //触发边沿<--取反

(3)松开按键的一瞬间,会由于“上升沿”触发而第二次进入中断,此时获取当前系统时钟,与HAL_KEY_starting_time做差即可得到此次按键的持续时间——HAL_KEY_interval_time,仅当持续时间大于HAL_KEY_FILTER_TIME(20 ms)才会认为是有效(valid),否则则会被过滤掉:

      HAL_KEY_interval_time = osal_GetSystemClock()-HAL_KEY_starting_time;
      if(HAL_KEY_interval_time > HAL_KEY_FILTER_TIME)//小于HAL_KEY_FILTER_TIME ms的电平变化都会被过滤掉
      {
        isrKeys |= HAL_KEY_SW_1;
        valid = TRUE;
      }

退出中断前,将触发模式还原为“下降沿”触发:

PICTL ^= HAL_KEY_SW_1_EDGEBIT; //触发边沿<--取反

(4)如果本次按键有效,则会最终将按键的事件(KEY_CHANGE)发送至应用层任务(ProjectApp_TaskID):

  if (valid)
  {
    osal_set_event(Hal_TaskID, HAL_KEY_EVENT);
  }

(中间过程请回顾《ZigBee CC2530 Z-Stack 15 按键驱动移植及使用1-轮询模式与中断模式》)

OnBoard_KeyCallback()函数修改为如下:

void OnBoard_KeyCallback ( uint8 keys, uint8 state )
{
  uint8 shift;
  (void)state;

  if     (HAL_KEY_interval_time <  5000) shift = HAL_KEY_00_05_S;
  else if(HAL_KEY_interval_time < 10000) shift = HAL_KEY_05_10_S;
  else if(HAL_KEY_interval_time < 15000) shift = HAL_KEY_10_15_S;
  else return;

  if ( OnBoard_SendKeys( keys, shift ) != ZSuccess )
  {
  }
}

既然按键是有效的,那我们就可以根据此次按键的持续时间——HAL_KEY_interval_time,将按键时间划分为如上述代码中所示的多段,其中总共有3个有效的时间段,我们通过shift(state)的值,将时间段的标识传递到应用层任务,我们在应用层的处理对应代码如下:

case KEY_CHANGE         : ProjectApp_HandleKeys(((keyChange_t *)MSGpkt)->state,((keyChange_t *)MSGpkt)->keys);break;
static void ProjectApp_HandleKeys( uint8 shift, uint8 keys )
{
  if ( keys & HAL_KEY_SW_1 )
  {
    switch(shift)
    {
      case HAL_KEY_00_05_S :
        break;
      case HAL_KEY_05_10_S :
        break;
      case HAL_KEY_10_15_S :
        break;
    }
  }

  uint16 ss = HAL_KEY_interval_time/1000;
  uint16 ms = HAL_KEY_interval_time%1000;
  printf("keys:%02X shift:%01d interval:%02d.%03ds\r\n",
         keys,
         shift,
         ss,
         ms);
}

在switch语句中的各个case分支下,我们可以根据自己的需求,分别去实现自己想要的不同功能;最后的printf()函数在这里只是临时debug使用的,可以方便大家清楚地知道精确的按键持续时间。上述描述已将多功能按键的原理分析完毕,如果有疑问或者想阅读完整工程代码的话,可以直接去本文最开始提供的百度网盘链接去下载~

三、实验验证

1、编译下载

本次实验验证只需要一个ZigBee设备即可完成,这里我们选择“CoordinatorEB”编译下载:

2、实验现象

下载成功之后,一开始ZigBee设备还是和以前一样会打印一些自己的网络状态变化信息,接下来,我们便开始验证我们的多功能按键:

按键时间在20ms~15000ms之间都会有串口输出,串口打印的信息非常容易理解,此处就不再赘述~此外,这里我们只实现了KEY1,大家如果想扩展其余按键的功能,按照前面讲述的原理,一样的操作即可~

【配套源码文档软件硬件等资源,入口见文末

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拿破仑940911

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值