【BLE】CC2541之按键

一、简介

本篇介绍如何在SimpleBLECentral工程和SimpleBLEPeripheral工程中使用按键,并且剖析按键的初始化、响应的流程。


二、实验平台

协议栈版本:BLE-CC254x-1.4.0

编译软件:IAR 8.20.2

硬件平台:Smart RF开发板


三、版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.net/feilusia

联系方式:[email protected]

技术交流QQ群:127442605


四、硬件原理图

1、普通按键

【BLE】CC2541之按键_第1张图片

触发引脚:P0_1

常态:低电平

按下:高电平

松开:低电平

适合触发方式:上升沿触发


2、五向按键

【BLE】CC2541之按键_第2张图片

原理:五向按键每一端连接或与芯片SN74HC32D,使得按下五向按键即可触发P2_0。随即从P0_6采集双级运算放大芯片TLV272输出的电压,来确定是五向按键的哪个脚。

1)触发

触发引脚:P2_0

触发引脚常态:低电平

触发引脚按下:高电平

触发引脚松开:低电平

适合触发方式:上升沿触发

2)采集

采集引脚:P0_6

无按键时电压:2.39V

按center键时电压:2.39V

按up键时电压:0.41V

按down键时电压:1.36V

按left键时电压:1.85V

按right键时电压:2.05V


五、SimpleBLEPeripheral工程的按键代码修改

注:SimpleBLECentral工程步骤也类似,只是少了几步去除代码中的宏定义“CC2540_MINIDK”的步骤。

1、IAR的宏定义

要想使用按键,首先在IAR的设置中的宏定义里添加“HAL_KEY = TRUE”;反之,则“HAL_KEY = FALSE”。

注:由于协议栈中有下面这段代码,因此即使IAR的宏定义设置中没有添加“HAL_KEY = TRUE”也可以使用按键。

/* Set to TRUE enable KEY usage, FALSE disable it */
#ifndef HAL_KEY
#define HAL_KEY TRUE
#endif
建议在IAR的宏定义中手动添加,以防出现不必要的错误。


2、修改应用层代码(SimpleBLEPeripheral.c中)

1)应用层的按键事件入口处

【BLE】CC2541之按键_第3张图片


2)simpleBLEPeripheral_HandleKeys的声明

【BLE】CC2541之按键_第4张图片


3)simpleBLEPeripheral_HandleKeys函数

【BLE】CC2541之按键_第5张图片

把工程默认的按键处理也都删了,否则代码编译会报错。


4)注册按键事件

【BLE】CC2541之按键_第6张图片


2、按键驱动代码修改(hal_key.c)

1)修改按键S1的边沿触发方式

#define HAL_KEY_SW_6_EDGE     HAL_KEY_RISING_EDGE//HAL_KEY_FALLING_EDGE
由于我的板子适合上升沿触发,而协议栈默认是下降沿触发,因此这里配置成上升沿。


2)修改五向按键的边沿触发方式

#define HAL_KEY_JOY_MOVE_EDGE     HAL_KEY_RISING_EDGE//HAL_KEY_FALLING_EDGE


3)更正协议栈的错误代码

//    /* Rising/Falling edge configuratinn */
//    HAL_KEY_JOY_MOVE_ICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT);    /* Clear the edge bit */
//    /* For falling edge, the bit must be set. */
//  #if (HAL_KEY_JOY_MOVE_EDGE == HAL_KEY_FALLING_EDGE)
//    HAL_KEY_JOY_MOVE_ICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;
//  #endif
    
    /* Rising/Falling edge configuratinn */
    PICTL &= ~(HAL_KEY_JOY_MOVE_EDGEBIT);    /* Clear the edge bit */
    /* For falling edge, the bit must be set. */
  #if (HAL_KEY_JOY_MOVE_EDGE == HAL_KEY_FALLING_EDGE)
    PICTL |= HAL_KEY_JOY_MOVE_EDGEBIT;
  #endif

原代码错将中断使能寄存器HAL_KEY_JOY_MOVE_ICTL(P2IEN)当做PICTL寄存器。详情如下:

#define HAL_KEY_JOY_MOVE_ICTL     P2IEN /* Port Interrupt Control register */

【BLE】CC2541之按键_第7张图片

【BLE】CC2541之按键_第8张图片


4)修改HalKeyPoll函数

//  if (!(HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT))    /* Key is active low */
//  {
//    keys |= HAL_KEY_SW_6;
//  }
  if ((HAL_KEY_SW_6_PORT & HAL_KEY_SW_6_BIT))    /* Key is active high */  
  {
    keys |= HAL_KEY_SW_6;
  }
1.4.0的协议栈才要这么做。


六、解析按键初始化

1、复位按键的相关参数、变量

【BLE】CC2541之按键_第9张图片


【BLE】CC2541之按键_第10张图片


【BLE】CC2541之按键_第11张图片


2、注册任务ID

【BLE】CC2541之按键_第12张图片


3、正式初始化按键配置

【BLE】CC2541之按键_第13张图片


下图默认开启中断,并且按键的回调函数注册为OnBoard_KeyCallback。

【BLE】CC2541之按键_第14张图片


七、解析按键响应

1、扫描按键值

1)当硬件有按键时,则进入中断服务函数halProcessKeyInterrupt

【BLE】CC2541之按键_第15张图片


2)HAL_KEY_EVENT事件

在Hal_ProcessEvent中的HAL_KEY_EVENT事件中扫描按键。

【BLE】CC2541之按键_第16张图片


3)扫描按键值HalKeyPoll

【BLE】CC2541之按键_第17张图片

【BLE】CC2541之按键_第18张图片


2、将按键值送往上层的应用层

1)OnBoard_KeyCallback函数

【BLE】CC2541之按键_第19张图片


2)OnBoard_SendKeys函数

【BLE】CC2541之按键_第20张图片

通过osal_msg_send传递的消息,都会到选中的任务下的默认事件下(此时也就是simpleBLEPeripheral_TaskID任务的SYS_EVENT_MSG事件)。


3)应用层处理

【BLE】CC2541之按键_第21张图片

【BLE】CC2541之按键_第22张图片

【BLE】CC2541之按键_第23张图片


八、解析按键中一处难点

1、难懂的代码

  /* If any key is currently pressed down and interrupt
     is still enabled, disable interrupt and switch to polling */
  if( keys != 0 )
  {
    if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_ENABLE )
    {
      OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE;
      HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
    }
  }
  /* If no key is currently pressed down and interrupt
     is disabled, enable interrupt and turn off polling */
  else
  {
    if( OnboardKeyIntEnable == HAL_KEY_INTERRUPT_DISABLE )
    {
      OnboardKeyIntEnable = HAL_KEY_INTERRUPT_ENABLE;
      HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);
    }
  }

OnBoard_KeyCallback函数中还有上面的一段代码很难理解,百度后无果,自己也是单步执行跑完按键流程后才理解这段代码的用途。

这段代码是实现中断方式和扫描方式互相切换。

作用是检测键值是否松开:

1)当“硬件上的按键不按为高电平,按下为低电平”时:下降沿触发时我们可以知道何时按键松开。

2)当“硬件上的按键不按为低电平,按下为高电平”时:上升沿触发时我们可以知道何时按键松开。


注:下面这个框中代码就是用于中断方式与查询方式来回切换用的。

它是指查询到键值回零后、由查询方式转为中断方式时,停止定时器。

【BLE】CC2541之按键_第24张图片


2、详细分析

下面以“硬件上的按键不按为低电平,按下为高电平”、“上升沿触发”为前提,看下面的按键流程:

功能:中断方式检测按键按下、扫描方式检测按键松开。(按键松开会通知用户)

1)按键S1按下:

触发上升沿中断,发送键值“0x20”给应用层。

由中断触发方式切换成扫描方式。


2)按键S1松开

扫描到引脚变化,则发送键值“0x00”给应用层。

由扫描方式切换回中断触发方式。


3、小实验

接下来测试下按键流程是否跟我解析的一致,这里只测试上升沿触发的情况。

1、代码修改:

static void simpleBLEPeripheral_HandleKeys( uint8 shift, uint8 keys )
{
  VOID shift;  // Intentionally unreferenced parameter 

  if ( keys & HAL_KEY_SW_6 )//上升沿触发,按键按下
  {  
    NPI_PrintString("key is press!\r\n");  
  }
  
  if ( keys == 0x00 )    //上升沿触发,按键松开
  {
    NPI_PrintString("key is loosen!\r\n");  
  }  
}

2、实验现象:

【BLE】CC2541之按键_第25张图片

按键按下时是中断方式发现按键,并发送0x20键值给应用层,此时显示“key is press!”。

按键松开时是扫描方式扫到按键,并发送0x00键值给应用层,此时显示“key is loosen!”。

实验结果与我分析的一致。


你可能感兴趣的:(【BLE】CC2541之按键)