一、硬件连接
按键名称 | 引脚 | 控制方法 |
---|---|---|
UP | DIO_19 | 按下触发 |
DOWN | DIO_12 | 按下触发 |
LEFT | DIO_15 | 按下触发 |
RIGHT | DIO_18 | 按下触发 |
SELECT | DIO_11 | 按下触发 |
二、移植文件
链接:https://pan.baidu.com/s/13bouzcp4L2rHKm9mXgm72A 提取码:1f78
将 board_key.c 和 board_key.h 两个文件拖拽至CCS工程的Application文件夹下
添加文件过程中,选项选择如下
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 VARIABLES
*/
// 键值
static uint8_t s_keysPressed;
// 按键消抖时钟
static Clock_Struct s_keyChangeClock;
// 对应应用层回调函数的函数指针
static keysPressedCB_t s_appKeyChangeHandler = NULL;
// Memory for the GPIO module to construct a Hwi
static Hwi_Struct s_callbackHwiKeys;
// 按键IO配置
static PIN_Config s_keyPinsCfg[] =
{
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,
PIN_TERMINATE
};
// 按键IO状态结构体
static PIN_State s_keyPins;
// 按键IO句柄结构体
static PIN_Handle s_hKeyPins;
/*********************************************************************
* LOCAL FUNCTIONS
*/
/**
@brief 按键驱动回调函数
@param none
@return none
*/
static void board_keyCallback(PIN_Handle hPin, PIN_Id pinId)
{
// 清除键值
s_keysPressed = 0;
// 判断按键是否按下
if(PIN_getInputValue(Board_KEY_SELECT) == 0)
{
// 保存键值
s_keysPressed |= KEY_SELECT;
}
if(PIN_getInputValue(Board_KEY_UP) == 0)
{
s_keysPressed |= KEY_UP;
}
if(PIN_getInputValue(Board_KEY_DOWN) == 0)
{
s_keysPressed |= KEY_DOWN;
}
if(PIN_getInputValue(Board_KEY_LEFT) == 0)
{
s_keysPressed |= KEY_LEFT;
}
if(PIN_getInputValue(Board_KEY_RIGHT) == 0)
{
s_keysPressed |= KEY_RIGHT;
}
// 启动定时器进行消抖
Util_startClock(&s_keyChangeClock);
}
/**
@brief 按键驱动的消抖处理函数
@param none
@return none
*/
static void board_keyChangeHandler(UArg a0)
{
// 判断是否有注册
if(s_appKeyChangeHandler != NULL)
{
// 消抖
if(PIN_getInputValue(Board_KEY_SELECT) == 0)
{
s_keysPressed |= KEY_SELECT;
}
if(PIN_getInputValue(Board_KEY_UP) == 0)
{
s_keysPressed |= KEY_UP;
}
if(PIN_getInputValue(Board_KEY_DOWN) == 0)
{
s_keysPressed |= KEY_DOWN;
}
if(PIN_getInputValue(Board_KEY_LEFT) == 0)
{
s_keysPressed |= KEY_LEFT;
}
if(PIN_getInputValue(Board_KEY_RIGHT) == 0)
{
s_keysPressed |= KEY_RIGHT;
}
// 调用按键应用层处理函数
(*s_appKeyChangeHandler)(s_keysPressed);
}
}
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/**
@brief 按键驱动的初始化函数
@param appKeyCB 按键回调函数
@return none
*/
void Board_initKeys(keysPressedCB_t appKeyCB)
{
// 初始化按键的IO
s_hKeyPins = PIN_open(&s_keyPins, s_keyPinsCfg);
// 注册回调函数
PIN_registerIntCb(s_hKeyPins, board_keyCallback);
// 修改成双沿中断触发,以避免睡眠之后中断不灵
PIN_setConfig(s_hKeyPins, PIN_BM_IRQ, Board_KEY_SELECT | PIN_IRQ_BOTHEDGES); // PIN_IRQ_NEGEDGE
PIN_setConfig(s_hKeyPins, PIN_BM_IRQ, Board_KEY_UP | PIN_IRQ_BOTHEDGES);
PIN_setConfig(s_hKeyPins, PIN_BM_IRQ, Board_KEY_DOWN | PIN_IRQ_BOTHEDGES);
PIN_setConfig(s_hKeyPins, PIN_BM_IRQ, Board_KEY_LEFT | PIN_IRQ_BOTHEDGES);
PIN_setConfig(s_hKeyPins, PIN_BM_IRQ, Board_KEY_RIGHT | PIN_IRQ_BOTHEDGES);
// 低功耗下的配置
#ifdef POWER_SAVING
PIN_setConfig(s_hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_SELECT | PINCC26XX_WAKEUP_NEGEDGE);
PIN_setConfig(s_hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_UP | PINCC26XX_WAKEUP_NEGEDGE);
PIN_setConfig(s_hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_DOWN | PINCC26XX_WAKEUP_NEGEDGE);
PIN_setConfig(s_hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_LEFT | PINCC26XX_WAKEUP_NEGEDGE);
PIN_setConfig(s_hKeyPins, PINCC26XX_BM_WAKEUP, Board_KEY_RIGHT | PINCC26XX_WAKEUP_NEGEDGE);
#endif // POWER_SAVING
// 初始化按键定时事件
Util_constructClock(&s_keyChangeClock, board_keyChangeHandler,
KEY_DEBOUNCE_TIMEOUT, 0, false, 0);
// 保存应用层的函数指针
s_appKeyChangeHandler = appKeyCB;
}
/*************************************END OF FILE*************************************/
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
// 超时时间
#define KEY_DEBOUNCE_TIMEOUT 20 // 200
/*********************************************************************
* TYPEDEFS
*/
typedef void (*keysPressedCB_t)(uint8_t keysPressed);
/*********************************************************************
* API FUNCTIONS
*/
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)
{
// 自定义处理
}
}
}
6)编译错误
如果工程的Properties-->Build-->ARM Compiler-->Predefined Symbols开了CC2640R2DK_7ID的宏,产生如下错误:
在blestack\boards\CC2640R2DK_7ID\Board.h中,把这几行注释掉
//#define Board_KEY_DOWN CC2650DK_7ID_KEY_DOWN
//#define Board_KEY_LEFT CC2650DK_7ID_KEY_LEFT
//#define Board_KEY_RIGHT CC2650DK_7ID_KEY_RIGHT
//#define Board_KEY_SELECT CC2650DK_7ID_KEY_SELECT
//#define Board_KEY_UP CC2650DK_7ID_KEY_UP
• 由 Leung 写于 2019 年 1 月 22 日