本文介绍了在nRF51822上如何开始编写低功耗蓝牙(BLE)应用程序,包括对BLE的特性进行了概要的介绍,并且详细描述了构建一个定制服务的简单例程,这个简单的例程叫做LED Button服务。 1 简介 本文的目的是教你如何一步步创建自己的BLE应用程序,包括使用nRF51822芯片创建一个定制的服务。 1.1 昀低要求 需要有嵌入式C语言编程经验,以便完全理解本应用手册。 1.1.1 需要的工具 需要一个nRF51822 Evaluation Kit的开发板,另外还需要下载和安装以下软件工具: • S110 SoftDevice • nRFgo Studio • nRF51 SDK • Keil MDK‐ARM • SEGGER’s J‐Link tools 如何把协议栈固件S110 SoftDevice烧录到nRF51822芯片中请参考:《nRF51822 Evaluation Kit User Guide》。 注意:当编写本文档时参考了昀新版本的nRF51 SDK 5.2.0和昀新版本的协议栈S110 SoftDevice 6.0.0。 1.2 文档说明 下面的文档是重要的参考资料。 文档 描述 nRF51822 Evaluation Kit User Guide 使用Evaluation Kit开发板的介绍和配置,包括Keil和SoftDevice的配置。 nRF51 SDK documentation 这个文件在SDK安装的文件夹之下的子文件夹中,包含了SDK中所有功能API的文档。 S110 nRF51822 SoftDevice Specification 介绍了协议栈S110 SoftDevice,包括资源的用法和高级的功能函数。 nRF51822 Product Specification 描述了nRF51的硬件、模块和电气特性。 nRF51 Series Reference Manual 介绍了nRF51芯片系列所有功能模块的描述和芯片所有的外围资源。 nAN‐15: Creating Applications with the Keil C51 Compiler 这个应用手册包含使用Keil μVision的信息,它为nRF24LE1芯片而写,但是3.3节“Including files”和3.4节““Debug your project”同样适用于nRF51822芯片。 Bluetooth Core Specification, version 4.0 卷1,3,4,6 这个文档由蓝牙技术联盟组织提供,包含了关于蓝牙服务和profiles的信息。 1.3 蓝牙技术资源 所有蓝牙技术联盟的服务、特性和描述都是根据蓝牙开发网站来定义,可以参考规范的不同部分找到UUID或者是数据格式的定义。 1.4 nRF51822 和 S110 SoftDevice S110 SoftDevice是BLE外围设备协议栈的解决方案,它集成了低功耗控制器、主机,并提供了一个完整和灵活的API用于在一个片上系统(SoC)构建一个低功耗蓝牙的解决方案,S110 SoftDevice提供的是已经编译完成的HEX文件,在加载你的应用程序之前,你必须把它预先烧录到芯片中。 S110 SoftDevice 使用了一部分芯片的flash和RAM,它们在你的代码中已被保护,因此你不能意外地写数据到该区域。S110 SoftDevice也需要互斥地访问外围资源和寄存器。 如何烧录S110 SoftDevice到nRF51822中请参考: 《nRF51822 Evaluation Kit User Guide》 SoftDevice使用了哪些资源,请参考: 《nRF51822 S110 SoftDeviceSpecification》 1.5 应用简述 LED Button 应用示例是为了让你学习如何在nRF51822上开发BLE应用,它是一个通过BLE的通知功能进行通信的BLE应用的简单演示。当它运行时,你可以通过集中器(见第10页2.2.1节“角色”中对集中器的定义部分)触发nRF51822上LED的输出,并且当在nRF51822上的按键被按下时集中器将会收到一个通知。 这个应用通过一个服务(见第10页2.2.2节“GATT层”服务和特性的描述部分)被建立,这个服务包括2个特性:LED特性和按键特性。LED特性:通过没有回应的写远程操作LED的亮灭。按键特性:当按键被按下时,将会发送一个通知到集中器。 2 BLE介绍 本章将介绍BLE协议不同的层,包括各个层的部件和它们的概念。 2.1 通用访问规范(Generic Access Profile,GAP) GAP是应用层能够直接访问BLE协议栈的昀底层,它包括管理广播和连接事件的有关参数。 注意:GAP的更多详细介绍见《Bluetooth Core Specification》(蓝牙核心规范)的第3卷C部分。 2.1.1 角色 为了创建和维持一个BLE连接,引入了“角色”这一概念。一个BLE设备不是集中器角色就是外围设备角色,这是根据是谁发起这个连接来确定的。集中器设备总是连接的发起者,而外围设备总是被连接者。集中器和外围设备的关系就像链路层中的主机和从机的概念。 在LED Button应用例程中,使用S110 SoftDevice烧录到nRF51822作为外围设备,计算机或者手机作为集中器。 除了集中器角色和外围设备角色,蓝牙核心规范还定义了观察者角色和广播者角色,观察者角色监听空中的事件,广播者角色只是广播信息而不接收信息。观察者角色和广播者角色都只广播而并不建立连接。它们在我们的这个应用中并不适用。 注意:在一个连接的另一端的设备被称为对等设备,不管它是集中器还是外围设备。 2.1.2 广播 集中器能够与外围设备建立连接,外围设备必须处于广播状态,它每经过一个时间间隔发送一次广播数据包,这个时间间隔称为广播间隔,它的范围是20ms到10.24s。广播间隔影响建立连接的时间。 集中器发送一个连接请求来发起连接之前,必须接收到一个广播数据包,外围设备发送一个广播数据包之后一小段时间内只监听连接请求。 一个广播数据包昀多能携带31字节的数据,它通常包含用户可读的名字、关于设备发送数据包的有关信息、用于表示此设备是否可被发现的标志等类似的标志。 当集中器接收到广播数据包后,它可能发送请求更多数据包的请求,称为扫描回应,如果它被设置成主动扫描,外围设备将会发送一个扫描回应做为对集中器请求的回应,扫描回应昀多可以携带31字节的数据。 广播,包括扫描请求和扫描回应,出现在远离WLAN使用的2.4G频段之外的3个频率上,以防止被WiFi干扰。 2.1.3 扫描 扫描是集中器监听广播数据包和发送扫描请求的过程,它有2个定时参数需要特别注意:扫描窗口和扫描间隔。 对于每一个扫描间隔,集中器扫描的时间等于一个扫描窗口,这就意味着如果扫描窗口等于扫描间隔,那么集中器将处于连续扫描之中。扫描窗口和扫描间隔之比为扫描占空比。 2.1.4 发起 如果集中器想建立一个连接,当扫描监听到广播数据包后它将采用相同的过程:当要发起连接时,集中器接收到一个广播数据包之后将会发送一个连接请求。 2.1.5 连接 集中器和外围设备第一次交换数据定义为连接状态。在一个连接状态中,集中器将会在一个特定定义的间隔从外围设备请求数据,这个间隔称为连接间隔,它由集中器决定并应用于连接,但是外围设备可以发送连接参数更新请求给集中器。根据蓝牙核心规范,连接间隔必须在7.5ms到4s之间。 如果外围设备在一个时间帧内没有回应集中器的数据包,称为连接监管超时,连接被认为丢失。 可以通过在每一个连接间隔中传输多个数据包以获得更高的数据吞吐量,每一个传输数据包昀多可以携带20个字节的应用数据。但是如果电流消耗是重点,同时外围设备也没有数据要发送,它可以选择忽略一定数量的连接间隔,这个忽略连接间隔的数目称为从机延时(slave latency)。 在一个连接中,除了广播信道,设备间在频带的所有信道中进行通信。当然对于应用层,这是完全透明的。 2.2 通用属性配置文件(Generic Attribute profile,GATT) GATT层是传输真正数据所在的层。 2.2 2.2.1角色 除了GAP定义了角色之外,BLE还定义了另外2种角色:GATT服务器和GATT客户端,它们完全独立于GAP的角色。提供数据的设备称为GATT服务器,访问GATT服务器而获得数据的设备称为GATT客户端。 以LED Button应用为例,外围设备(带有LED和按键)作为服务器,集中器作为客户端。 注意:一个设备可以同时作为服务器和客户端。 2.2.2 GATT层 一个GATT服务器通过一个称为属性表的表格组织数据,这些数据就是用于真正发送的数据。 2.2.2.1 属性 一个属性包含句柄、UUID、值,句柄是属性在GATT表中的索引,在一个设备中每一个属性的句柄都是唯一的。UUID包含属性表中数据类型的信息,它是理解属性表中的值的每一个字节的意义的关键信息。在一个GATT表中可能有许多属性,这些属性能可能有相同的UUID。 2.2.2.2 特性 一个特性至少包含2个属性:一个属性用于声明,一个属性用于存放特性的值。 所有通过GATT服务传输的数据必须映射成一系列的特性,可以把特性中的这些数据看成是一个个捆绑起来的数据,每个特性就是一个自我包容而独立的数据点。例如,如果几块数据总是一起变化,那么我们可以把它们集中在一个特性里。 以LED Button应用为例,外围设备(带有LED和按键)作为服务器,集中器作为客户端。 在LED Button服务中,LED和按键之间没有任何联系,而且它们可以各自独立地改变, 因此,可以让它们成为独立的特性,所以我们用一个特性表示当前按键的状态,用另一个特性用来表示当前LED的状态。 2.2.2.3描述符 任何在特性中的属性不是定义为属性值就是为描述符。描述符是一个额外的属性以提供更多特性的信息,它提供一个人类可识别的特性描述的实例。 然而,有一个特别的描述符值得特别地提起:客户端特性配置描述符(Client Characteristic Configuration Descriptor,CCCD),这个描述符是给任何支持通知或指示功能的特性额外增加的,参见第15页第2.2.5节“空中操作和性质”。 在CCCD中写入“1”使能通知功能,写入“2”使能指示功能,写入“0”同时禁止通知和指示功能。 在S110 SoftDevice协议栈中,对任何使能了通知功能或是指示功能的特性,协议栈将自动加入这个类型的描述符。 2.2.2.4服务 一个服务包含一个或多个特性,这些特性是逻辑上相关的集合体。 GATT服务一般包含几块具有相关的功能,比如特定传感器的读取和设置,人机接口的输入输出。组织具有相关的特性到服务中既实用又有效,因为它使得逻辑上和用户数据上的边界变得更加清晰,同时它也有助于不同应用程序间代码的重用。GATT基于蓝牙技术联盟(SIG)官方而设计,SIG建议根据它们的规范设计自己的profile。 对于LED Button应用例程,因为不关心它们的重用,所以把LED特性和按键特性放到了一个服务中。 2.2.2.5 profile(数据配置文件) 一个profile文件可以包含一个或者多个服务,一个profile文件包含需要的服务的信息或者为对等设备如何交互的配置文件的选项信息。设备的GAP和GATT的角色都可能在数据的交换过程中改变,因此,这个文件应该包含广播的种类、所使用的连接间隔、所需的安全等级等信息。 需要注意的是一个profile中的属性表不能包含另一个属性表。 在LED BUTTON示例中的profile不是一个标准描述的profile。 2.2.3 标准的定制服务和特性 蓝牙技