尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

一文搞清 BLE 蓝牙 UUID

一文搞清 BLE 蓝牙 UUID 一文带你搞清楚蓝牙 UUID ...... 矜辰所致 ...部分说明错误更正 2026/8/13前言在使用蓝牙的过程中UUID 作为通用唯一识别码是必须要清楚的按理来说它其实只是属于一个简单的概念但是由于蓝牙协议的层次分明对于初学者来说很容易看得迷糊理不清楚。所以本文就带大家详细认清蓝牙中的 UUID 。我是矜辰所致全网同名尽量用心写好每一系列文章不浮夸不将就认真对待学知识的我们矜辰所致金石为开目录前言一、 理论基础二、UUID 格式2.1 标准 UUIDSIG 定义2.2 自定义 UUID三、UUID 分类3.1 0x180x 开头UUIDService UUID3.2 0x2Axx 开头UUIDCharacteristic UUID3.2.1 键盘鼠标 UUID 说明3.3 0x29xx 开头UUIDDescriptor UUID3.4 0xFFxx开头 UUIDVendor Specific四、WCH 蓝牙示例中 UUID 对应体现4.1 0x28XX 开头UUID4.2 示例对应图结语一、 理论基础简单过一遍理论基础UUID通用唯一识别码Universally Unique Identifier 相当于蓝牙通信中的 “身份证”通过标准化和自定义两种形式确保蓝牙设备间能准确识别、通信和交互。蓝牙协议通过 UUID 实现设备间的标准化通信使用蓝牙对外提供服务的设备需要有对应的服务功能服务是蓝牙设备中功能划分的单元每个服务都对应着一种特定的功能或数据传输需求。例如当一个蓝牙设备如智能手环向外界广播服务时会携带对应的 UUID其他设备如手机通过识别这些 UUID就能知道该设备提供哪些功能如心率监测、数据传输等并建立针对性的连接。蓝牙 UUID 用于唯一标识蓝牙服务Service、特征Characteristic和描述符Descriptor等核心组件在蓝牙官方文档中有图对于蓝牙这个 服务特征值描述符知识理论基础大家可以自行网上翻阅资料在我以前的博文 ESP32-C3 学习测试 蓝牙 篇三、认识蓝牙 GATT 协议也有过这方面的说明。我们的手机连接上蓝牙设备也可以看到 UUID 二、UUID 格式蓝牙 UUID 的标准格式为 128 位通常表示为 32 个十六进制字符以 8-4-4-4-12 的格式分组共 36 个字符包括 4 个连字符格式8-4-4-4-12示例0000180D-0000-1000-8000-00805F9B34FB2.1 标准 UUIDSIG 定义由蓝牙技术联盟Bluetooth SIG定义用于常见服务。标准的UUID为0000xxxx-0000-1000-8000-00805F9B34FB为了节省带宽标准 UUID 通常使用 16 位或 32 位短格式实际通信时自动扩展为 128 位。每一个蓝牙技术联盟定义的属性有一个唯一的16位 UUID以代替上面的基本UUID的‘x’部分。若 16 bit UUID为xxxx那么 128 bit UUID 为 0000xxxx-0000-1000-8000-00805F9B34FB若 32 bit UUID为xxxxxxxx那么 128 bit UUID 为xxxxxxxx-0000-1000-8000-00805F9B34FB比如下图中第一个服务就是标准 UUID2.2 自定义 UUID用于私有服务或厂商特定功能需开发者自行生成通常使用 UUID 随机生成器生成 128 位 UUID确保全球唯一性。比如下图中的最后一个 Service 使用的就是自定义的 128 位 UUID 一般应用来说多见 16bit 或者128 bit UUID 本文后面的讨论也皆在讨论这两种情况。三、UUID 分类那我们上面知道服务有 UUID 特征有 UUID 描述符有 UUID而且有时候服务UUID 和 特征值 UUID 会一样这怎么区分开呢上面这个问题就是新手容易搞迷糊的地方首先他们确实是共用 16-bit 或者 128 bit 编号的而且确实存在Service和CharacteristicUUID 一样的情况但是Service和CharacteristicUUID 一样的情况只有在使用自定义的 128-bit UUID 的情况下才会发生16-bit 区间被 SIG 固定了用途。上面说到 16-bit 区间被 SIG 固定了用途我们平时蓝牙连接设备后几乎大部分设备都能见到 16-bit UUID 为 0x1800 、0x1801 什么的如下图其实这些都是蓝牙联盟规定好固定的0x180x 开头 → 只能当 Service UUID0x2Axx 开头 → 只能当 Characteristic UUID0x29xx 开头 → 只能当 Descriptor UUID只要记住这种规定以后看到 UUID 就不会犯迷糊了下面把常见的一些列出来当做记录也方便自己以后查阅。3.1 0x180x 开头UUIDService UUID0x180x 区间只能当 Service UUID 但是不是说 Service UUID 只能用 0x180x 这里要搞清楚因为我们可以自定义也可以使用一些预留区域的值。我们用表格记录一下通用类16-bit服务英文名称中文场景0x1800Generic Access必含设备名、外观、连接参数0x1801Generic Attribute必含Service Changed0x180ADevice Information厂商字符串/版本号0x180FBattery Service电池电量手环/键鼠必备基本上做 BLE 从机都得加上 0x1800 / 0x1801 / 0x180A / 0x180F 四件套。传感器与健康手环、手表、医疗16-bit服务英文名称中文场景0x180DHeart Rate心率0x1809Health Thermometer体温计0x1810Blood Pressure血压计0x1818Cycling Power骑行功率计0x1816Cycling Speed Cadence踏频/速度0x1814Running Speed Cadence跑步速度0x1843Pulse Oximeter血氧仪0x183EWeight Scale体重秤0x183FLocation Navigation自行车码表0x181BEnvironmental Sensing温湿度/气压/光照0x183BBinary Sensor门窗/烟雾开关量做传感器需要用到 0x180D / 0x1809 / 0x1810 / 0x1843 / 0x183E / 0x181B 等上面这些。HID 音频 OTA16-bit服务英文名称中文场景0x1812Human Interface Device键盘/鼠标/遥控0x1813Scan Parameters扫描窗口参数配合 HID0x1811Alert Notification Service来电/短信提醒0x184ECommon AudioLE Audio 统一服务0x181EBond Management删除配对键0x181FImmediate Alert防丢器“响铃”0x1825Object Transfer ServiceOTA/文件传输做 BLE 键鼠/遥控 0x1812 必用。手机/PC 常用后台服务16-bit服务英文名称中文场景0x1802Immediate Alert防丢响铃0x1803Link Loss断开报警0x1804Tx Power发射功率0x1805Current Time Service同步系统时间0x1806Reference Time Update网络校时0x1807Next DST Change夏令时0x1808Glucose血糖仪0x1815Automation IO通用 GPIO 控制0x1817Position Quality定位精度0x1819Location Speed位置速度0x183AMedia Control媒体播放控制0x183CMesh ProvisioningMesh 配网0x183DMesh ProxyMesh 代理3.2 0x2Axx 开头UUIDCharacteristic UUID0x2Axx (0x2A00 – 0x2AFF) 区间只能当 Characteristic UUID 同上面一样反过来并不是必须用这个区间来做 Characteristic UUID。下面列表东西放得比较多仅供参考博主没有一一验证在后面博主自己使用参考的时候也发现过问题当然博主自己有及时更正只是在这里说明一下不用盲目参考使用需要用到还是确认一下。通用与设备信息UUID名称典型用途0x2A00Device Name设备名称Generic Access 必含0x2A01Appearance外观图标键盘/鼠标/温度计…0x2A04Peripheral Preferred Connection ParametersPPCP广播里常用0x2A05Service ChangedGeneric Attribute 必含OTA 必备0x2A19Battery Level电池百分比0-1000x2A23System ID8 字节OUIVendor 自编0x2A24Model Number String型号0x2A25Serial Number String序列号0x2A26Firmware Revision StringFW 版本0x2A27Hardware Revision StringHW 版本0x2A28Software Revision StringSW 版本0x2A29Manufacturer Name String厂商名传感器与运动类手环/手表/温度计UUID名称EN中文说明 / 典型用途0x2A37Heart Rate Measurement心率测量值一次性通知uint8 flags 心率 能量等0x2A38Body Sensor Location身体传感器位置0-6胸、腕、指、手、耳、足、腰0x2A39Heart Rate Control Point心率控制点写 0x01 可重置能量消耗累计0x2A1CTemperature Measurement温度测量结果float °C 时间戳可选0x2A1DTemperature Type测温位置类型腋下、体表、直肠等枚举 0-90x2A1EIntermediate Temperature中间温度值连续测温时周期性通知0x2A6EPressure气压/压力值uint32分辨率 0.1 Pa0x2A6FHumidity相对湿度uint16分辨率 0.01 %0x2A6DRainfall降雨量uint16分辨率 0.1 mm0x2A5BCSC Measurement骑行/步速综合测量轮转速 曲柄转数 时间戳0x2A5CCSC FeatureCSC 支持特性位域轮速、曲柄、多传感等0x2A5DSensor Location传感器安装位置曲柄、轮毂、鞋、胸等 0-150x2A63Cycling Power Measurement骑行功率实时测量功率 W 可选踏频、扭矩等0x2A64Cycling Power Vector功率矢量各踏点扭矩、角度等数组用于高阶骑行分析0x2A65Cycling Power Feature功率计功能位域扭矩源、矢量、多链轮等0x2A6CElevation海拔高度uint24分辨率 0.1 m0x2A6ABattery Power State电池功率状态位域是否充电、电量充足、低电、临界等电池与电源UUID名称EN中文说明 / 典型用途0x2A19Battery Level电池剩余电量百分比uint80–100。最常用单电池场景一条 Characteristic 即可。0x2A1ABattery Power State电池“功率/状态”位域充电中/放电中/充满/低电/临界/故障等与 0x2A6A 同义二选一。0x2A1BBattery Group Info电池组信息组内电池数量 每个电池的 0/1 状态位图支持多电池设备一次性汇报。HIDUUID名称EN中文说明 / 典型用途0x2A22Boot Keyboard Input Report键盘引导输入报告Boot 模式下键盘按键数据。0x2A32Boot Keyboard Output Report主机→键盘 LED 状态NumLock/CapsLock/ScrollLock 等1 字节。0x2A33Boot Mouse Input Report3 字节鼠标输入按键XY 位移。0x2A4AHID InformationHID 版本与特性标志2 字节 bcdHID 1 字节 country code 1 字节 flags。0x2A4BReport MapHID 报告描述符主机先读它才能解析后续 Report。0x2A4CHID Control Point主机写0x00/0x01让设备 suspend/resume无响应纯控制。0x2A4DReportHID通用输入/输出/特征报告日常键鼠数据就靠它。0x2A4EProtocol Mode切换 Boot Protocol(0x00) 与 Report Protocol(0x01)。安全与配对UUID名称EN中文说明 / 典型用途0x2A3DSupported New Alert Category手机端支持的新增告警类型位图邮件、短信、来电等 0-7 类。0x2A3EAlert Category ID单条告警的类别编号1 字节枚举。0x2A3FAlert Category ID Bit Mask批量告警类别位掩码每位对应 0x2A3E 的一个类别。0x2A40Alert Level告警级别无(0)、温和(1)、高(2)用于立即提醒或震动。0x2A41Alert Notification Control Point写命令控制使能/禁能某类告警、立即清除未读计数等。0x2A42Unread Alert Status未读计数器类别 ID 未读条数uint8。0x2A43New Alert新增告警类别 ID 字符串内容UTF-8一次性通知。0x2A4FScan Refresh扫描刷新写 0x00 通知外设“可重新开始广播”用于减小广播窗口。0x2A31Scan Interval Window主机建议的扫描间隔与窗口各 2 字节单位 0.625 ms外设可采纳以节电。0x2A55Bond Management Control Point绑定管理控制点删除指定绑定、删除所有绑定、清除密钥等写命令返回结果。0x2A56Bond Management Feature绑定管理特性位域支持删除单个/全部/授权列表等能力标志。3.2.1 键盘鼠标 UUID 说明记录到这里还想说明一个问题我们发现有的 UUID 在 Service 里面之专门给某个东西的在 Characteristic 里面也有专门给这个东西的比如键盘鼠标比如传感器为什么 SIG 要在服务和特征里面“重复”用 UUID 标定这里专门分一小节说明一下。Service 的 0x1812 是 “功能集合” 名称 。告诉客户端“本设备提供 HID 功能下面可以放键盘、鼠标、消费级遥控器甚至电池报告。Characteristic 0x2A22 / 0x2A32 / 0x2A33是 “数据槽” 名称 。告诉客户端 “ 这个槽放的是 Boot 键盘输入报告长度 8 字节格式固定 ”。名字里带“Keyboard/Mouse”只是告诉你“这条管道按 Boot 协议走固定格式”.UUID 数字本身不带格式格式由 Report Map DescriptorUUID 0x2A4E里那张 80~200 字节的“小字节码”定义。.真正决定“是键盘还是鼠标”的是 Report Map 描述符不是 UUID 名字那里才写“Usage Page Generic DesktopUsage KeyboardReport Size 8Report Count 6”。这个在后期学习键盘鼠标报表的时候会遇到。如果是键盘手机端展开 0x1812 Human Interface Device 服务后HandleUUID角色手机 UI 常见文字0x00330x2A4EReport Map“Report Map”0x00360x2A4DReport“Input Report”0x00390x2A4DReport“Output Report”0x003C0x2A22Boot Keyboard Input Report“Boot KB In”0x003F0x2A32Boot Keyboard Output Report“Boot KB Out”0x00420x2A4AHID Information“HID Information”0x00450x2A4CProtocol Mode“Protocol Mode”0x00480x2A4BHID Control Point“Control Point”→ Service 的 0x1812 只出现在最顶层→ 下面的 0x2A4D / 0x2A22 分配在这个 0x1812 的 Service 下面的不同 Characteristic 上手机端查看层次如下图所示还是要再次说明真正告诉手机“这是键盘”的是 Report Map 里的描述符不是 UUID。因为这里我们主要讨论 UUID 就不展开讨论。3.3 0x29xx 开头UUIDDescriptor UUID0x29xx 开头只能当 Descriptor UUID 而且描述符 UUID 并不多。截至 Bluetooth v5.40x2900 ~ 0x290D 是当前已发布的标准描述符 UUID 。下面的比上面的记录多了变量名是根据WCH CH585 示例工程中的定义来列举的变量名代码UUID标准名称EN简单用途含必选提示charExtPropsUUID0x2900Characteristic Extended Properties扩展属性位可选charUserDescUUID0x2901Characteristic User Description用户文字说明可选clientCharCfgUUID0x2902Client Characteristic Configuration开/关通知或指示通知/指示特征必备servCharCfgUUID0x2903Server Characteristic Configuration服务器端广播指示极少用charFormatUUID0x2904Characteristic Presentation Format数值格式与单位可选charAggFormatUUID0x2905Characteristic Aggregate Format组合多个格式可选validRangeUUID0x2906Valid Range合法最小最大值可选extReportRefUUID0x2907External Report Reference指向外部服务HID 可选reportRefUUID0x2908Report ReferenceReport ID 与类型HID 可选至于新增加的 0x2908 后面的描述符大家可自行网上查找。我们这里看一个示例架构帮助大家理解一下上面的分类3.4 0xFFxx开头 UUIDVendor Specific0xFF00 ~ 0xFFFF 区间为SIG 的公共预留池Vendor-Specific 区间任何厂商都可以临时借用。这个区间 SIG 作为公共预留区间一般用作示例测试参考属于临时方案想要作为产品要么去 SIG 申请正式分配要么直接用 128-bit 自建 UUID。额外说明。使用 16bit UUID 那么久必须保证同一份规范表里 Service、Characteristic 不能重复。这是官方文档规定好的。CH585 例程把 0xFFE0 当 Service再把 0xFFE1-0xFFE5 当 Characteristic作为示例演示使用如下图当然除了 0xFF00 ~ 0xFFFF 区间如果想用其他数值比如0xCCC0、0xAAA1 这种他们并不在 SIG 已经划出用途的 “ 固定区间 ”里能不能用会怎么样首先单协议角度看拿 0xCCC0 / 0xAAA1 当 Service 或 Characteristic 用没什么问题芯片例程、调试 Demo 里这么干只要自己知道自己的设定也能够调试解析。但是仅限于例程产品不建议它们仍是 SIG 的公共编号池资源只是目前还没轮到给 0xCCC0 分配名字而已指不定哪天 SIG 把 0xCCC0 分配成“某官方服务”你就得跟着改否则后续过认证、做 BQB 测试就会出问题。做产品最规范的途径只有两条去 SIG 花钱申请正式分配16/32-bit直接用 128-bit 自建 UUID。所以 0xCCC0、0xAAA1 这种临时使用可以本质上和 0xFF00 ~ 0xFFFF 的公共预留区差不多属于 SIG 公共编号区目前没人使用但是随时可能有用。还要记住整个 16-bit 空间都由 Bluetooth SIG 的官方文档 《16-bit UUID Numbers Document》统一管理所有的 16-bit 空间 所有的 16-bit 空间 经过上面的说明相信大家以后在看到蓝牙设备的 UUID 能够清楚的识别是什么类型。四、WCH 蓝牙示例中 UUID 对应体现最后一小节我们来简单看看一下在 WCH 蓝牙芯片例程中与 UUID 相关的地方。我们打开从机工程详细的从机例程会有对应的从机示例解析博文博主还没写 等写了以后放上链接大家可以自己查看网上其他资料~我们要看的地方是static gattAttribute_t simpleProfileAttrTbl[]这个数组因为他直接和我们手机连接上设备看到的框架图对应起来。4.1 0x28XX 开头UUID在第一栏我们就能看到一个名为primaryServiceUUID的东西但是跳转过去我们是找不到这个定义的因为他是一个指针指向一个 UUID 的地址但是这个地址是一个 Flash 的固定地址就等于说CH585 示例种这个 UUID 数据是烧录完后就会保存在固定地址的一个数据。既然官方都定义为 UUID 而且固定起来了说明他肯定是标准的 UUID 于是上网查了一下0x28xx 一共只有 4 个SIG 已全部分配完毕它们是 GATT 的“骨架”UUID永远不参与用户数据只用来告诉客户端我这条属性是干什么的这里是服务头 / 特征头 / 引用头。16-bit名字在属性表里的作用0x2800Primary Service“一个主服务开始了”0x2801Secondary Service“一个次级服务开始了”极少用0x2802Include“这里包含另一个服务”跨服务引用0x2803Characteristic“后面跟的是一条特征”在示例代码中的体现在有些地方会有如下定义/** * GATT Declarations */#defineGATT_PRIMARY_SERVICE_UUID0x2800// Primary Service#defineGATT_SECONDARY_SERVICE_UUID0x2801// Secondary Service#defineGATT_INCLUDE_UUID0x2802// Include#defineGATT_CHARACTER_UUID0x2803// Characteristic不参与用户数据作为框架存在所以我们在手机端是看不到这几个 UUID 的但是我们在例程中定义的时候确实是需要用到而且位置是固定的用的时候照抄常量我们只需要记住0x2800 只放在 服务第一行0x2803 只放在 每条特征第一行如下// 1. 主服务声明 → UUID 用 0x2800{{ATT_BT_UUID_SIZE,primaryServiceUUID},// type 0x2800GATT_PERMIT_READ,0,(uint8_t*)devInfoService// 值 0x180A},// 2. 每条特征必须先放 0x2803 声明{{ATT_BT_UUID_SIZE,characterUUID},// type 0x2803GATT_PERMIT_READ,0,devInfoMfrNameProps// 属性句柄真正UUID},4.2 示例对应图我们这里上一下从机示例中的个人做的分析框图这些会在我的从机服务分析文章中内容有详细说明由于涉及到了 UUID这里也放一遍加深印象。首先是整体的框架图还有服务 UUID 和 特征 UUID 在程序中定义方式是不同的如下图:这里还有一个简单的框架示例程序帮助大家加深印象// 1. 0x28xx 骨架 UUIDconstuint8_tprimaryServiceUUID[2]{0x00,0x28};constuint8_tcharacterUUID[2]{0x03,0x28};// 2. 0x180x 服务 UUIDconstuint8_tenvServUUID[2]{0x1A,0x18};// 0x181A// 3. 0x2Axx 特征 UUIDconstuint8_ttempUUID[2]{0x6E,0x2A};constuint8_thumiUUID[2]{0x6F,0x2A};constuint8_tbattUUID[2]{0x19,0x2A};// 4. 0x29xx 描述符 UUIDconstuint8_tdescCCC[2]{0x02,0x29};constuint8_tdescUser[2]{0x01,0x29};constuint8_tdescFormat[2]{0x03,0x29};// 5. 属性表 —— 与上面 0~9 行一一对应staticgattAttribute_tenvAttrTbl[]{/*0*/{{ATT_BT_UUID_SIZE,primaryServiceUUID},GATT_PERMIT_READ,0,(uint8_t*)envService},/*1*/{{ATT_BT_UUID_SIZE,characterUUID},GATT_PERMIT_READ,0,tempProps},/*2*/{{ATT_BT_UUID_SIZE,tempUUID},GATT_PERMIT_READ,0,(uint8_t*)tempVal},/*3*/{{ATT_BT_UUID_SIZE,descCCC},GATT_PERMIT_READ|GATT_PERMIT_WRITE,0,(uint8_t*)tempCCC},/*4*/{{ATT_BT_UUID_SIZE,characterUUID},GATT_PERMIT_READ,0,humiProps},/*5*/{{ATT_BT_UUID_SIZE,humiUUID},GATT_PERMIT_READ,0,(uint8_t*)humiVal},/*6*/{{ATT_BT_UUID_SIZE,characterUUID},GATT_PERMIT_READ,0,battProps},/*7*/{{ATT_BT_UUID_SIZE,battUUID},GATT_PERMIT_READ,0,(uint8_t*)battVal},/*8*/{{ATT_BT_UUID_SIZE,descUser},GATT_PERMIT_READ,0,(uint8_t*)battUserDesc},/*9*/{{ATT_BT_UUID_SIZE,descFormat},GATT_PERMIT_READ,0,(uint8_t*)battFormat}};结语本文详细的说明了一下 BLE 蓝牙的 UUID应该算是特别全面了。最后再总结一下0x280x 只当“标签”对用户不可见0x180x / 0x2Axx 是用户数据分别对应服务0x180x和特征0x2Axx0x29xx 只是附加说明其他没有定义的区间测试可以临时用所有的16-bit UUID 都由 SIG 的官方文档 《16-bit UUID Numbers Document》统一管理自定义的 128-bit UUID服务 UUID 可以和 特征 UUID 一样16-bit 的服务和特征值的 UUID 不能一样同一设备不同特征 UUID 任何时候都不能一样好了本文就到这里吧谢谢大家 ❤️ △ ❤️
返回列表