本帖最后由 icode 于 2016-3-7 12:06 编辑
工欲善其事,必先利其器。所以俺在趁着活动弄了一块板,首先谢谢取码,好了,话不多说,言归正值传! 如果想了解BLE,当前蓝牙标准是不能不看的,现在最新的蓝牙标准是4.2,可以到度娘搜一下,当然2千多页的英文文档,也挺考验我们的耐心与英文水平,但好在里面的英文都比较简单,而且,你只需要看你需要的部分就可以了,好吧,关于蓝牙标准的问题,就先谈到这吧,如果您对蓝牙标准哪个地方有不了解的可以找我讨论,毕竟,俺还接触过有几年了。 蓝牙开发中,最基本的就是配置文件profile,有了这个profile,主机从机才能相互打招乎,才能知道怎么个礼尚往来,就像USB协议中的各种枚举类型一样,当然您一时闭会不理解这个profile是什么东西也没关系,等到你跑一两个例程,你就深谙其事了。关于GATT 的profile可以参看core4.2文档中的第3章《Vol3|:Core System Package[Host Volum]》中的partG:Generic Attrivute Profile这一部分有详细的讲解,请您有空了一定要耐着性子去看。 好吧,正面对着代码慢慢说: 首先建个自己的C文件,例如sample_service.c,sample_service.h,名字可以自己定义, /********************************************************************************************
文件名称 : ample_service.c
修订信息 : 2016年3月4日 09:15:18 By : Mark Xu
软件版本 : R00
文件描述 : 自定义的配置文件
Copyright 2005 - 2016 Mark Xu . All Rights Reserved.
-------------------------------------------------------------------------------------------------
注意事项: 1)...
修改记录 : 1)...
********************************************************************************************/
/* ------------------------------------------------------------------------------------------------
* 头文件
*-----------------------------------------------------------------------------------------------*/
#include "sample_service.h"
#include "connection_config.h"
/* ------------------------------------------------------------------------------------------------
* 全局变量 *------------------------------------------------------------------------------------------------
*/
extern BLE_RoleTypeDef BLE_Role;
/*------------------------------------------------------------------------------------------------
* 私有变量
*------------------------------------------------------------------------------------------------
*/
volatile int connected = FALSE;
volatile uint8_t set_connectable = 1;
volatile uint16_t connection_handle = 0;
volatile uint8_t notification_enabled = FALSE;
uint16_t sampleServHandle, TXCharHandle, RXCharHandle;
// 自己定义的服务 UUID
// uuid="7aac6ac0-afca-11e1-9feb-0002a5d5c51b"
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
const uint8_t service_uuid[16] =
{
0x1b,0xc5,0xd5,0xa5,0x02,0x00,0xeb,0x9f,0xe1,0x11,0xca,0xaf,0xc0,0x6a,0xac,0x7a
};
// 通过该 UUID,把数据发送给主机
const uint8_t charUuidTX[16] =
{
// uuid="aed04e80-afc9-11e1-a484-0002a5d5c51b"
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
0x1b,0xc5,0xd5,0xa5,0x02,0x00,0x84,0xa4,0xe1,0x11,0xc9,0xaf,0x80,0x4e,0xd0,0xae
};
// 通过该 UUID接收来自己主机的数据
const uint8_t charUuidRX[16] =
{
// uuid="19575ba0-b20d-11e1-b0a5-0002a5d5c51b"
// 0 1 2 3 4 5 6 7 8 9 a b c d e f
0x1b,0xc5,0xd5,0xa5,0x02,0x00,0xa5,0xb0,0xe1,0x11,0x0d,0xb2,0xa0,0x5b,0x57,0x19
};#define COPY_UUID_128(uuid_struct,uuid_15, uuid_14, uuid_13, uuid_12, uuid_11, uuid_10, uuid_9, uuid_8, uuid_7,uuid_6, uuid_5, uuid_4, uuid_3, uuid_2, uuid_1, uuid_0)
do {uuid_struct.uuid128[0] = uuid_0; uuid_struct.uuid128[1] = uuid_1;uuid_struct.uuid128[2] = uuid_2; uuid_struct.uuid128[3] = uuid_3;
uuid_struct.uuid128[4] = uuid_4; uuid_struct.uuid128[5] = uuid_5;uuid_struct.uuid128[6] = uuid_6; uuid_struct.uuid128[7] = uuid_7;
uuid_struct.uuid128[8] = uuid_8; uuid_struct.uuid128[9] = uuid_9;uuid_struct.uuid128[10] = uuid_10; uuid_struct.uuid128[11] = uuid_11;
uuid_struct.uuid128[12] = uuid_12; uuid_struct.uuid128[13] = uuid_13;uuid_struct.uuid128[14] = uuid_14; uuid_struct.uuid128[15] = uuid_15;
}while(0) 此处说一下,BLE支持16位的UUID与128位的UUID,关于UUID,16位的UUID有些已被 标准的配置占用了,比如心率,电池等,这个可以在蓝牙标准组织的网站上可以查看到,128位的UUID可以在网上直接生成,直接在度娘写入关键写“UUID在线生成”,立马会生成一坨(好吧,希望你不是在吃饭时看到该帖子的)…… //设置广播间隔 320*0.625ms = 200ms
#define MIN_DEF_ADVERTISING_INTERVAL 320
#define MAX_DEF_ADVERTISING_INTERVAL 336 理论上广播间隔可以20ms到10.24s之间,但是也要参看 手机方面的要求,太快或太慢,手机端都收不到,这个是手机操作系统有关,关于手机方面的要求,可以参看IOS及android方面的BLE编程要求,这里不做讨论,关于蓝牙标准上定义如下 所示,如果你读的蓝牙标准不是4.2.那么你可以在PDF中搜索关键字“ Advertising Interval”,在这里,俺设置为200ms: /* 应答数组
GAP - SCAN RSP data (max size = 31 bytes)
*/
const uint8_t scanRspData[] =
{
// complete name
0x09, // length of first data structure (9 bytes excluding length byte)
AD_TYPE_COMPLETE_LOCAL_NAME, // AD Type = Complete local name 0x09
'L', // -- 1
'O', // -- 2
'V', // -- 3
'E , // -- 4
' ', // -- 5
'B', // -- 6
'L', // -- 7
'E', // -- 8
};
关于应答数组,简单的说就是A机在广播,B机发送扫描请求,A机说可以,于是发给B机一个应答数组, 其最大长度是31个字节,数组的内容,可以是设备的名称,制造商信息,广播强度等,这个没有强制的要求,但对数组的结构有要求,关于数组的结构可以参看蓝牙标准《Vol3:Core System Package[Host volume]》--> --><11 Advertising and Scan Responese Data Formate>,如果蓝牙标准版本不一样,可以在pdf中搜索关键字“Scan data formate”,也希望您在有空的时候仔细把这一章节好好读几遍,书读百篇,其意自现,当然最重要的还是看源码,毕竟应用为主^_^// 定义 设备名称
const char local_name[] =
{
AD_TYPE_COMPLETE_LOCAL_NAME,
'L', // -- 1
'O', // -- 2
'V', // -- 3
'E , // -- 4
' ', // -- 5
'B', // -- 6
'L', // -- 7
'E', // -- 8
}; uint8_t manuf_data[]= /* 制造商信息,此处为测试用,所以定义为123*/
{
4, //
AD_TYPE_MANUFACTURER_SPECIFIC_DATA, // 0
0x31, // 1
0x32, // 2
0x33, //3
}; 下面就要创建我们的服务文件: /**************************************************************************************************
* 文件名称: Add_Sample_Service
*
* 函数功能: 添加指定的文件
*
* 入口参数: None
*
* 出口参数: tBleStatus - BLE_STATUS_SUCCESS 添加 成功 BLE_STATUS_ERROR添加失败
*
* 备 注:
**************************************************************************************************/
tBleStatus Add_Sample_Service(void)
{
tBleStatus ret;
ret = aci_gatt_add_serv(UUID_TYPE_128, service_uuid, PRIMARY_SERVICE, 7,&sampleServHandle);
if (ret != BLE_STATUS_SUCCESS) goto fail;
ret = aci_gatt_add_char(sampleServHandle, UUID_TYPE_128, charUuidTX, 20,(CHAR_PROP_NOTIFY|CHAR_PROP_READ), ATTR_PERMISSION_NONE, 0,
16, 1, &TXCharHandle);
if (ret != BLE_STATUS_SUCCESS) goto fail;
ret = aci_gatt_add_char(sampleServHandle, UUID_TYPE_128, charUuidRX, 20,CHAR_PROP_WRITE|CHAR_PROP_WRITE_WITHOUT_RESP, ATTR_PERMISSION_NONE,GATT_NOTIFY_ATTRIBUTE_WRITE,
16, 1, &RXCharHandle);
if (ret != BLE_STATUS_SUCCESS) goto fail;
PRINTF("Sample Service added.nTX Char Handle %04X, RX Char Handle%04Xn", TXCharHandle, RXCharHandle);
return BLE_STATUS_SUCCESS;
fail:
PRINTF("Error while adding Sample Service.n");
return BLE_STATUS_ERROR ;
} 关于添加服务的函数“aci_gatt_add_serv”可以在“bluenrg_gatt_aci.h”中找到,也有相应的说明,这里就不啰嗦了 关于添加服务的函数“ aci_gatt_add_char”,是添加character的函数,可以在“bluenrg_gatt_aci.h”中找到,也有相应的说明。 这里提醒一下,关于character的属性,请参考蓝牙标准《Volum3 - Core System Package [Hostvolume]》 --> -- ><3.3.1.1 Characteristic Properties>,此处做为测试,我设置发的UUID的属性为notify,这样,只要主机不需要实时查询,只要从机数据更改,就可以直接发送给主机
|