【CC2640R2F】香瓜CC2640R2F之自定义按键



本文最后修改时间:2017年11月13日 15:00

 

一、本节简介

本节以simple_peripheral工程为例,介绍如何使用任意的IO口作为按键。

注:香瓜为了方便按键测试,本文使用香瓜CC2640R2F开发板上的5个按键来举例,也可自行更换IO口。


二、实验平台

1)CC2640R2F平台

①协议栈版本:CC2640R2 SDK v1.40.00.45

②编译软件:CCS7.3.0.00019

③硬件平台:香瓜CC2640R2F开发板

④仿真器:香瓜XDS100V3下载器


三、版权声明

1)作者:甜甜的大香瓜

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

3)纠错/业务合作:[email protected]

4)香瓜BLE之CC2640R2F群:557278427

5)本文出处:原创连载资料《简单粗暴学蓝牙5》

6)完整开源资料下载地址(电脑端打开):

https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

7)香瓜CC2640R2F开发板购买链接:

https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4023-16963296339.8.21bfc58419sWKt&id=558653143169

8)香瓜XDS100V3下载器购买链接:

https://item.taobao.com/item.htm?spm=a230r.1.14.1.1d150040zvJBco&id=558356989143&ns=1&abbucket=6#detail


四、实验前提

1、在进行本文步骤前,请先阅读以下章节:

1)《简单粗暴学蓝牙5》的“第一章至第四章”章节​。

 

2、在进行本文步骤前,请先实现以下章节:

1)《简单粗暴学蓝牙5》的“第三章 软件的安装及使用”章节。

2) 《简单粗暴学蓝牙5》的《香瓜CC2640R2F之LED》:http://blog.csdn.net/feilusia/article/details/78087346


五、基础知识

1、自定义驱动与协议栈驱动有什么区别?

答:结果上没有区别,而香瓜写的自定义驱动更方便移植、更方便修改IO口或新增按键。


六、硬件原理

1、原理图

【CC2640R2F】香瓜CC2640R2F之自定义按键_第1张图片

【CC2640R2F】香瓜CC2640R2F之自定义按键_第2张图片

由上面两图可知,

名称 引脚 控制方法
UP DIO_19 按键按下触发
DOWN DIO_12 按键按下触发
LEFT DIO_15 按键按下触发
RIGHT DIO_18 按键按下触发
SELECT DIO_11 按键按下触发
注:SFM16是拨码开关。


2、开发板对应位置

【CC2640R2F】香瓜CC2640R2F之自定义按键_第3张图片

需将拨码开关的左1(VCC)、右9(SELECT)、右8(DOWN)、右7(UP)、右6(RIGHT)、右5(LEFT)按键上拨。


七、实验步骤

1、编写并添加自定义的LED驱动

1)写一个按键驱动GUA_Key.c(存放在“……\simplelink_cc2640r2_sdk_1_40_00_45\examples\rtos\CC2640R2_LAUNCHXL\ble5stack\simple_peripheral\src\app\GUA”路径下

//**********************************************************************
//name:         GUA_Key.c
//introduce:    香瓜自定义的按键驱动
//author:       甜甜的大香瓜      
//email:        [email protected]   
//QQ group:     香瓜BLE之CC2640R2F(557278427)
//shop:
//https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
//changetime:   2017.11.09
//**********************************************************************
#include 
#include 
#include 
#include 
#include 
#include 

#ifdef USE_ICALL
#include 
#endif

#include 

#include "util.h"
#include "Board.h"

#include "GUA_Key.h"

/*********************宏定义************************/
#define GUA_KEY_UP          IOID_19
#define GUA_KEY_DOWN        IOID_12
#define GUA_KEY_LEFT        IOID_15
#define GUA_KEY_RIGHT       IOID_18
#define GUA_KEY_SELECT      IOID_11

/*********************内部变量************************/
//键值
static GUA_U8 GUA_keysPressed;

//按键消抖时钟
static Clock_Struct GUA_keyChangeClock;

//对应应用层回调函数的函数指针
static GUA_keysPressedCB_t GUA_appKeyChangeHandler = NULL;

//IO配置需要的数组
static PIN_Config GUA_keyPinsCfg[] =
{
    GUA_KEY_UP | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP,
    GUA_KEY_DOWN | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP,
    GUA_KEY_LEFT | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP,
    GUA_KEY_RIGHT | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP,
    GUA_KEY_SELECT | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP,
    PIN_TERMINATE
};

//IO状态结构体
static PIN_State  GUA_keyPins;

//IO句柄结构体
static PIN_Handle GUA_hKeyPins;

/*********************内部函数************************/
static void GUA_keyChangeHandler(UArg a0);
static void GUA_keyCallback(PIN_Handle hPin, PIN_Id pinId);

//**********************************************************************
//name:         GUA_keyCallback
//introduce:    香瓜按键驱动的回调函数
//parameter:    hPin:按键句柄
//              pinId:按键ID
//return:       none
//author:       甜甜的大香瓜
//email:        [email protected]
//QQ group:     香瓜BLE之CC2640R2F(557278427)
//shop:
//https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
//changetime:   2017.11.09
//**********************************************************************
static void GUA_keyCallback(PIN_Handle hPin, PIN_Id pinId)
{
  //清除键值
  GUA_keysPressed = 0;

  //判断按键是否按下
  if(PIN_getInputValue(GUA_KEY_UP) == 0)
  {
    //保存键值
    GUA_keysPressed |= GUA_KEY_UP_VALUE;
  }

  //判断按键是否按下
  if(PIN_getInputValue(GUA_KEY_DOWN) == 0)
  {
    //保存键值
    GUA_keysPressed |= GUA_KEY_DOWN_VALUE;
  }

  //判断按键是否按下
  if(PIN_getInputValue(GUA_KEY_LEFT) == 0)
  {
    //保存键值
    GUA_keysPressed |= GUA_KEY_LEFT_VALUE;
  }

  //判断按键是否按下
  if(PIN_getInputValue(GUA_KEY_RIGHT) == 0)
  {
    //保存键值
    GUA_keysPressed |= GUA_KEY_RIGHT_VALUE;
  }

  //判断按键是否按下
  if(PIN_getInputValue(GUA_KEY_SELECT) == 0)
  {
    //保存键值
    GUA_keysPressed |= GUA_KEY_SELECT_VALUE;
  }

  //启动定时器进行消抖
  Util_startClock(&GUA_keyChangeClock);
}

//**********************************************************************
//name:         GUA_keyChangeHandler
//introduce:    香瓜按键驱动的消抖处理函数
//parameter:    a0:忽略
//return:       none
//author:       甜甜的大香瓜
//email:        [email protected]
//QQ group:     香瓜BLE之CC2640R2F(557278427)
//shop:
//https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
//changetime:   2017.11.09
//**********************************************************************
static void GUA_keyChangeHandler(UArg a0)
{
  //清除键值
  GUA_keysPressed = 0;

  //判断是否有注册
  if(GUA_appKeyChangeHandler != NULL)
  {
    //消抖
    if(PIN_getInputValue(GUA_KEY_UP) == 0)
    {
      GUA_keysPressed |= GUA_KEY_UP_VALUE;
    }

    //消抖
    if(PIN_getInputValue(GUA_KEY_DOWN) == 0)
    {
      GUA_keysPressed |= GUA_KEY_DOWN_VALUE;
    }

    //消抖
    if(PIN_getInputValue(GUA_KEY_LEFT) == 0)
    {
      GUA_keysPressed |= GUA_KEY_LEFT_VALUE;
    }

    //消抖
    if(PIN_getInputValue(GUA_KEY_RIGHT) == 0)
    {
      GUA_keysPressed |= GUA_KEY_RIGHT_VALUE;
    }

    //消抖
    if(PIN_getInputValue(GUA_KEY_SELECT) == 0)
    {
      GUA_keysPressed |= GUA_KEY_SELECT_VALUE;
    }

    //调用按键应用层处理函数
    (*GUA_appKeyChangeHandler)(GUA_keysPressed);
  }
}

//**********************************************************************
//name:         GUA_initKeys
//introduce:    香瓜按键驱动的初始化函数
//parameter:    GUA_appKeyCB:应用层的按键处理函数
//return:       none
//author:       甜甜的大香瓜
//email:        [email protected]
//QQ group:     香瓜BLE之CC2640R2F(557278427)
//shop:
//https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
//changetime:   2017.11.09
//**********************************************************************
void GUA_initKeys(GUA_keysPressedCB_t GUA_appKeyCB)
{
  //初始化按键的IO
  GUA_hKeyPins = PIN_open(&GUA_keyPins, GUA_keyPinsCfg);

  //注册回调函数
  PIN_registerIntCb(GUA_hKeyPins, GUA_keyCallback);

  //修改成双沿中断触发,以避免睡眠之后中断不灵
  PIN_setConfig(GUA_hKeyPins, PIN_BM_IRQ, GUA_KEY_UP | PIN_IRQ_BOTHEDGES);
  PIN_setConfig(GUA_hKeyPins, PIN_BM_IRQ, GUA_KEY_DOWN | PIN_IRQ_BOTHEDGES);
  PIN_setConfig(GUA_hKeyPins, PIN_BM_IRQ, GUA_KEY_LEFT | PIN_IRQ_BOTHEDGES);
  PIN_setConfig(GUA_hKeyPins, PIN_BM_IRQ, GUA_KEY_RIGHT | PIN_IRQ_BOTHEDGES);
  PIN_setConfig(GUA_hKeyPins, PIN_BM_IRQ, GUA_KEY_SELECT | PIN_IRQ_BOTHEDGES);

  //低功耗下的配置
#ifdef POWER_SAVING
  PIN_setConfig(GUA_hKeyPins, PINCC26XX_BM_WAKEUP, GUA_KEY_UP | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(GUA_hKeyPins, PINCC26XX_BM_WAKEUP, GUA_KEY_DOWN | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(GUA_hKeyPins, PINCC26XX_BM_WAKEUP, GUA_KEY_LEFT | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(GUA_hKeyPins, PINCC26XX_BM_WAKEUP, GUA_KEY_RIGHT | PINCC26XX_WAKEUP_NEGEDGE);
  PIN_setConfig(GUA_hKeyPins, PINCC26XX_BM_WAKEUP, GUA_KEY_SELECT | PINCC26XX_WAKEUP_NEGEDGE);
#endif

  //初始化按键定时事件
  Util_constructClock(&GUA_keyChangeClock, GUA_keyChangeHandler,
                      GUA_KEY_DEBOUNCE_TIMEOUT, 0, false, 0);

  //保存应用层的函数指针
  GUA_appKeyChangeHandler = GUA_appKeyCB;
}

2)写一个按键驱动头文件GUA_Key.h (存放在“…… \simplelink_cc2640r2_sdk_1_40_00_45\examples\rtos\CC2640R2_LAUNCHXL\ble5stack\simple_peripheral\src\app\GUA”路径下)

//**********************************************************************
//name:         GUA_Key.h
//introduce:    香瓜自定义的按键驱动头文件
//author:       甜甜的大香瓜      
//email:        [email protected]   
//QQ group:     香瓜BLE之CC2640R2F(557278427)
//shop:
//https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
//changetime:   2017.11.09
//**********************************************************************
#ifndef _GUA_KEY_H_
#define _GUA_KEY_H_

/*********************宏定义************************/
//类型宏
#ifndef GUA_C
typedef char GUA_C;
#endif

#ifndef GUA_U8
typedef unsigned char GUA_U8;
#endif

#ifndef GUA_8
typedef signed char GUA_8;
#endif

#ifndef GUA_U16
typedef unsigned short GUA_U16;
#endif

#ifndef GUA_16
typedef signed short GUA_16;
#endif

#ifndef GUA_U32
typedef unsigned long GUA_U32;
#endif

#ifndef GUA_32
typedef signed long GUA_32;
#endif

#ifndef GUA_U64
typedef unsigned long long GUA_U64;
#endif

#ifndef GUA_64
typedef signed long long GUA_64;
#endif

//键值
#define GUA_KEY_UP_VALUE                0x0001
#define GUA_KEY_DOWN_VALUE              0x0002
#define GUA_KEY_LEFT_VALUE              0x0004
#define GUA_KEY_RIGHT_VALUE             0x0008
#define GUA_KEY_SELECT_VALUE            0x0010

//超时时间
#define GUA_KEY_DEBOUNCE_TIMEOUT        20

/*********************外部函数************************/
typedef void (*GUA_keysPressedCB_t)(GUA_U8 GUA_keysPressed);
extern void GUA_initKeys(GUA_keysPressedCB_t GUA_appKeyCB);

#endif

2、工程中添加GUA_Key.c和GUA_Key.h

注:拖拽至CCS工程的Application文件夹下

【CC2640R2F】香瓜CC2640R2F之自定义按键_第4张图片

添加文件过程中,选项选择如下


【CC2640R2F】香瓜CC2640R2F之自定义按键_第5张图片【CC2640R2F】香瓜CC2640R2F之自定义按键_第6张图片


3、应用层调用
1)添加头文件(simple_peripheral.c中)

//GUA
#include "GUA_Key.h"
//GUA

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

//GUA
    //初始化按键
    GUA_initKeys(GUA_HandleKeys);
//GUA

3)添加按键处理函数

①添加按键处理函数simple_peripheral.c中

//**********************************************************************
//name:         GUA_HandleKeys
//introduce:    应用层按键处理函数
//parameter:    GUA_Keys:键值
//return:       none
//author:       甜甜的大香瓜
//email:        [email protected]
//QQ group:     香瓜BLE之CC2640R2F(557278427)
//shop:
//https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
//changetime:   2017.10.08
//**********************************************************************
static void GUA_HandleKeys(uint8 GUA_Keys)
{
  //UP按键
  if(GUA_Keys & GUA_KEY_UP_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_1, GUA_LED_MODE_TOGGLE);      //LED1取反一次
  }

  //DOWN按键
  if(GUA_Keys & GUA_KEY_DOWN_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_2, GUA_LED_MODE_TOGGLE);      //LED2取反一次
  }

  //LEFT按键
  if(GUA_Keys & GUA_KEY_LEFT_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_3, GUA_LED_MODE_TOGGLE);      //LED3取反一次
  }

  //RIGHT按键
  if(GUA_Keys & GUA_KEY_RIGHT_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_4, GUA_LED_MODE_TOGGLE);      //LED4取反一次
  }

  //SELECT按键
  if(GUA_Keys & GUA_KEY_SELECT_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_ALL, GUA_LED_MODE_TOGGLE);    //LED全取反一次
  }
}

②添加按键处理函数声明 simple_peripheral.c中

//GUA
static void GUA_HandleKeys(uint8 GUA_Keys);
//GUA


八、注意事项
暂无

九、实验结果
仿真并全速运行,分别按下5个按键,现象分别为LED1亮灭取反、LED2亮灭取反、LED3亮灭取反、LED4亮灭取反、所有LED亮灭取反。

因此,实验成功。


你可能感兴趣的:(BLE-CC2640R2F)