(二)蓝牙低功耗(BLE)基础教程--基于nRF5x系列SOC

时间:2024-03-10 08:02:01

蓝牙基本理论
  蓝牙核心规范对GATT(The Generic Attribute Profile)给出了如下定义:

GATT定义了一种进行数据交换的结构,结构中包含一些基本元素如服务(services)和特性(characteristics)。

  换句话说,GATT定义了一系列的规则,这些规则告诉我们如何使用 BLE 进行数据的传输,捆绑,展现等等。你可以阅读蓝牙核心规范 Bluetooth Core Specification v4.2, Vol. 3, Part G获取更详细的内容,虽然蓝牙核心规范读起来有些难懂,但还是值得一读的。

  蓝牙核心规范对服务(service)给出了如下定义:

服务是指一种数据以及与其相关的行为的集合。服务中有一些需要强制包含的特性或者可选择包含的特性。

   换句话说,服务是一些信息,例如传感器的某项测量值。为了方便行业发展,使得开发者更容易地让APPs与固件兼容,蓝牙SIG已经定义了一些标准服务,如心率服务。当然,你也可以根据自己的想法来定义需要用到的服务结构,而不必仅仅局限于蓝牙SIG中已定义的服务。

  蓝牙核心规范对特性(characteristic)的定义如下:

特性是指服务中使用的数值以及如何访问和表示这些数值的属性和配置信息。

   换句话说,特性是实际数值及相关信息具体表现,是其存储的地方。如用于保存传感器的某项测量值。安全参数等相关数据信息也被封装在特性里。
  与实际生活中的事物进行类比可以发现,假如一个房间里有许多柜子,每个柜子中都有许多抽屉,那么GATT profile就像是这个房间,柜子就是服务,抽屉是指特性,抽屉里有许多东西,就像特性中包含许多信息。有些抽屉被锁上了,从而限制了对内部信息的访问。
  举个例子,对于一个可以进行心率检测的手表,至少包含两种服务:
1.心率服务。包含3个特性:
   1)必要的心率测量特性,用于保存心率测量值。
   2)可选择的体传感器位置特性。
   3)有条件的心率控制点特性。
2.电池服务:
   1)必要的电池电量特性。

   说到这里,我们可能会有疑问,为什么要考虑这些麻烦的东西?为什么不直接发送需要的数据而不考虑什么服务,特性什么的?原因是灵活性,高效性,交叉平台的兼容性以及易于实现程度。当 iPhones,安卓平板,笔记本电脑等发现某个设备在广播心率服务时,依据标准,它们完全可以发现心率测量特性并且以一种标准的方式表示出来。如果某个设备包含许多服务,你可以*选择获取某项服务和特性。通过这种方式来包装这些信息,可以让设备快速发现可用的信息,并且快速获取特定的信息,从而节省了时间和能量。记住,BLE的指导方针就是低功耗。
   继续进行上面的类比,房间位于一个小型办公室里,里面有两个文件柜。一个柜子由会计师使用,抽屉里有财政文件,以日期分类保存。抽屉被锁上了,只有会计师和上级领导有权访问。另一个柜子由人力资源经理使用,保存了员工的相关记录表,以字母顺数排序保存。同样的,抽屉被锁住了,只有人力资源经理和上级领导可以访问。公司里的每一个人都知道这个房间在哪以及房间里保存了什么东西,但是只有某些特定人群有权访问。这样就确保了高效性,安全性及秩序。

通用唯一识别码 (UUID):
   在BLE学习过程中,我们会经常遇到UUID。它是一串数字,用来唯一识别特定服务,特性和描述符。这串数字可以通过无线传输,这样外设可以通知中心设备它提供了那些服务。
   为了减少传输时间和存储器空间,我们通常使用两种UUID,一种是短的16位UUID,另一种是长的128位UUID。例如,心率服务的16位UUID是0x180D,它包含的心率测量特性的UUID是0x2A37。16位UUID节省了能量和储存空间,但16位数字能表示的UUID有限,所以你只能使用蓝牙SIG已经定义好的UUID。如果要使用自己定义的UUID就需要使用另一种UUID表示型式了,即128位UUID。
   128位UUID的型式如: 4A98xxxx-1CC4-E7C1-C757-F1267DD021E8 ,称为基准UUID。四个x代表你自定义的16位ID,就像蓝牙SIG定义的16位UUID一样。这样你就可以将基准UUID保存在存储器中,然后使用自定义的16位UUID。需要提到的一点是并没有数据库保存已用的UUID以确保其使用的唯一性,但是你随机生成的两个128位UUID一样的概率非常低,大约:1/340,000,000,000,000,000,000,000,000,000,000,000,000。

示例
   将NRF52832官方提供的例程下载到SOC中运行可得:
这里写图片描述

这里写图片描述

   可以发现,即使我们没有做任何事情,就已经有了两个需要强制添加的服务:
1.通用访问服务。UUID为0x1800。包含三个必要特性:
   1)设备名,UUID=0x2A00
   2)外观, UUID=0x2A01
   3)外设最佳连接参数,UUID=0x2A04
2.通用属性服务。UUID为0x1801。包含一个可选特性:
   1)服务改变。UUID=0x2A05
通用访问服务包含设备的相关信息。你可以识别到设备名或者设备外观。外观可以告知其它设备本设备是什么,如鼠标这个外观。第三个特性包含许多用于连接的参数,如连接间隔MIN_CONN_INTERVAL,MAX_CONN_INTERVAL, SLAVE_LATENCY,CONN_SUP_TIMEOUT等等。通用属性服务可以用来通知*设备外设中包含的服务与特性的改变。

   创建一项服务主要包含7个步骤,具体细节在此不再赘述。主要有:1.声明一个服务结构体;2.初始化服务;3.添加UUID到蓝牙栈表;4.添加服务;5-7.广播128位UUID。

总结:
   到这里,你已经知道该如何设置和创建一项新的服务了。现在并没有完全结束,我们还需要创建服务中包含的特性,用来保存需要的数据。未完待续。。。