CC2640R2F学习笔记(3)——按键使用

一、硬件连接

按键名称 引脚 控制方法
UP DIO_19 按下触发
DOWN DIO_12 按下触发
LEFT DIO_15 按下触发
RIGHT DIO_18 按下触发
SELECT DIO_11 按下触发

二、移植文件

链接:https://pan.baidu.com/s/1cC8HA_GC6e3Kci1ayvJPIA 提取码:xdke
board_key.cboard_key.h 两个文件拖拽至CCS工程的Application文件夹下

6793005-80c242b407a26b38.jpg

添加文件过程中,选项选择如下
6793005-22934b03f012cb86.png

6793005-eec70c9839749771.png

2.1 board_key.c

/*********************************************************************
 * INCLUDES
 */
#include <stdbool.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/family/arm/m3/Hwi.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Queue.h>

#include <ti/drivers/pin/PINCC26XX.h>

#ifdef USE_ICALL
#include <icall.h>
#endif

#include <inc/hw_ints.h>

#include "util.h"
#include "board_key.h"
#include "board.h"

/*********************************************************************
 * LOCAL FUNCTIONS
 */
static void Board_keyChangeHandler(UArg a0);
static void Board_keyCallback(PIN_Handle hPin, PIN_Id pinId);

/*********************************************************************
 * LOCAL VARIABLES
 */

// Value of keys Pressed
//键值
static uint8_t keysPressed;

// Key debounce clock
//按键消抖时钟
static Clock_Struct keyChangeClock;

// Pointer to application callback
//对应应用层回调函数的函数指针
keysPressedCB_t appKeyChangeHandler = NULL;

// Memory for the GPIO module to construct a Hwi
Hwi_Struct callbackHwiKeys;

// PIN configuration structure to set all KEY pins as inputs with pullups enabled
//IO配置需要的数组
PIN_Config keyPinsCfg[] =
{
#if defined(CC2650_LAUNCHXL) || defined(CC2640R2_LAUNCHXL) || defined(CC1350_LAUNCHXL)
    Board_BTN1          | PIN_GPIO_OUTPUT_DIS  | PIN_INPUT_EN  |  PIN_PULLUP,
    Board_BTN2          | PIN_GPIO_OUTPUT_DIS  | PIN_INPUT_EN  |  PIN_PULLUP,
#elif defined(CC2650DK_7ID)  || defined(CC1350DK_7XD) || defined(CC2640R2DK_7ID)
    Board_KEY_SELECT    | PIN_GPIO_OUTPUT_DIS  | PIN_INPUT_EN  |  PIN_PULLUP,
    Board_KEY_UP        | PIN_GPIO_OUTPUT_DIS  | PIN_INPUT_EN  |  PIN_PULLUP,
    Board_KEY_DOWN      | PIN_GPIO_OUTPUT_DIS  | PIN_INPUT_EN  |  PIN_PULLUP,
    Board_KEY_LEFT      | PIN_GPIO_OUTPUT_DIS  | PIN_INPUT_EN  |  PIN_PULLUP,
    Board_KEY_RIGHT     | PIN_GPIO_OUTPUT_DIS  | PIN_INPUT_EN  |  PIN_PULLUP,
#endif
    PIN_TERMINATE
};

//IO状态结构体
PIN_State  keyPins;
//IO句柄结构体
PIN_Handle hKeyPins;

/*********************************************************************
 * PUBLIC FUNCTIONS
 */
/*********************************************************************
 * @fn      Board_initKeys
 *          按键驱动的初始化函数
 * @brief   Enable interrupts for keys on GPIOs.
 *
 * @param   appKeyCB - application key pressed callback
 *
 * @return  none
 */
void Board_initKeys(keysPressedCB_t appKeyCB)
{
  // Initialize KEY pins. Enable int after callback registered
  //初始化按键的IO
  hKeyPins = PIN_open(&keyPins, keyPinsCfg);
  //注册回调函数
  PIN_registerIntCb(hKeyPins, Board_keyCallback);

#if defined(CC2650_LAUNCHXL) || defined(CC2640R2_LAUNCHXL) || defined(CC1350_LAUNCHXL)
  PIN_setConfig(hKeyPins, PIN_BM_IRQ, Board_BTN1        | PIN_IRQ_NEGEDGE);
  PIN_setConfig(hKeyPins, PIN_BM_IRQ, Board_BTN2        | PIN_IRQ_NEGEDGE);
#elif defined(CC2650DK_7ID)  || defined(CC1350DK_7XD) || defined(CC2640R2DK_7ID)
  //修改成双沿中断触发,以避免睡眠之后中断不灵
  PIN_setConfig(hKeyPins, PIN_BM_IRQ, Board_KEY_SELECT  | PIN_IRQ_BOTHEDGES);     // PIN_IRQ_NEGEDGE
  PIN_setConfig(hKeyPins, PIN_BM_IRQ, Board_KEY_UP      | PIN_IRQ_BOTHEDGES);
  PIN_setConfig(hKeyPins, PIN_BM_IRQ, Board_KEY_DOWN    | PIN_IRQ_BOTHEDGES);
  PIN_setConfig(hKeyPins, PIN_BM_IRQ, Board_KEY_LEFT    | PIN_IRQ_BOTHEDGES);
  PIN_setConfig(hKeyPins, PIN_BM_IRQ, Board_KEY_RIGHT   | PIN_IRQ_BOTHEDGES);
#endif

  //低功耗下的配置
#ifdef POWER_SAVING
  //Enable wakeup
#if defined(CC2650_LAUNCHXL) || defined(CC2640R2_LAUNCHXL) || defined(CC1350_LAUNCHXL)
  PIN_setConfig(hKeyPins, PINCC26XX_BM_WAKEUP, Board_BTN1        | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(hKeyPins, PINCC26XX_BM_WAKEUP, Board_BTN2        | PINCC26XX_WAKEUP_NEGEDGE);
#elif defined(CC2650DK_7ID)  || defined(CC1350DK_7XD) || defined(CC2640R2DK_7ID)
  PIN_setConfig(hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_SELECT | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_UP | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_DOWN | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_LEFT | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_RIGHT | PINCC26XX_WAKEUP_NEGEDGE);
#endif
#endif //POWER_SAVING

  // Setup keycallback for keys
  //初始化按键定时事件
  Util_constructClock(&keyChangeClock, Board_keyChangeHandler,
                      KEY_DEBOUNCE_TIMEOUT, 0, false, 0);

  // Set the application callback
  //保存应用层的函数指针
  appKeyChangeHandler = appKeyCB;
}

/*********************************************************************
 * @fn      Board_keyCallback
 *          按键驱动的回调函数
 * @brief   Interrupt handler for Keys
 *
 * @param   none
 *
 * @return  none
 */
static void Board_keyCallback(PIN_Handle hPin, PIN_Id pinId)
{
  //清除键值
  keysPressed = 0;

#if defined(CC2650_LAUNCHXL) || defined(CC2640R2_LAUNCHXL) || defined(CC1350_LAUNCHXL)
  if ( PIN_getInputValue(Board_BTN1) == 0 )
  {
    keysPressed |= KEY_LEFT;
  }

  if ( PIN_getInputValue(Board_BTN2) == 0 )
  {
    keysPressed |= KEY_RIGHT;
  }
#elif defined(CC2650DK_7ID)  || defined(CC1350DK_7XD) || defined(CC2640R2DK_7ID)
  //判断按键是否按下
  if ( PIN_getInputValue(Board_KEY_SELECT) == 0 )
  {
    //保存键值
    keysPressed |= KEY_SELECT;
  }

  if ( PIN_getInputValue(Board_KEY_UP) == 0 )
  {
    keysPressed |= KEY_UP;
  }

  if ( PIN_getInputValue(Board_KEY_DOWN) == 0 )
  {
    keysPressed |= KEY_DOWN;
  }

  if ( PIN_getInputValue(Board_KEY_LEFT) == 0 )
  {
    keysPressed |= KEY_LEFT;
  }

  if ( PIN_getInputValue(Board_KEY_RIGHT) == 0 )
  {
    keysPressed |= KEY_RIGHT;
  }
#endif
  //启动定时器进行消抖
  Util_startClock(&keyChangeClock);
}

/*********************************************************************
 * @fn      Board_keyChangeHandler
 *          按键驱动的消抖处理函数
 * @brief   Handler for key change
 *
 * @param   UArg a0 - ignored
 *
 * @return  none
 */
static void Board_keyChangeHandler(UArg a0)
{
  //判断是否有注册
  if (appKeyChangeHandler != NULL)
  {
    //消抖
    if ( PIN_getInputValue(Board_KEY_SELECT) == 0 )
    {
        keysPressed |= KEY_SELECT;
    }

    if ( PIN_getInputValue(Board_KEY_UP) == 0 )
    {
        keysPressed |= KEY_UP;
    }

    if ( PIN_getInputValue(Board_KEY_DOWN) == 0 )
    {
        keysPressed |= KEY_DOWN;
    }

    if ( PIN_getInputValue(Board_KEY_LEFT) == 0 )
    {
        keysPressed |= KEY_LEFT;
    }

    if ( PIN_getInputValue(Board_KEY_RIGHT) == 0 )
    {
        keysPressed |= KEY_RIGHT;
    }

    // Notify the application
    //调用按键应用层处理函数
    (*appKeyChangeHandler)(keysPressed);
  }
}
/*********************************************************************
*********************************************************************/

2.2 board_key.h

#ifndef BOARD_KEY_H
#define BOARD_KEY_H

#ifdef __cplusplus
extern "C" {
#endif

/*********************************************************************
 * DEFINITIONS
 */
//键值
#define KEY_SELECT            0x0001
#define KEY_UP                0x0002
#define KEY_DOWN              0x0004
#define KEY_LEFT              0x0008
#define KEY_RIGHT             0x0010

#define Board_KEY_UP          IOID_19
#define Board_KEY_DOWN        IOID_12
#define Board_KEY_LEFT        IOID_15
#define Board_KEY_RIGHT       IOID_18
#define Board_KEY_SELECT      IOID_11

// Debounce timeout in milliseconds
//超时时间
#define KEY_DEBOUNCE_TIMEOUT  20    // 200

/*********************************************************************
 * TYPEDEFS
 */
typedef void (*keysPressedCB_t)(uint8_t keysPressed);

/*********************************************************************
 * @fn      Board_initKeys
 *
 * @brief   Enable interrupts for keys on GPIOs.
 *
 * @param   appKeyCB - application key pressed callback
 *
 * @return  none
 */
void Board_initKeys(keysPressedCB_t appKeyCB);

/*********************************************************************
*********************************************************************/

#ifdef __cplusplus
}
#endif

#endif /* BOARD_KEY_H */

三、API调用

需包含头文件 board_key.h

Board_initKeys

功能 初始化按键引脚
函数定义 void Board_initKeys(keysPressedCB_t appKeyCB)
参数 按键事件处理回调函数
返回

四、使用例子

1)添加头文件(例 multi_role.c 中)

#include "board_key.h"

2)添加初始化代码(multi_role.c 的 multi_role_init 函数末尾中)

// 初始化按键
Board_initKeys(multi_role_keyChangeHandler);

3)添加按键改变产生按键事件函数

/**
 @brief Key event handler function.
 @param bit field for key events.
 @return None.
*/
void multi_role_keyChangeHandler(uint8_t keys)
{
  uint8_t *pData;

  // Allocate space for the event data.
  if ((pData = ICall_malloc(sizeof(uint8_t))))
  {
    // Store the key data
    *pData = keys;

    // Queue the event.
    multi_role_enqueueMsg(MR_KEY_CHANGE_EVT, pData);
  }
}

4)注册按键事件(multi_role.c 的 multi_role_processAppMsg 函数中)

/**
 @brief Process an incoming callback from a profile.
 @param pMsg - message to process.
 @return None.
*/
static void multi_role_processAppMsg(mrEvt_t *pMsg)
{
  switch (pMsg->event)
  {
  /*------------------按键事件处理--------------------*/
  case MR_KEY_CHANGE_EVT:
    multi_role_handleKeys(*(pMsg->pData));
    // Free the app data
    ICall_free(pMsg->pData);
    break;

  default:
    // Do nothing.
    break;
  }
}

5)添加按键处理函数

/**
 @brief Handles all key events for this device.
 @param keys - bit field for key events. Valid entries:
                 HAL_KEY_SW_2
                 HAL_KEY_SW_1
 @return None.
*/
static void multi_role_handleKeys(uint8_t keys)
{
  if (keys & KEY_LEFT)
  {
    // Check if the key is still pressed
    if (PIN_getInputValue(Board_KEY_LEFT) == 0)
    {
      // 自定义处理
    }
  }
  else if (keys & KEY_UP)
  {
    // Check if the key is still pressed
    if (PIN_getInputValue(Board_KEY_UP) == 0)
    {
      // 自定义处理
    }
  }
}

• 由 Leung 写于 2019 年 1 月 22 日

• 参考:【CC2640R2F】香瓜CC2640R2F之自定义按键

猜你喜欢

转载自blog.csdn.net/weixin_34384915/article/details/87610580