BLE简介、体系结构与核心概念
讲的是BLE,不是经典蓝牙
蓝牙简介
基本概念
蓝牙版本
由此可见
蓝牙协议是一个通用协议;
BLE是属于蓝牙4.0以上版本的规范。
设备类型
一般来说,手机都是双模设备,既支持蓝牙低功耗,又支持传统蓝牙,所以,不管蓝牙模组使用的是BLE还是传统蓝牙,手机都能和他们建立连接并通信。
CC2640就是一个单模的设备,只支持BLE。
注意:
传统蓝牙和低功耗蓝牙在底层的射频硬件上是一样的,这使得二者可以有很好的兼容性。
蓝牙 4.0 规范将低功耗蓝牙的硬件芯片分为两类,分别是单模(Single Mode)和双模(Dual Mode)。双模蓝牙就是把传统蓝牙和低功耗蓝牙集成到同一个芯片中,它能够兼容传统蓝牙和低功耗蓝牙,具有良好的互操作性,具备现有蓝牙技术的大部分功能和射频功能。与现在的芯片相比,这样的芯片增加的费用是最少的,通常被安装在便携式计算机、智能手机、平板电脑等智能电子设备上。而单模蓝牙仅仅支持低功耗蓝牙,芯片集成度很高且尺寸很小,功耗很低,为传统蓝牙功耗的 10% 左右。低功耗蓝牙协议栈有一个简化的链路层,提供超低功耗的运行模式,它找到设备的过程很简单,点对多点的数据传输很可靠,具有先进的节电功能和加密功能,一般用于低成本、功能要求低及资源受限的设备,或仅仅支持低功耗蓝牙的设备。例如,具备蓝牙功能的温度采集器、心率监测器等只具备为主设备发送收集到的数据,而不具备接收主设备指令的低功耗器件。这类器件的结构及功能一般相对简单且功耗较低,待机运行时间一般都在几个月以上。
蓝牙主机和蓝牙从机
蓝牙通信中,分为主机和从机,有的模组实现了从机功能,就只能作为从机;有的模组实现了主机功能,就只能作为主机;有的模组既实现了主机功能,又实现了从机功能,所以是主从一体的,既能配置为主机,也能配置为从机。所以在购买蓝牙模组时,就需要注意自己到底需要买的是哪种类型的模组。像nRF52832蓝牙主控芯片,购买时并不存在是主机还是从机一说,而是我们自己用代码去实现主机还是从机的功能。
通常来说,蓝牙协议是一个通用协议,只要主从双方,都是使用的蓝牙协议,并且,从机是在主机的连接范围之内,就可以连接。就像单片机的程序,只要是同一款芯片,不管是烧到哪个芯片里,作用都是一样的,要做的,可能就是改变一下引脚定义,应用软件部分是不用修改的。
BLE体系结构
关于蓝牙协议栈的分层结构说明,参考:
蓝牙协议栈分层_蓝牙协议栈有几层组成?各层的协议有哪些?_wwwlyj123321的博客-CSDN博客
这篇文章可以作为入门来看。
如下所示:
从对链路层的描述我们可以知道:
1、一个设备,同一时刻,要么是主机,要么是从机,不可能同时既是主机又是从机。
2、只有建立连接之后,才会互传数据,所以为什么要建立连接之后模组才能进入透传模式,就是这个原因。
3、为什么需要AT指令模式,就是因为设备上电后,不可能直接进入连接态,必须先设置,然后经由广播态或者发起态才能进入连接态。因此,我们在编写程序时,一定是先设置AT指令,开启广播,连接成功后才会发送透传数据。
链路层信道映射
补充
频率和信道分布
BLE(蓝牙,Bluetooth Low Energy 包括经典蓝牙)主要使用 2.4 GHz ISM 频段(工业、科学和医疗频段),具体频率范围为 2.400 GHz 至 2.4835 GHz。
以下是 BLE 的信道划分详情:
1. 信道总数
BLE 将 2.4 GHz 频段划分为 40 个信道,每个信道带宽为 2 MHz。
(相比之下,经典蓝牙划分为 79 个信道,每个带宽 1 MHz)。
2. 信道的分类与用途
这 40 个信道根据用途分为两类:
A. 广播信道(3 个)
用于设备发现、广播数据、建立连接。
信道索引:37、38、39
中心频率:
信道 37:2402 MHz
信道 38:2426 MHz
信道 39:2480 MHz
设计特点:这三个信道刻意分散在频段的低、中、高三个位置,目的是避开同样使用 2.4 GHz 频段的 Wi-Fi(通常会占用信道 1、6、11)的干扰。即使 Wi-Fi 信号很强,至少有一个 BLE 广播信道能正常工作。
B. 数据信道(37 个)
用于连接建立后的数据传输。
信道索引:0 到 36
中心频率:计算公式为 2402+�×22402+k×2 MHz(其中 �k 为信道索引,范围为 0~36)。
例如:信道 0 中心频率为 2402 MHz,信道 36 中心频率为 2478 MHz。
跳频机制:BLE 采用自适应跳频技术。在连接状态下,设备会在 37 个数据信道之间快速跳频(通常每秒几百次)。如果某个信道检测到干扰(如与 Wi-Fi 重叠),协议栈会将该信道标记为“已映射”,并跳过它,从而保证通信的可靠性。
3. 与经典蓝牙的区别
特性 BLE 经典蓝牙 信道数量 40 个 79 个 信道带宽 2 MHz 1 MHz 广播信道 3 个(37/38/39) 32 个(用于查询/寻呼) 数据信道 37 个(自适应跳频) 79 个(跳频) 4. 信道避让与共存
由于 2.4 GHz 频段非常拥挤(Wi-Fi、Zigbee、Thread、微波炉等均在此频段),BLE 的 3 个广播信道(37、38、39) 在选址上经过了特殊考量:
信道 37 (2402 MHz):位于 Wi-Fi 信道 1 的左侧保护带。
信道 38 (2426 MHz):位于 Wi-Fi 信道 6 的间隙之间。
信道 39 (2480 MHz):位于 Wi-Fi 信道 11 的右侧保护带。
这种分布确保了即使在 Wi-Fi 流量繁忙的环境中,BLE 广播包依然有较大概率成功收发。
UUID
UUID(通用唯一标识符)详解
UUID 是 BLE 协议栈中最基础的标识体系,贯穿服务、特征、描述符、甚至厂商自定义数据的每一个角落。
一、什么是 UUID?
UUID = Universally Unique Identifier(通用唯一标识符)
它是一个 128 位(16 字节) 的数字,用于全球唯一地标识某个东西——在 BLE 中,它标识的是服务、特征、描述符的类型。
二、为什么需要 UUID?
BLE 设备之间要通信,必须知道对方的数据类型:
问题:手机连接心率带后,怎么知道哪个数据是心率? 解决: - 心率服务用 UUID = 0x180D 标识 - 心率测量特征用 UUID = 0x2A37 标识 - 手机发现这些 UUID,就知道如何解析数据UUID 的作用:让不同厂商的设备能够互操作——只要遵循相同的 UUID 定义,任何心率带都能被任何手机识别。
三、UUID 的两种格式
1. 16-bit UUID(短格式)
属性 说明 长度 2 字节(16 位) 范围 0x0000 ~ 0xFFFF 用途 蓝牙 SIG 定义的标准服务/特征 示例 0x180D(心率服务)、0x2A37(心率测量)2. 128-bit UUID(长格式)
属性 说明 长度 16 字节(128 位) 用途 厂商自定义的私有服务/特征 示例 0000180D-0000-1000-8000-00805F9B34FB四、16-bit 与 128-bit 的转换
蓝牙 SIG 定义了一个基础 UUID:
00000000-0000-1000-8000-00805F9B34FB转换公式:将 16-bit UUID 填入基础 UUID 的如下
0000位置。
16-bit UUID 转换为 128-bit UUID 0x180D0000180D-0000-1000-8000-00805F9B34FB0x2A3700002A37-0000-1000-8000-00805F9B34FB0x180A0000180A-0000-1000-8000-00805F9B34FB为什么这样设计?
节省空间:广播包中传输 2 字节的
0x180D比 16 字节的完整 UUID 高效得多统一性:所有标准 UUID 都基于同一个基础 UUID,便于识别
五、UUID 的分类与范围
1. 蓝牙 SIG 分配的标准 UUID
类别 16-bit 范围 用途 服务 UUID 0x1800 ~ 0x27FF 标准服务(心率、电池、设备信息等) 特征 UUID 0x2A00 ~ 0x3FFF 标准特征(心率值、电量、设备名等) 描述符 UUID 0x2900 ~ 0x29FF 标准描述符(CCCD、用户描述等) 2. 厂商自定义 UUID
范围 说明 0x0000 ~ 0xFFFF 16-bit 范围内已被 SIG 占用,厂商不能随意使用 128-bit 厂商使用完整的 16 字节 UUID,保证全球唯一 厂商自定义 128-bit UUID 示例:
F000AA01-0451-4000-B000-000000000000 ← TI 传感器标签 0000FFE0-0000-1000-8000-00805F9B34FB ← Nordic UART Service六、常用标准 UUID 速查表
标准服务(部分)
服务名称 UUID 说明 通用访问服务 (GAP) 0x1800 设备名称、外观、连接参数 通用属性服务 (GATT) 0x1801 服务变更通知 设备信息服务 (DIS) 0x180A 制造商、型号、序列号 电池服务 0x180F 电池电量 心率服务 0x180D 心率数据 血压服务 0x1810 血压数据 环境感知服务 0x181A 温湿度、气压 定位和导航服务 0x1819 位置、速度 健身器械服务 0x1826 跑步机、健身车数据 标准特征(部分)
特征名称 UUID 说明 设备名称 0x2A00 设备名称字符串 外观 0x2A01 设备类型编码 制造商名称 0x2A29 厂商名称字符串 型号 0x2A24 设备型号 序列号 0x2A25 设备序列号 电池电量 0x2A19 0~100% 心率测量 0x2A37 心率值 + 标志位 位置 0x2A67 GPS 坐标 温度 0x2A6E 温度值 湿度 0x2A6F 湿度百分比 标准描述符(部分)
描述符名称 UUID 说明 特征用户描述 0x2901 特征的人类可读名称 客户端特征配置 (CCCD) 0x2902 通知/指示的开关 特征表示格式 0x2904 数据的格式、单位 特征有效范围 0x2906 有效值范围 七、UUID 在 BLE 协议中的位置
┌─────────────────────────────────────────────────────────────┐ │ 设备 │ ├─────────────────────────────────────────────────────────────┤ │ 【服务】UUID = 0x180F (电池服务) │ │ └─ 【特征】UUID = 0x2A19 (电池电量) │ │ ├─ 特征值:85(实际电量) │ │ └─ 【描述符】UUID = 0x2902 (CCCD) │ │ └─ 值:0x0001(通知已启用) │ ├─────────────────────────────────────────────────────────────┤ │ 【服务】UUID = 0x180A (设备信息服务) │ │ ├─ 【特征】UUID = 0x2A29 (制造商名称) │ │ │ └─ 特征值:"Apple" │ │ └─ 【特征】UUID = 0x2A24 (型号) │ │ └─ 特征值:"AirPods Pro" │ └─────────────────────────────────────────────────────────────┘八、UUID 的查找方式
1. 官方文档
蓝牙 SIG 官网维护完整的 UUID 列表:
https://www.bluetooth.com/specifications/assigned-numbers/
2. 常用工具
工具 说明 nRF Connect 扫描设备后自动显示服务/特征的 UUID 和名称 LightBlue 类似,界面友好 Wireshark 抓包时自动解析标准 UUID 3. 常见 UUID 速记
很多开发工具会显示 UUID 的简称:
0x180F→ "Battery Service"
0x2A19→ "Battery Level"
0x2902→ "Client Characteristic Configuration"九、厂商自定义 UUID 的规范
当开发自己的 BLE 设备时,如果需要定义私有服务/特征,应该使用 128-bit UUID。
生成方式
# Python 示例 import uuid my_uuid = uuid.uuid4() print(my_uuid) # 例如:550e8400-e29b-41d4-a716-446655440000自定义 UUID 示例(Nordic UART Service)
服务 UUID: 0000FFE0-0000-1000-8000-00805F9B34FB 特征 UUID 1: 0000FFE1-0000-1000-8000-00805F9B34FB (TX) 特征 UUID 2: 0000FFE2-0000-1000-8000-00805F9B34FB (RX)自定义 UUID 的注意事项
不要使用 16-bit 范围内的值:可能未来被 SIG 占用,造成冲突
使用随机生成的 128-bit UUID:保证唯一性
在广播数据中:如果需要广播服务 UUID,16-bit 更省空间;128-bit 会占用更多广播包空间
十、UUID 在广播包中的体现
广播包示例(iBeacon)
02 01 06 1A FF 4C 00 02 15 63 6F 3F 8F 64 91 48 EE 95 F7 D8 CC 64 A8 63 B5 00 00 00 00 C8 00其中
1A FF 4C 00表示:
1A= 26 字节数据
FF= AD Type 0xFF(厂商数据)
4C 00= 公司 ID 0x004C(Apple)后面的数据是 iBeacon 格式,其中包含 16 字节的 UUID(
63 6F 3F 8F...)服务 UUID 的广播
广播包可能包含: - AD Type 0x02:不完整的 16-bit 服务 UUID 列表 - AD Type 0x03:完整的 16-bit 服务 UUID 列表 - AD Type 0x06:不完整的 128-bit 服务 UUID 列表 - AD Type 0x07:完整的 128-bit 服务 UUID 列表十一、总结
问题 答案 什么是 UUID? 128 位全局唯一标识符,用于标识服务、特征、描述符的类型 为什么需要 UUID? 让不同厂商的设备能够互操作,知道对方的数据格式 两种格式的区别? 16-bit 用于标准服务/特征(省空间),128-bit 用于厂商自定义(全球唯一) 如何转换? 16-bit UUID + 基础 UUID = 128-bit UUID 谁分配 UUID? 蓝牙 SIG 分配标准 UUID,厂商自己生成自定义 UUID 如何查找 UUID? 蓝牙 SIG 官网、nRF Connect、LightBlue 等工具 自定义 UUID 注意什么? 使用随机生成的 128-bit UUID,不要占用 16-bit 范围 一句话总结
UUID 是 BLE 世界的"身份证号"——服务用它表明"我是谁",特征用它表明"我是什么数据",描述符用它表明"我如何配置"。
可参考:蓝牙小知识:UUID 是什么 - 物联网技术分享
UUID是“Universally Unique Identifier”的简称,通用唯一识别码的意思。对于蓝牙设备,每个服务/特征都有通用、独立、唯一的UUID与之对应。
常用的是16bit的UUID,也就是16位的别名。
比如,设备名称的UUID为0x2A00,是固定的,蓝牙协议里规定的。
服务/特征/属性……
先大概认识下,Profile、Service、Characteristic
一、一句话定调
服务是功能模块,特征是模块下的数据点,特征属性是操作权限,特征值是实际数据,描述符是配置开关,UUID是身份证号。
二、概念详解
1. 服务(Service)
定义:相关特征的容器,代表设备的一项功能模块。
设备:智能手环 ├── 服务1:心率服务 (UUID: 0x180D) │ ├── 心率测量特征 │ └── 体感位置特征 ├── 服务2:电池服务 (UUID: 0x180F) │ └── 电池电量特征 └── 服务3:设备信息服务 (UUID: 0x180A) ├── 制造商名称特征 └── 型号特征要点:
一个设备可以有多个服务
服务之间相互独立
通过 UUID 识别(如
0x180D= 心率服务)2. 特征(Characteristic)
定义:服务中的最小数据单元,代表一个具体的数据点。
服务:心率服务 ├── 特征:心率测量 (UUID: 0x2A37) ├── 特征:体感位置 (UUID: 0x2A38) └── 特征:心率控制点 (UUID: 0x2A39)要点:
特征是逻辑概念,不直接存数据
每个特征有唯一的 UUID
特征由多个属性组成(声明、特征值、描述符)
3. 特征值(Characteristic Value)
定义:特征中实际存储的数据。
特征:心率测量 └── 特征值:72(当前心率)要点:
这是你真正想要的数据
存储在特征值属性中
可以通过读/写/通知来访问
4. 特征属性(Characteristic Properties)
定义:定义如何操作特征值的权限标志。
属性 方向 说明 Read 客户端 → 服务器 读取特征值 Write 客户端 → 服务器 写入特征值(需确认) Write Without Response 客户端 → 服务器 写入(无需确认,更快) Notify 服务器 → 客户端 主动推送(无确认) Indicate 服务器 → 客户端 主动推送(有确认) Broadcast 服务器 → 所有人 通过广播发送 组合示例:
心率测量特征属性:Read | Notify - 可以读取当前心率 - 心率变化时会主动推送 电池电量特征属性:Read - 只能读取,不能写入 - 不会主动推送5. 描述符(Descriptor)
定义:特征的配置信息或元数据。
描述符 UUID 作用 CCCD 0x2902 最重要!控制 Notify/Indicate 的开关 用户描述 0x2901 特征的人类可读名称("心率测量") 表示格式 0x2904 数据的格式、单位(如 uint8, bpm) 有效范围 0x2906 有效值范围(0-255) CCCD 示例:
特征:心率测量(支持 Notify) ├── CCCD 值:0x0001 ← 表示"通知已启用" └── 客户端写入 0x0001 后,服务器才开始推送心率数据6. UUID(通用唯一标识符)
定义:服务、特征、描述符的全球唯一身份证。
格式 长度 用途 示例 16-bit 2 字节 标准服务/特征 0x180D(心率服务)128-bit 16 字节 厂商自定义 550e8400-e29b-41d4-a716-4466554400007. 属性(Attribute)
定义:GATT 层的物理存储单元,实际存放数据的数据结构,比如C语言中的结构体。
┌─────────────────────────────────────────────────────────────┐ │ 特征:心率测量(逻辑概念) │ ├─────────────────────────────────────────────────────────────┤ │ 【属性1】特征声明 │ │ - 句柄: 0x0002 │ │ - UUID: 0x2803(固定) │ │ - 值: [属性: Notify\|Read, 值句柄: 0x0003, UUID: 0x2A37] │ ├─────────────────────────────────────────────────────────────┤ │ 【属性2】特征值 ← 实际数据在这里! │ │ - 句柄: 0x0003 │ │ - UUID: 0x2A37(心率测量) │ │ - 值: 72(当前心率) │ ├─────────────────────────────────────────────────────────────┤ │ 【属性3】CCCD 描述符 │ │ - 句柄: 0x0004 │ │ - UUID: 0x2902 │ │ - 值: 0x0001(通知已启用) │ └──────────────────
