【BLE】CC2541之自定义按键

本篇博文最后修改时间: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

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、 实验前提
1、在进行本文步骤前,请先 阅读 以下博文:
暂无

2、在进行本文步骤前,请先 实现以下博文:
暂无


五、基础知识

暂无


六、实验步骤

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;        //清中断标志   
} 

2)写一个按键头文件Key.h (存放在“……\BLE-CC254x-1.4.0\Projects\ble\SimpleBLEPeripheral\Source\GUA”路径下)

//******************************************************************************          
//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


3)工程中添加Key.c和Key.h

【BLE】CC2541之自定义按键_第1张图片


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);
  } 

2)定义一个按键事件的宏(SimpleBLEPeripheral.h中)
#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亮灭。


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