一、硬件连接
按键名称 | 引脚 | 控制方法 |
---|---|---|
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.c 和 board_key.h 两个文件拖拽至CCS工程的Application文件夹下
![](https://img.haomeiwen.com/i6793005/80c242b407a26b38.jpg)
添加文件过程中,选项选择如下
![](https://img.haomeiwen.com/i6793005/22934b03f012cb86.png)
![](https://img.haomeiwen.com/i6793005/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 日
网友评论