本篇博文最后修改时间:2017年01月06日,11:06。
一、简介
本文以SimpleBLEPeripheral为例,介绍如何将普通IO口(P12)自定义为按键。
注:本文添加按键方法不与协议栈的按键相冲突,协议栈自带的按键仍可正常使用。
二、实验平台
协议栈版本:BLE-CC254x-1.4.0
编译软件:IAR 8.20.2
硬件平台:Smart RF(主芯片CC2541)
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:[email protected]
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
香瓜BLE之Android群:541462902
五、基础知识
暂无
六、实验步骤
1、编写并添加自定义的按键驱动
1)写一个按键驱动Key.C(存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)
//******************************************************************************
//name: Key.c
//introduce: 按键驱动
//author: 甜甜的大香瓜
//changetime: 2016.04.14
//email: [email protected]
//******************************************************************************
#include
#include "Key.h"
/*********************宏定义************************/
//注册时使用的宏
#define NO_TASK_ID 0xFF //没有注册时的任务id
#define NO_EVEN_ID 0x0000 //没有注册时的事件id
//中断消抖时使用的宏
#define KEY_DEBOUNCE_VALUE 20 //消抖时间20ms
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
typedef signed char int8; //!< Signed 8 bit integer
typedef unsigned char uint8; //!< Unsigned 8 bit integer
typedef signed short int16; //!< Signed 16 bit integer
typedef unsigned short uint16; //!< Unsigned 16 bit integer
typedef signed long int32; //!< Signed 32 bit integer
typedef unsigned long uint32; //!< Unsigned 32 bit integer
/*********************内部变量************************/
static U8 registeredKeyTaskID = NO_TASK_ID;
static U16 registeredKeyEvenID = NO_EVEN_ID;
/*********************函数声明************************/
extern uint8 osal_start_timerEx( uint8 task_id, uint16 event_id, uint32 timeout_value );
//******************************************************************************
//name: Key_Init
//introduce: 按键初始化
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//changetime: 2016.04.14
//******************************************************************************
void Key_Init(void)
{
P1SEL &= ~(1 << 2); //P12设置为IO口
P1DIR &= ~(1 << 2); //P12设置为输入
P1INP &= ~(1 << 2); //P1上拉下拉模式
P2INP &= ~(1 << 6); //P1上拉
P1_2 = 1; //P12拉高
P1IFG &= ~(1 << 2); //初始化P12中断标志位
PICTL |= (1 << 1); //下降沿触发
P1IEN |= (1 << 2); //使能P12中断
IEN2 |= (1 << 4); //允许P1口中断;
}
//******************************************************************************
//name: RegisterForKey
//introduce: 注册任务号、处理事件号
//parameter: task_id:任务id
// even_id:事件id
//return: true:注册成功
// flase:注册不成功
//author: 甜甜的大香瓜
//email: [email protected]
//changetime: 2016.04.14
//******************************************************************************
U8 RegisterForKey(U8 task_id, U16 even_id)
{
// Allow only the first task
if ( registeredKeyTaskID == NO_TASK_ID )
{
registeredKeyTaskID = task_id;
}
else
return ( false );
// Allow only the first even
if ( registeredKeyEvenID == NO_EVEN_ID )
{
registeredKeyEvenID = even_id;
}
else
return ( false );
return ( true );
}
//******************************************************************************
//name: Key_Check_Pin
//introduce: 按键检测高低电平状态
//parameter: none
//return: KEY_LOOSEN:此时无按键按下
// KEY_PRESS:此时按键按下
//author: 甜甜的大香瓜
//email: [email protected]
//changetime: 2016.04.14
//******************************************************************************
U8 Key_Check_Pin(void)
{
if(P1 & (1 << 2))
{
return KEY_LOOSEN;
}
else
{
return KEY_PRESS;
}
}
//******************************************************************************
//name: P1_ISR
//introduce: P1的中断入口
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//changetime: 2016.04.14
//******************************************************************************
#pragma vector = P1INT_VECTOR
__interrupt void P1_ISR(void)
{
if(Key_Check_Pin() == KEY_PRESS)
{
osal_start_timerEx(registeredKeyTaskID, registeredKeyEvenID, KEY_DEBOUNCE_VALUE);
}
P1IFG = 0; //清中断标志
P1IF = 0; //清中断标志
}
//******************************************************************************
//name: Key.h
//introduce: 按键驱动的头文件
//author: 甜甜的大香瓜
//changetime: 2016.04.14
//email: [email protected]
//******************************************************************************
#ifndef KEY_H
#define KEY_H
/*********************宏定义************************/
#ifndef U8
typedef unsigned char U8;
#endif
#ifndef U16
typedef unsigned short U16;
#endif
//检测io口状态时使用的宏
#define KEY_LOOSEN 0x01
#define KEY_PRESS 0x00
/*********************函数声明************************/
extern void Key_Init(void);
extern U8 RegisterForKey(U8 task_id, U16 even_id);
extern U8 Key_Check_Pin(void);
#endif
4)在IAR设置中添加按键驱动源文件路径
$PROJ_DIR$\..\..\SimpleBLEPeripheral\Source\GUA
2、定义一个按键事件
1)定义一个按键事件(SimpleBLEPeripheral.c的SimpleBLEPeripheral_ProcessEvent中)
//按键检测处理事件
if ( events & SBP_KEY_CHECK_PROCESS_EVT )
{
//防止抖动,确定是按键
if(Key_Check_Pin() == KEY_PRESS)
{
//按键处理函数
GUA_Key_Process();
}
return (events ^ SBP_KEY_CHECK_PROCESS_EVT);
}
#define SBP_KEY_CHECK_PROCESS_EVT 0x1000 //按键检测处理事件
3、定义并声明一个按键处理函数(SimpleBLEPeripheral.c中)
1)定义一个按键处理函数(SimpleBLEPeripheral.c中)
//******************************************************************************
//name: GUA_Key_Process
//introduce: 按键处理函数
//parameter: none
//return: none
//author: 甜甜的大香瓜
//email: [email protected]
//changetime: 2016.04.14
//******************************************************************************
static void GUA_Key_Process(void)
{
//test
P1SEL &= ~(1 << 0); //设置为IO口
P1DIR |= (1 << 0); //设置为输出
P1_0 = ~P1_0; //这里测试按一次按键,就取反一次P1_0,方便观察P1_0对应的led
//test
}
2)声明一个按键处理函数(SimpleBLEPeripheral.c中)
static void GUA_Key_Process(void); //按键处理函数
4、在应用层中使用按键
1)按键初始化(SimpleBLEPeripheral.c的SimpleBLEPeripheral_Init中)
//按键初始化
Key_Init();
RegisterForKey(simpleBLEPeripheral_TaskID, SBP_KEY_CHECK_PROCESS_EVT);
2)应用层代码中添加按键驱动头文件(SimpleBLEPeripheral.c中)
//GUA
#include "Key.h"
//GUA
七、注意事项
暂无
八、实验结果
手头没有按键,因此拿一根跳线,一端接在GND,另一端不停地触碰P12引脚,则会发现P10对应的LED1会随着触碰不停地亮灭。
因此实验成功,实现P12按键触发P10的led亮灭。