news 2026/4/16 11:00:16

通信协议仿真:蓝牙协议仿真_(4).蓝牙低功耗协议

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
通信协议仿真:蓝牙协议仿真_(4).蓝牙低功耗协议

蓝牙低功耗协议

引言

蓝牙低功耗(Bluetooth Low Energy,简称BLE)是一种旨在降低功耗的无线通信技术,广泛应用于健康、运动、智能家居等领域。与经典蓝牙相比,BLE在功耗、连接速度和数据传输方面有显著的改进。本节将详细探讨BLE协议的原理和内容,包括其基本架构、数据包格式、连接流程、服务和特征等,并通过具体的代码示例来说明如何在仿真环境中实现BLE通信。

基本架构

1. 物理层(Physical Layer)

物理层负责定义无线信号的传输频率、调制方式、发射功率等。BLE工作在2.4 GHz ISM频段,使用GFSK(高斯频移键控)调制,数据传输速率为1 Mbps。BLE使用37个数据信道和3个广告信道(37、38、39 MHz),其中广告信道用于设备发现和连接建立。

2. 链路层(Link Layer)

链路层负责设备之间的连接管理和数据包的传输。BLE链路层的主要功能包括:

  • 设备发现:通过广告信道广播设备信息。
  • 连接建立:设备通过广告信道建立连接。
  • 数据传输:连接建立后,设备通过数据信道传输数据。
  • 连接维护:包括连接参数更新、断开连接等。
广告包

广告包是BLE设备在广告信道上发送的数据包,用于广播设备的标识和信息。广告包的格式如下:

  • Preamble:1字节,固定为0x55。
  • Access Address:4字节,固定为0x8E89BED6。
  • AD Data:包含设备信息的广告数据,最大长度为31字节。
  • CRC:3字节,用于校验数据的完整性。
连接请求包

连接请求包用于发起连接请求。其格式如下:

  • Preamble:1字节,固定为0x55。
  • Access Address:4字节,固定为0x8E89BED6。
  • Connection Request Data:包含连接参数,如连接间隔、从设备地址等。
  • CRC:3字节,用于校验数据的完整性。

3. 逻辑链路控制和适配协议(L2CAP)

L2CAP层负责数据包的分段和重组,以及多路复用。BLE使用的L2CAP层更加简单,主要用于传输ATT(属性协议)数据。

4. 属性协议(ATT)

属性协议(Attribute Protocol)用于定义和访问设备上的属性。每个属性都有一个唯一的16位或128位UUID(通用唯一识别码),并且可以通过读、写、通知等操作进行访问。

服务和特征
  • 服务(Service):一组相关的特征,用于描述特定的功能或应用。例如,一个心率服务可能包含心率测量、体感温度等特征。
  • 特征(Characteristic):服务中的具体数据项,可以读取、写入或通知。例如,心率测量特征包含当前的心率值。

5. 通用访问配置文件(GAP)

通用访问配置文件(Generic Access Profile)定义了设备如何被发现、连接和配置。GAP包括设备的名称、外观、连接模式等。

6. 通用属性配置文件(GATT)

通用属性配置文件(Generic Attribute Profile)定义了如何通过ATT协议访问服务和特征。GATT包括服务发现、特征发现、读取和写入等操作。

数据包格式

1. 广告包格式

| 字段 | 长度(字节) | 描述 | |--------------|--------------|-------------------------------| | Preamble | 1 | 固定为0x55 | | Access Address| 4 | 固定为0x8E89BED6 | | AD Data | 0-31 | 广告数据,包含设备信息 | | CRC | 3 | 循环冗余校验码 |

2. 连接请求包格式

| 字段 | 长度(字节) | 描述 | |----------------------------|--------------|-------------------------------| | Preamble | 1 | 固定为0x55 | | Access Address | 4 | 固定为0x8E89BED6 | | Connection Request Data | 25 | 包含连接参数和设备地址 | | CRC | 3 | 循环冗余校验码 |

连接流程

1. 广告

设备通过广告信道广播自己的信息。广告包包括设备的名称、UUID、功率等级等。

2. 扫描

扫描设备监听广告信道,收集广告包中的信息。扫描设备可以发送扫描请求,广告设备可以回应扫描响应。

3. 连接建立

扫描设备向广告设备发送连接请求,广告设备接受请求后,两者建立连接。连接建立后,设备通过数据信道进行数据传输。

4. 数据传输

连接建立后,设备通过数据信道传输数据。数据传输可以是单向或双向的,具体取决于服务和特征的定义。

5. 连接维护

连接建立后,设备需要定期发送维持连接的信号,如心跳包。连接参数可以动态调整,以适应不同的应用场景。

服务和特征

1. 服务定义

服务是一组相关的特征,用于描述特定的功能或应用。服务可以通过UUID来唯一标识。例如,心率服务的UUID为0x180D。

2. 特征定义

特征是服务中的具体数据项,可以读取、写入或通知。特征也有自己的UUID。例如,心率测量特征的UUID为0x2A37。

3. 服务和特征的访问

通过GATT协议,设备可以访问其他设备的服务和特征。访问操作包括:

  • 服务发现:获取设备上所有服务的UUID。
  • 特征发现:获取特定服务下所有特征的UUID。
  • 读取特征值:读取特定特征的当前值。
  • 写入特征值:写入特定特征的值。
  • 通知和指示:设备可以启用特征的通知或指示,当特征值发生变化时,主动通知或指示另一设备。

代码示例

1. 广告包生成

以下是一个Python示例,用于生成并发送BLE广告包。

importstructimportbinasciidefgenerate_advertising_packet(device_name,uuid):""" 生成BLE广告包 :param device_name: 设备名称 :param uuid: 设备UUID :return: 广告包数据 """# 固定前缀preamble=b'\x55'access_address=b'\x8E\x89\xBE\xD6'# 广告数据adv_data=b'\x02\x01\x06'# Flagsadv_data+=struct.pack('B',len(device_name)+1)+b'\x09'+device_name.encode('utf-8')# 设备名称adv_data+=struct.pack('B',len(uuid)+1)+b'\x07'+binascii.unhexlify(uuid)# UUID# 计算CRCcrc=b'\x00\x00\x00'# 假设CRC为0x000000,实际应用中需要计算CRC# 组合成完整的广告包advertising_packet=preamble+access_address+adv_data+crcreturnadvertising_packet# 示例:生成一个包含设备名称"BLE Device"和UUID"180D"的广告包advertising_packet=generate_advertising_packet("BLE Device","180D")print(binascii.hexlify(advertising_packet))

2. 连接请求包生成

以下是一个Python示例,用于生成并发送BLE连接请求包。

defgenerate_connection_request_packet(initiator_address,advertising_address,connection_interval,slave_latency,supervision_timeout):""" 生成BLE连接请求包 :param initiator_address: 发起设备地址 :param advertising_address: 广告设备地址 :param connection_interval: 连接间隔 :param slave_latency: 从设备延迟 :param supervision_timeout: 监督超时时间 :return: 连接请求包数据 """# 固定前缀preamble=b'\x55'access_address=b'\x8E\x89\xBE\xD6'# 连接请求数据conn_req_data=b'\x00\x00\x00\x00\x00\x00'# 初始化PDU类型和信道conn_req_data+=struct.pack('6s',binascii.unhexlify(initiator_address))# 发起设备地址conn_req_data+=struct.pack('6s',binascii.unhexlify(advertising_address))# 广告设备地址conn_req_data+=struct.pack('<H',connection_interval)# 连接间隔conn_req_data+=struct.pack('<H',slave_latency)# 从设备延迟conn_req_data+=struct.pack('<H',supervision_timeout)# 监督超时时间# 计算CRCcrc=b'\x00\x00\x00'# 假设CRC为0x000000,实际应用中需要计算CRC# 组合成完整的连接请求包connection_request_packet=preamble+access_address+conn_req_data+crcreturnconnection_request_packet# 示例:生成一个连接请求包initiator_address="A1:B2:C3:D4:E5:F6"advertising_address="01:02:03:04:05:06"connection_interval=7.5# 7.5 msslave_latency=0# 无延迟supervision_timeout=100# 100 ms# 将连接间隔和监督超时时间转换为BLE协议的单位conn_interval=int(connection_interval*1000/1.25)sup_timeout=int(supervision_timeout*10)connection_request_packet=generate_connection_request_packet(initiator_address,advertising_address,conn_interval,slave_latency,sup_timeout)print(binascii.hexlify(connection_request_packet))

3. 服务和特征的访问

以下是一个Python示例,使用pybluez库来访问BLE设备的服务和特征。

importbluetoothdefdiscover_services(device_address):""" 发现设备上的所有服务 :param device_address: 设备地址 :return: 服务列表 """services=bluetooth.find_service(address=device_address)returnservicesdefdiscover_characteristics(device_address,service_uuid):""" 发现特定服务下的所有特征 :param device_address: 设备地址 :param service_uuid: 服务UUID :return: 特征列表 """characteristics=[]services=discover_services(device_address)forserviceinservices:ifservice['uuid']==service_uuid:forcharacteristicinservice['characteristics']:characteristics.append(characteristic)returncharacteristicsdefread_characteristic_value(device_address,characteristic_uuid):""" 读取特征值 :param device_address: 设备地址 :param characteristic_uuid: 特征UUID :return: 特征值 """sock=bluetooth.BluetoothSocket(bluetooth.L2CAP)sock.connect((device_address,0x10))# 发送读取特征值的请求request=b'\x01'+binascii.unhexlify(characteristic_uuid)sock.send(request)# 接收响应response=sock.recv(1024)sock.close()returnresponse# 示例:发现服务和特征,读取特征值device_address="A1:B2:C3:D4:E5:F6"service_uuid="180D"characteristic_uuid="2A37"services=discover_services(device_address)print("发现的服务:",services)characteristics=discover_characteristics(device_address,service_uuid)print("发现的特征:",characteristics)value=read_characteristic_value(device_address,characteristic_uuid)print("读取的特征值:",binascii.hexlify(value))

仿真环境搭建

1. 使用pybluez

pybluez是一个Python库,用于在Linux系统上进行蓝牙通信。以下是如何安装和使用pybluez库的步骤。

安装
pipinstallpybluez
示例代码

以下是一个简单的示例,展示如何使用pybluez库进行设备扫描、连接、发送和接收数据。

importbluetoothdeffind_devices():""" 扫描附近的蓝牙设备 :return: 设备列表 """nearby_devices=bluetooth.discover_devices(duration=8,lookup_names=True,flush_cache=True,lookup_class=False)returnnearby_devicesdefconnect_to_device(device_address,port):""" 连接到蓝牙设备 :param device_address: 设备地址 :param port: 端口 :return: 连接套接字 """sock=bluetooth.BluetoothSocket(bluetooth.RFCOMM)sock.connect((device_address,port))returnsockdefsend_data(sock,data):""" 发送数据到蓝牙设备 :param sock: 连接套接字 :param data: 要发送的数据 """sock.send(data)defreceive_data(sock):""" 从蓝牙设备接收数据 :param sock: 连接套接字 :return: 接收到的数据 """returnsock.recv(1024)# 示例:扫描设备、连接设备、发送和接收数据devices=find_devices()print("附近的设备:",devices)device_address="A1:B2:C3:D4:E5:F6"port=1sock=connect_to_device(device_address,port)send_data(sock,b'Hello, BLE Device!')data=receive_data(sock)print("接收到的数据:",data)sock.close()

2. 使用nRF5 SDK进行硬件仿真

nRF5 SDK是Nordic Semiconductor提供的开发工具,用于开发基于nRF5系列芯片的蓝牙低功耗应用。以下是如何使用nRF5 SDK进行硬件仿真的步骤。

环境搭建
  1. 安装工具链:安装GNU Arm Embedded ToolchainSEGGER J-Link等工具。
  2. 下载SDK:从Nordic的官方网站下载nRF5 SDK
  3. 配置项目:在nRF5 SDK中创建一个新的项目,并配置项目参数。
示例代码

以下是一个简单的示例,展示如何使用nRF5 SDK创建一个广告和连接的BLE设备。

#include"ble.h"#include"ble_advdata.h"#include"ble_hci.h"#include"nrf_sdh.h"#include"nrf_sdh_ble.h"#include"nrf.h"#include"nrf_log.h"#include"nrf_log_ctrl.h"#include"nrf_log_default_backends.h"staticuint16_tservice_uuid=0x180D;staticuint16_tcharacteristic_uuid=0x2A37;staticble_gap_adv_params_tm_adv_params;staticble_gap_conn_params_tm_conn_params;staticvoidble_gap_params_init(void){// 广告参数初始化memset(&m_adv_params,0,sizeof(m_adv_params));m_adv_params.type=BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;m_adv_params.p_props=NULL;m_adv_params.p_whitelist=NULL;m_adv_params.primary_phy=BLE_GAP_PHY_1MBPS;m_adv_params.secondary_phy=BLE_GAP_PHY_1MBPS;m_adv_params.duration=0;// 永久广告m_adv_params.max_adv_evts=0;m_adv_params.channel_mask=0x07;m_adv_params.interval=MSEC_TO_UNITS(100,UNIT_0_625_MS);// 100 msm_adv_params.timeout=0;// 连接参数初始化memset(&m_conn_params,0,sizeof(m_conn_params));m_conn_params.min_conn_interval=MSEC_TO_UNITS(7.5,UNIT_1_25_MS);// 7.5 msm_conn_params.max_conn_interval=MSEC_TO_UNITS(7.5,UNIT_1_25_MS);// 7.5 msm_conn_params.slave_latency=0;m_conn_params.conn_sup_timeout=MSEC_TO_UNITS(100,UNIT_10_MS);// 100 ms}staticvoidble_advdata_init(void){// 广告数据初始化ble_advdata_tadvdata;uint8_tadvdata_array[31];uint8_tadvdata_len;memset(&advdata,0,sizeof(advdata));advdata.name_type=BLE_advdata_name_type_short_name;advdata.include_addr=true;advdata.flags=BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;advdata.p_service_uuids=&service_uuid;advdata.service_uuid_count=1;advdata.p_manufacturer_specific_data=NULL;advdata_len=ble_advdata_encode(&advdata,advdata_array);// 发送广告数据nrf_ble_gap_adv_data_set(BLE_GAP_ADV_DATA_TYPE_ADVERTISING,advdata_array,advdata_len);}staticvoidble_conn_params_init(void){// 连接参数初始化nrf_ble_gap_conn_params_set(&m_conn_params);}staticvoidble_stack_init(void){// 初始化蓝牙堆栈nrf_sdh_enable_request();nrf_sdh_ble_default_cfg_set(BLE_CONN_CFG_DEFAULT,NULL);nrf_sdh_ble_enable(&m_conn_params);// 注册事件处理函数nrf_sdh_ble_observers_register(&m_ble_observer);}staticvoidble_adv_start(){// 开始广告nrf_ble_gap_adv_start(&m_adv_params);}intmain(void){// 初始化日志nrf_log_init();nrf_log_default_backends_init();// 初始化蓝牙堆栈ble_stack_init();// 初始化广告参数ble_gap_params_init();// 初始化广告数据ble_advdata_init();// 初始化连接参数ble_conn_params_init();// 开始广告ble_adv_start();// 主循环while(1){nrf_sdhprocesso();}return0;}

3. 使用nRF Connect for Desktop进行测试

nRF Connect for Desktop是一个图形化的工具,用于测试和调试BLE设备。以下是使用该工具进行测试的步骤:

  1. 安装工具:从Nordic Semiconductor的官方网站下载并安装nRF Connect for Desktop
  2. 打开工具:启动nRF Connect for Desktop,选择nRF Connect for Bluetooth Low Energy应用。
  3. 扫描设备:点击“扫描”按钮,搜索附近的BLE设备。
  4. 连接设备:选择要连接的设备,点击“连接”按钮。
  5. 服务和特征:连接成功后,工具会自动发现设备上的服务和特征。可以在服务列表中选择特定的服务和特征进行读取、写入或启用通知。

4. 使用nRF Connect for Mobile进行测试

nRF Connect for Mobile是Nordic Semiconductor提供的移动应用,用于测试和调试BLE设备。以下是使用该应用进行测试的步骤:

  1. 安装应用:从Google Play或Apple App Store下载并安装nRF Connect for Mobile
  2. 打开应用:启动应用,选择“扫描”功能。
  3. 扫描设备:搜索附近的BLE设备。
  4. 连接设备:选择要连接的设备,点击“连接”按钮。
  5. 服务和特征:连接成功后,应用会自动发现设备上的服务和特征。可以在服务列表中选择特定的服务和特征进行读取、写入或启用通知。

结论

蓝牙低功耗(BLE)协议在功耗、连接速度和数据传输方面具有显著的优势,使其成为许多低功耗应用场景的首选技术。通过本文的介绍,读者可以了解BLE的基本架构、数据包格式、连接流程、服务和特征的定义,以及如何在仿真环境中实现BLE通信。希望这些内容能够帮助读者更好地理解和应用BLE技术。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/21 16:26:23

jEasyUI 设置冻结列详解

jEasyUI 设置冻结列详解 引言 jEasyUI 是一款流行的前端框架,它简化了网页的UI开发。在jEasyUI中,表格是常用的组件之一。冻结列功能允许用户在滚动表格时保持某些列固定显示,这对于展示大量数据时保持关键信息的可见性非常有用。本文将详细讲解如何在jEasyUI中设置冻结列…

作者头像 李华
网站建设 2026/4/12 19:23:55

XQuery 语法概述

XQuery 语法概述 XQuery 是一种用于查询结构化数据的查询语言,它主要应用于 XML 和 XPath 数据源。本篇文章将对 XQuery 的基本语法进行详细介绍,包括数据模型、数据类型、表达式、查询结构以及常用的操作符。 数据模型 XQuery 的数据模型主要包括以下几种类型: XML 文档…

作者头像 李华
网站建设 2026/4/9 7:49:12

XHTML 简介

XHTML 简介 引言 随着互联网技术的飞速发展,网页设计已经成为一个重要的领域。HTML(超文本标记语言)作为网页设计的基础,一直被广泛使用。然而,随着技术的发展,HTML面临着一些新的挑战。为了解决这些问题,XHTML(可扩展超文本标记语言)应运而生。本文将详细介绍XHTML…

作者头像 李华
网站建设 2026/4/16 10:57:57

我想知道相机的不同系列,比如因特尔realsense、奥比中光的不同系列相机,他们的SDK一样吗?或者说一般一样嘛?

我想知道相机的不同系列&#xff0c;比如因特尔realsense、奥比中光的不同系列相机&#xff0c;他们的SDK一样吗&#xff1f;或者说一般一样嘛&#xff1f;了解了&#xff01;你是指同一品牌下不同系列相机的SDK是否相同或类似&#xff1f;对于 Intel RealSense 和 奥比中光&am…

作者头像 李华
网站建设 2026/4/2 5:15:56

[数字信号处理-入门] 采样定理

[数字信号处理-入门] 采样定理 个人导航 知乎&#xff1a;https://www.zhihu.com/people/byzh_rc CSDN&#xff1a;https://blog.csdn.net/qq_54636039 注&#xff1a;本文仅对所述内容做了框架性引导&#xff0c;具体细节可查询其余相关资料or源码 参考文章&#xff1a;各…

作者头像 李华
网站建设 2026/4/15 19:57:21

SQL BETWEEN 运算符详解

SQL BETWEEN 运算符详解 概述 SQL BETWEEN 运算符用于检查一个值是否介于两个值之间。这个运算符在处理日期和数字时非常有用,尤其是在数据库查询中用于筛选数据。 BETWEEN 运算符语法 SELECT column_name FROM table_name WHERE column_name BETWEEN value1 AND value2;在…

作者头像 李华