本篇博文最后修改时间:2017年01月06日,11:06。
一、简介
本文以SimpleBLEPeripheral为例,通过按键触发广播数据的变化,实现按一次按键改变一次广播数据。
二、实验平台
协议栈版本:BLE-CC254x-1.4.0
编译软件:IAR 8.20.2
硬件平台:Smart RF开发板(主芯片CC2541)、USB Dongle
三、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.NET/feilusia
联系方式:897503845@qq.com
香瓜BLE之CC2541群:127442605
香瓜BLE之CC2640群:557278427
五、基础知识
1、动态广播的思路是怎么样的?
答:
1)按键触发进入按键处理事件simpleBLEPeripheral_HandleKeys。
2)关闭广播。
3)进入SBP_KEY_UPDATE_ADV_EVT事件(自定义),调用GAP_UpdateAdvertisingData修改广播数据。
4)开启广播。
注:
2、动态广播的实验预期现象是怎么样的?
答:
1)板子上电:广播默认的数据
static uint8 advertData[] =
{
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16( SIMPLEPROFILE_SERV_UUID ),
HI_UINT16( SIMPLEPROFILE_SERV_UUID ),
};
2)按键按1、2、4、5、7、8次……(非3的倍数次)
uint8 advertData_Update[] =
{
0x07, //自定义短名的长度
GAP_ADTYPE_LOCAL_NAME_SHORT,
0x47, //G
0x55, //U
0x41, //A
0x3A, //:
0x20, //键值
0x00, //给按键次数预留
0x03, //UUID字段长度
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16( SIMPLEPROFILE_SERV_UUID ),
HI_UINT16( SIMPLEPROFILE_SERV_UUID ),
};
第8字节累加。
3)按键按3、6、9次(3的倍数次)
与板子上电时的协议栈默认广播数据一样。
六、实验步骤
1、添加一个“动态广播”事件
1)定义事件(SimpleBLEPeripheral.c的SimpleBLEPeripheral_ProcessEvent函数中)
if ( events & SBP_KEY_UPDATE_ADV_EVT ) //按键更新广播事件
{
return (events ^ SBP_KEY_UPDATE_ADV_EVT);
}
#define SBP_KEY_UPDATE_ADV_EVT 0x0008
2、添加动态广播的处理代码
1)定义一个变量用于按键计数(SimpleBLEPeripheral.c中)
static uint8 key_count = 1;
2)修改按键处理函数(SimpleBLEPeripheral.c中)
/*********************************************************************
* @fn simpleBLEPeripheral_HandleKeys
*
* @brief Handles all key events for this device.
*
* @param shift - true if in shift/alt.
* @param keys - bit field for key events. Valid entries:
* HAL_KEY_SW_2
* HAL_KEY_SW_1
*
* @return none
*/
static void simpleBLEPeripheral_HandleKeys( uint8 shift, uint8 keys )
{
VOID shift; // Intentionally unreferenced parameter
if ( keys & HAL_KEY_SW_6 )
{
uint8 initial_advertising_enable = FALSE;
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );//关广播
osal_start_timerEx( simpleBLEPeripheral_TaskID, SBP_KEY_UPDATE_ADV_EVT, 0 );//修改广播数据
}
}
3)添加SBP_KEY_UPDATE_ADV_EVT事件中的处理(SimpleBLEPeripheral.c中)
if ( events & SBP_KEY_UPDATE_ADV_EVT ) //按键更新广播事件
{
uint8 advertData_Update[] =
{
0x07, //自定义短名的长度
GAP_ADTYPE_LOCAL_NAME_SHORT,
0x47, //G
0x55, //U
0x41, //A
0x3A, //:
0x00, //给键值预留
0x00, //给按键次数预留
0x03, //UUID字段长度
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16( SIMPLEPROFILE_SERV_UUID ),
HI_UINT16( SIMPLEPROFILE_SERV_UUID ),
};
advertData_Update[6] = HAL_KEY_SW_6; //把按键值放到广播数据中
advertData_Update[7] = key_count; //把按键值放到广播数据中
if((key_count++)%3)//如果按键次数不是3的倍数,则广播我自己的数据
{
GAP_UpdateAdvertisingData(simpleBLEPeripheral_TaskID,
TRUE,
sizeof(advertData_Update),
advertData_Update ); //更新广播数据
}
else//如果按键次数是5的倍数,则广播协议栈本来的数据
{
GAP_UpdateAdvertisingData(simpleBLEPeripheral_TaskID,
TRUE,
sizeof(advertData),
advertData ); //更新广播数据
}
uint8 initial_advertising_enable = TRUE;
GAPRole_SetParameter( GAPROLE_ADVERT_ENABLED, sizeof( uint8 ), &initial_advertising_enable );//开广播
return (events ^ SBP_KEY_UPDATE_ADV_EVT);
}
注:GAP_UpdateAdvertisingData的第二个形参为TRUE时修改的是广播数据、为FALSE时修改的是扫描应答数据。
这里只以广播数据为例,扫描应答数据的修改也是类似的。
七、注意事项
手机可能缓存了之前的代码(在更新过CC2541的代码之后,都需要清除手机端的缓存!!!),因此要清除缓存,清除缓存的方法如下:
方法一:关闭app、关闭蓝牙总开关、打开蓝牙总开关、打开app。
方法二:手机重启。
使用抓包软件Packet Sniffer,来观察CC2541的广播过程。
1、上电广播
这是协议栈默认的广播数据。
2、按键按1下
可以看到广播数据变了,并且第8个数据是当前的按键次数1。
3、按键按2下
第8个字节的按键次数由1变成了2。
4、按键按3次
按键次数为3的倍数,所以修改回协议栈默认的广播数据。
5、按键按4次
非3的倍数次按键,都会是我自己定义的数据。此时第8字节是4次按键。
成功地通过按键变换广播数据。
因此,实验成功。