1、实验简介

参考网址:https://gitee.com/Lockzhiner-Electronics/lz3863/tree/master/apps/d2_ble_connect_client

1.1、实验目的

本实验旨在帮助学习者掌握 OpenHarmony 轻量系统中 BLE(Bluetooth Low Energy,低功耗蓝牙)GATT 客户端 的基本使用方法。通过本实验,你将学会:

  1. 理解 BLE GAP(Generic Access Profile) 扫描与连接机制,以及 GATT Client(通用属性客户端) 服务发现流程;
  2. 在开发板上实现 BLE UART 客户端,完成扫描、连接、服务/特征发现与数据收发;
  3. 使用 CMSIS-RTOS v2 创建独立的收发任务,实现与服务端的双向数据通信;
  4. 掌握 BLE 扫描回调、连接状态回调、Notify 接收与 Write 写命令发送的处理流程;
  5. 完成案例代码的编译、烧录,并与 d1_ble_connect_server 服务端案例进行双板联调。

1.2、实验内容

本案例在 LZ3863-星闪开发板上实现 BLE GATT 客户端 功能:初始化蓝牙协议栈并注册 GATT 客户端,扫描并连接指定 MAC 地址的服务端;连接建立后完成 GATT 服务发现,通过 Write 周期性向服务端发送数据,同时接收服务端 Notify 通知并打印到串口。

项目 说明
应用层源文件 ble_client_app.c(任务与收发逻辑)
协议栈封装 ble_client_lib.c / ble_client_lib.h(扫描、连接、GATT 发现、回调)
设备名称 ble_uart(GAP 本地名)
客户端 MAC 地址 12:22:33:44:55:66
目标服务端 MAC 地址 11:22:33:44:55:66(与 d1 服务端一致)
服务 UUID 0xABCD(由服务端提供,客户端发现所有服务)
写特征 UUID 0xEFEF(对应服务端 RX 特征,客户端 → 服务端)
接收特征 服务端 TX 特征 0xCDEF 的 Notify 通知(服务端 → 客户端)
发送数据 "hello ble:from client"
发送周期 约 1 秒(osDelay(100),tick = 10 ms)
接收缓冲区 g_ble_rx_data[256]
初始化入口 APP_FEATURE_INIT(ble_server_app)

典型联调拓扑:

┌─────────────────────┐    BLE 连接     ┌─────────────────────┐
│  开发板 A(d1 服务端)│ ◄────────────► │  开发板 B(本案例)   │
│  d1_ble_connect_    │  GATT Notify   │  d2_ble_connect_    │
│  server(Server)    │  GATT Write    │  client(Client)    │
│  广播: ble_uart_    │                │  扫描并连接服务端     │
│  server             │                │  发送: hello ble:     │
│  发送: hello ble:   │                │  from client        │
│  from server        │                │                     │
└─────────────────────┘                 └─────────────────────┘

说明:本案例为 BLE 客户端,需配合 d1_ble_connect_server 服务端案例完成联调。建议先烧录并启动服务端开发板,确认广播就绪后再启动客户端开发板。

1.3、实验环境

项目 说明
硬件 两块 LZ3863-星闪开发板(服务端 + 客户端)、USB 数据线
软件 OpenHarmony v5.1.0 源码、hb 编译工具
联调案例 d1_ble_connect_server(服务端,烧录至第一块开发板)
调试工具 串口助手(波特率 115200,8N1)
案例路径 applications/sample/wifi-iot/app/d2_ble_connect_client/

注意:完整双向通信实验需要 两块开发板,分别烧录服务端固件(d1_ble_connect_server)和客户端固件(本案例)。


2、基础知识

2.1、BLE 协议栈概述

BLE(Bluetooth Low Energy) 是一种面向低功耗、短距离通信的无线技术,广泛应用于可穿戴设备、传感器和物联网场景。BLE 协议栈从下到上可分为:

层次 英文名称 主要功能
物理层 PHY 2.4 GHz 射频收发
链路层 LL 连接建立、数据包封装
主机控制器接口 HCI 控制器与主机间通信
逻辑链路控制与适配 L2CAP 多路复用、分段重组
属性协议 ATT 属性读写、句柄管理
通用属性配置文件 GATT 基于 ATT 的服务/特征抽象
通用访问配置文件 GAP 广播、扫描、连接、配对
安全管理协议 SMP 加密与配对安全

本案例主要涉及 GAP(扫描与连接)和 GATT Client(服务发现与特征读写)两层。

2.2、GAP:扫描与连接

GAP 定义了 BLE 设备的发现与连接方式。本案例客户端采用 主动扫描(Active Scan) 发现服务端,匹配目标 MAC 地址后发起连接:

客户端启动
    ↓
注册 GATT 客户端回调
    ↓
enable_ble()  →  ble_client_enable_cbk
    ↓
设置扫描参数  →  ble_client_set_scan_param_cbk
    ↓
gap_ble_start_scan()  →  开始扫描
    ↓
扫描到目标 MAC  →  停止扫描 → gap_ble_connect_remote_device()
    ↓
连接建立  →  GAP_BLE_STATE_CONNECTED
    ↓
连接断开  →  重新扫描

本案例扫描参数:

参数 说明
扫描间隔 0x48 单位 0.625 ms
扫描窗口 0x48 与间隔相等,持续扫描
扫描类型 0x00 被动扫描
扫描 PHY 0x01 LE 1M PHY
过滤策略 0x00 接受所有广播包
目标地址 11:22:33:44:55:66 与服务端 MAC 一致

2.3、GATT Client:服务发现

GATT 采用 Client/Server 模型。客户端连接服务端后,需要通过 服务发现(Service Discovery) 获取服务端提供的服务与特征句柄,才能进行数据读写。

本案例连接的服务端提供 BLE UART 透传服务,结构如下:

Service: 0xABCD (BLE UART Service)
    ├── Characteristic TX: 0xCDEF
    │       属性: Read | Write | Write No Response | Notify
    │       描述符: Client Characteristic Configuration (0x2902)
    │       用途: 服务端通过 Notify 向客户端发送数据(客户端接收)
    │
    └── Characteristic RX: 0xEFEF
            属性: Write | Write No Response
            用途: 客户端向服务端写入数据(客户端发送)
角色 数据方向 本案例实现方式
服务端 → 客户端 TX 特征 Notify ble_client_notification_cbk() → 写入 g_ble_rx_data
客户端 → 服务端 RX 特征 Write ble_client_write_cmd()gattc_write_cmd()

GATT 发现流程:

连接建立 → MTU 交换
    ↓
gattc_discovery_service()     发现所有服务
    ↓
gattc_discovery_character()   发现服务内所有特征
    ↓
匹配 UUID 0xEFEF → 保存写特征句柄 g_ble_chara_hanle_write_value
    ↓
gattc_discovery_descriptor()  发现特征描述符
    ↓
服务发现完成 → 开始数据收发

2.4、BLE 事件回调机制

BLE 协议栈通过回调函数异步通知应用层状态变化。本案例注册了 GAP 与 GATT Client 两类回调:

GAP 回调:

回调函数 触发时机 处理逻辑
ble_client_enable_cbk BLE 协议栈启用完成 设置设备名/MAC,注册 GATT 客户端,设置扫描参数
ble_client_set_scan_param_cbk 扫描参数设置完成 清除配对信息,开始扫描
ble_client_scan_result_cbk 扫描到广播设备 匹配目标 MAC,停止扫描并发起连接
ble_client_connect_change_cbk 连接状态变化 连接时交换 MTU;断开时重新扫描
ble_client_pair_result_cb 配对完成 交换 MTU

GATT Client 回调:

回调函数 触发时机 处理逻辑
ble_client_mtu_changed_cbk MTU 协商完成 开始服务发现
ble_client_discover_service_cbk 发现服务 发起特征发现
ble_client_discover_character_cbk 发现特征 匹配 0xEFEF 写句柄,发现描述符
ble_client_discover_descriptor_cbk 发现描述符 读取描述符值
ble_client_notification_cbk 收到 Notify 通知 将数据拷贝至 g_ble_rx_data,置位 g_ble_new_data_ready
ble_client_write_cfm_cbk 写操作完成 打印写操作结果
ble_client_read_cfm_cbk 读操作完成 打印读操作结果

2.5、软件调用层次

本案例的软件调用层次如下:

应用层(ble_client_app.c)
    ├── ble_server_app()          ← APP_FEATURE_INIT 注册入口
    ├── ble_rx_client()           ← 接收任务:打印服务端 Notify 数据
    └── ble_tx_client()           ← 发送任务:周期性 Write 发送数据
            │
封装层(ble_client_lib.c)
    ├── ble_client_init()         ← 初始化:注册回调、启用 BLE
    ├── ble_set_scan_parameters() ← 配置扫描参数
    ├── ble_start_scan()          ← 开始扫描
    ├── ble_client_discover_all_service() ← GATT 服务发现
    ├── ble_client_write_cmd()    ← GATT Write 发送
    └── ble_get_write_vlaue_handle() ← 获取写特征句柄
            │
协议栈 / 驱动层
    ├── gap_ble_*()               ← GAP 扫描与连接管理
    ├── gattc_*()                 ← GATT Client 发现/读写
    └── enable_ble()              ← 启用 BLE 协议栈

2.6、核心 API 介绍

2.6.1、头文件
#include "ble_client_lib.h"
#include "cmsis_os2.h"
#include "ohos_init.h"
2.6.2、应用层 API
API 名称 功能说明
ble_client_init() 初始化 BLE 客户端:注册回调、启用 BLE 协议栈
ble_get_write_vlaue_handle() 获取服务端 RX 特征的写句柄(服务发现后有效)
ble_client_write_cmd(data, len, handle) 通过 GATT Write 向服务端发送数据
osThreadNew(func, arg, &attr) 创建 RTOS 线程
osDelay(ticks) 线程延时,100 ticks ≈ 1 秒(tick = 10 ms)
APP_FEATURE_INIT(func) 注册应用特性初始化入口,系统启动后自动执行
2.6.3、协议栈 API(ble_client_lib.c 内部调用)
API 名称 功能说明
enable_ble() 启用 BLE 协议栈
gap_ble_set_local_name() 设置 GAP 本地设备名称
gap_ble_set_local_addr() 设置 BLE 设备 MAC 地址
gap_ble_set_scan_parameters() / gap_ble_start_scan() 配置并启动扫描
gap_ble_connect_remote_device() 连接远程 BLE 设备
gattc_register_client() 注册 GATT 客户端
gattc_exchange_mtu_req() 请求 MTU 交换
gattc_discovery_service() 发现 GATT 服务
gattc_discovery_character() 发现 GATT 特征
gattc_discovery_descriptor() 发现 GATT 描述符
gattc_write_cmd() 无应答写命令

3、程序设计

3.1、程序架构

本案例目录结构

d2_ble_connect_client/
├── ble_client_app.c      # 应用层:收发任务与入口
├── ble_client_lib.c      # 协议栈封装:扫描、连接、GATT 发现、回调
├── ble_client_lib.h      # 头文件:UUID 宏定义与 API 声明
├── BUILD.gn              # GN 编译配置
├── README_zh.md          # 案例简要说明
└── 实验手册.md            # 本实验手册

程序执行流程:

系统启动
    │
    ▼
ble_server_app()                ← APP_FEATURE_INIT 注册,自动执行
    │
    ├── ble_client_init()       ← 延时 3s → 注册回调 → 启用 BLE
    │       └── ble_client_enable_cbk → 设置名称/MAC → 注册 GATT Client
    │               └── 设置扫描参数 → 开始扫描
    │
    ├── osThreadNew(ble_rx_client)  ← 创建接收任务
    └── osThreadNew(ble_tx_client)  ← 创建发送任务
            │
            ▼
    ┌───────────────────────────────────────────┐
    │  扫描回调链(ble_client_lib.c)             │
    │  扫描到目标 MAC → 连接 → MTU 交换           │
    │  → 服务发现 → 特征发现 → 保存写句柄          │
    └───────────────────────────────────────────┘
    ┌───────────────────────────────────────────┐
    │  ble_rx_client(接收任务)                  │
    │  轮询 g_ble_new_data_ready → 打印 Notify 数据│
    └───────────────────────────────────────────┘
    ┌───────────────────────────────────────────┐
    │  ble_tx_client(发送任务)                  │
    │  每 1s 通过 Write 向服务端发送 send_date     │
    └───────────────────────────────────────────┘

3.2、源文件说明

文件 说明
ble_client_app.c 应用层主程序,定义发送数据缓冲区,创建 RX/TX 两个 RTOS 任务
ble_client_lib.c BLE 协议栈封装,实现扫描、连接、GATT 服务发现与各类回调处理
ble_client_lib.h UUID 宏定义、全局变量声明与 API 接口
BUILD.gn 编译配置,生成 ble_connect_client 静态库

3.3、关键代码分析

(1)UUID 与目标地址配置
#define BLE_CHARACTER_CLIENT_UUID_TX 0xEFEF

/* 客户端要连接的服务器地址(对应 MAC 11:22:33:44:55:66) */
static uint8_t g_ble_server_addr_connect[] = {0x66, 0x55, 0x44, 0x33, 0x22, 0x11};

/* 客户端本地 MAC 地址 */
static uint8_t g_ble_client_addr[] = {0x12, 0x22, 0x33, 0x44, 0x55, 0x66};

客户端通过 MAC 地址匹配目标服务端(而非设备名称),写特征 UUID 0xEFEF 对应服务端的 RX 特征,用于客户端向服务端发送数据。

(2)全局发送数据
uint8_t send_date[20] = "hello ble:from client";

客户端连接并发现服务后,发送任务每隔约 1 秒通过 Write 向服务端发送该字符串。

(3)接收任务 — ble_rx_client

接收任务通过轮询全局标志位 g_ble_new_data_ready 检测服务端 Notify 的新数据(由 GATT 通知回调 ble_client_notification_cbk 置位):

void ble_rx_client(void *arg)
{
    unused(arg);
    while (1)
    {
        if (g_ble_new_data_ready == true)
        {
            printf("ble rev date:%s", g_ble_rx_data);
            g_ble_new_data_ready = false;
        }
        osDelay(1);
    }
}
(4)发送任务 — ble_tx_client

发送任务周期性获取写特征句柄并调用 Write 发送接口:

void ble_tx_client(void *arg)
{
    unused(arg);
    while (1)
    {
        uint16_t write_handle = ble_get_write_vlaue_handle();
        ble_client_write_cmd(send_date, sizeof(send_date), write_handle);
        osDelay(100);
    }
}

注意:服务发现完成前 ble_get_write_vlaue_handle() 返回 0,此时 Write 操作无效。服务发现完成后句柄被正确赋值,数据收发方可正常工作。

(5)程序入口 — ble_server_app
static void ble_server_app(void)
{
    ble_client_init();

    osThreadAttr_t rx_attr = {0};
    rx_attr.name = "ble_rx_client";
    rx_attr.stack_size = 8192;
    rx_attr.priority = osPriorityNormal;
    osal_kthread_lock();
    if (osThreadNew(ble_rx_client, NULL, &rx_attr) == NULL)
    {
        printf("[LedTest] Failed to create led_pwm_main thread!\n");
    }
    osal_kthread_unlock();

    osThreadAttr_t tx_attr = {0};
    tx_attr.name = "ble_tx_client";
    tx_attr.stack_size = 8192;
    tx_attr.priority = osPriorityNormal;
    osal_kthread_lock();
    if (osThreadNew(ble_tx_client, NULL, &tx_attr) == NULL)
    {
        printf("[LedTest] Failed to create led_pwm_main thread!\n");
    }
    osal_kthread_unlock();
}

APP_FEATURE_INIT(ble_server_app);

说明:入口函数名为 ble_server_app(保留原代码命名),实际功能为 BLE 客户端初始化与任务创建。

(6)客户端初始化 — ble_client_init
errcode_t ble_client_init(void)
{
    errcode_t ret = ERRCODE_BT_SUCCESS;
    (void)osal_msleep(3000);   /* 延时 3s,等待 BLE 协议栈初始化完毕 */

    ret |= ble_client_callback_register();   /* 注册 GAP/GATT 回调 */
    ret |= enable_ble();                     /* 启用 BLE */
    return ret;
}

enable_ble() 成功后触发 ble_client_enable_cbk,在该回调中设置设备名/MAC、注册 GATT 客户端并配置扫描参数。

(7)扫描与连接 — ble_client_scan_result_cbk
void ble_client_scan_result_cbk(gap_scan_result_data_t *scan_result_data)
{
    if (memcmp(g_ble_server_addr_connect, scan_result_data->addr.addr,
               sizeof(g_ble_server_addr_connect)) == 0)
    {
        gap_ble_stop_scan();
        /* 构造连接地址并发起连接 */
        gap_ble_connect_remote_device(&bt_client_addr);
    }
}

扫描到目标 MAC 地址 11:22:33:44:55:66 后停止扫描并发起连接。

(8)GATT 服务发现链

连接建立后,回调链自动完成服务发现:

/* 连接成功 → 交换 MTU */
void ble_client_connect_change_cbk(...)
{
    if (conn_state == GAP_BLE_STATE_CONNECTED)
        gattc_exchange_mtu_req(g_client_id, g_conn_id, g_mtu);
}

/* MTU 完成 → 发现所有服务 */
void ble_client_mtu_changed_cbk(...)
{
    ble_client_discover_all_service(conn_id);
}

/* 发现服务 → 发现特征 */
void ble_client_discover_service_cbk(...)
{
    gattc_discovery_character(g_client_id, conn_id, &param);
}

/* 发现特征 → 匹配 0xEFEF 写句柄 */
void ble_client_discover_character_cbk(...)
{
    if (memcmp(character->uuid.uuid, write_uuid.uuid, ...) == 0)
        g_ble_chara_hanle_write_value = character->value_handle;
}
(9)Notify 接收 — ble_client_notification_cbk
void ble_client_notification_cbk(uint8_t client_id, uint16_t conn_id,
                               gattc_handle_value_t *data, errcode_t status)
{
    if ((data->data_len > 0) && data->data)
    {
        if (data->data_len <= sizeof(g_ble_rx_data))
        {
            memcpy(g_ble_rx_data, data->data, data->data_len);
            g_ble_rx_len = data->data_len;
            g_ble_new_data_ready = true;
        }
    }
}
(10)BUILD.gn — 编译配置
static_library("ble_connect_client") {
  sources = [
    "ble_client_lib.c",
    "ble_client_app.c",
  ]
  // ...
}

3.4、程序执行流程

d1 服务端 GATT Client GAP ble_client_lib ble_client_app d1 服务端 GATT Client GAP ble_client_lib ble_client_app loop [每 1 秒] loop [服务端 Notify] ble_client_init() enable_ble() ble_client_enable_cbk 设置扫描参数 → 开始扫描 创建 ble_rx_client / ble_tx_client 任务 广播 ble_uart_server scan_result_cbk(匹配目标 MAC) gap_ble_connect_remote_device() connect_change_cbk (CONNECTED) gattc_exchange_mtu_req() mtu_changed_cbk gattc_discovery_service() discover_service_cbk → 发现特征 discover_character_cbk → 保存 0xEFEF 写句柄 ble_client_write_cmd() gattc_write_cmd() Write RX 特征 Notify TX 特征 notification_cbk → g_ble_rx_data ble_rx_client 打印接收数据

4、编译步骤

本实验编译客户端固件并烧录至 开发板 B;服务端固件请参考 d1_ble_connect_server 案例编译烧录至 开发板 A。以下步骤只需在首次编译时完成 4.1~4.3 的配置注册。

4.1、确认案例目录

确认案例已位于 OpenHarmony 源码目录下:

applications/sample/wifi-iot/app/d2_ble_connect_client/
├── ble_client_app.c
├── ble_client_lib.c
├── ble_client_lib.h
├── BUILD.gn
└── 实验手册.md

若从外部复制,请将 d2_ble_connect_client 目录放到上述 app/ 路径下。

4.2、修改 BUILD.gn(注册编译组件)

编辑 applications/sample/wifi-iot/app/BUILD.gn,在 features 列表中添加本案例:

lite_component("app") {
  features = [
    "startup",
    "d2_ble_connect_client:ble_connect_client",   // 添加此行
  ]
}

4.3、修改 SDK 配置文件

步骤 1:编辑 device/soc/hisilicon/ws63v100/sdk/build/config/target_config/ws63/config.py

找到 'ws63-liteos-app' 配置段,在其 'ram_component' 列表中添加:

"ble_connect_client"

步骤 2:编辑 device/soc/hisilicon/ws63v100/sdk/libs_url/ws63/cmake/ohos.cmake

找到 "ws63-liteos-app" 对应的 set(COMPONENT_LIST 部分,添加:

"ble_connect_client"

4.4、编译固件

在 OpenHarmony 源码根目录下执行编译:

rm -rf out
hb set -root .
# 通过上下方向键选择 ws63 对应的编译分支(如 nearlink_txnl63 / nearlink_dk_3863)
hb build -f

编译成功后,将固件烧录到 开发板 B(作为 BLE 客户端)。

4.5、编译服务端固件(开发板 A)

按照 d1_ble_connect_server 案例的 README 或实验手册,完成服务端的 BUILD.gn 与 SDK 配置注册,编译后将固件烧录到 开发板 A

4.6、烧录固件

使用开发板配套的烧录工具,将编译生成的固件分别烧写到两块 LZ3863-星闪开发板。具体烧录步骤请参考开发板用户手册。


5、运行结果

5.1、硬件准备

  1. 开发板 A(服务端固件 d1_ble_connect_server)上电或复位,等待 BLE 广播启动;
  2. 开发板 B(客户端固件,本案例)上电或复位,开始扫描并连接服务端;
  3. 两块开发板分别通过 USB 连接 PC,打开串口助手查看日志(波特率 115200,8N1)。

建议:先启动服务端开发板,确认广播启动日志输出后,再启动客户端开发板,以提高首次连接成功率。

5.2、串口配置

参数
波特率 115200
数据位 8
停止位 1
校验位
流控

5.3、客户端预期输出(开发板 B)

烧录客户端固件并复位后,串口助手可观察到 BLE 初始化、扫描、连接与服务发现过程:

[SLE Client] try enable1.
ble enable: 0
ble enable end: 0
[ble client] set scan param status: 0

addr: 66: 55: 44: 33: 22: 11:
[ble client] connect state change conn_id: x, status: 2, pair_status:0, disc_reason 0
[ble client] connect change cbk conn_id =x
[ble client] Mtu changed----client:x conn_id:x, mtu size:xx, status:0
[ble client] Discovery service callback client:x conn_id:x
[ble client] discover character declare_handle:xx, value_handle:xx, properties:xx
[ble client] write declare_handle:xx, value_handle:xx, properties:xx

表示 BLE 协议栈启用成功,已扫描到目标服务端并完成连接与 GATT 服务发现。

连接建立且服务发现完成后,客户端还会持续输出:

ble rev date:hello ble:from server
[ble client] Write result----client:x conn_id:x handle:xx
[ble client] status:0

其中:

  • ble enable: 0 表示 BLE 协议栈启用成功;
  • connect state change ... status: 2 表示已成功连接服务端(GAP_BLE_STATE_CONNECTED);
  • Discovery service / discover character 表示 GATT 服务发现完成;
  • ble rev date:hello ble:from server 表示收到服务端 Notify 发送的数据;
  • Write result ... status:0 表示向服务端写入数据成功。

5.4、服务端预期输出(开发板 A)

烧录 d1_ble_connect_server 固件并复位后,串口助手可观察到广播启动与客户端连接过程:

[ble server] start service cbk , start adv
[ble uart adv] ble_uart_start_adv adv_id 1
[ble server] adv enable cbk adv_id:1 status:0
[ble server] connect state change conn_id: x, status: 2, ...
[ble server] send input report indicate_handle:xx
ble rev date:hello ble:from client

5.5、双向通信验证

连接建立后,两块开发板应持续(约每秒一次)交换数据:

方向 发送内容 接收端串口输出
服务端 → 客户端 hello ble:from server 客户端:ble rev date:hello ble:from server
客户端 → 服务端 hello ble:from client 服务端:ble rev date:hello ble:from client

5.6、结果分析

现象 说明
客户端输出 ble enable: 0 BLE 协议栈启用成功
客户端输出 set scan param status: 0 扫描参数配置成功,开始扫描
客户端输出 connect state change ... status: 2 已成功连接服务端
客户端输出 Discovery service / discover character GATT 服务发现正常
客户端输出 ble rev date:hello ble:from server Notify 接收正常
客户端输出 Write result ... status:0 Write 发送正常
客户端长时间无连接日志 服务端未启动或 MAC 地址不匹配
连接成功但无数据收发 GATT 服务发现未完成,检查 UUID 是否匹配
客户端有 Write 但服务端无接收 写特征句柄错误或 UUID 不匹配

5.7、常见问题排查

问题 可能原因 解决方法
客户端扫描不到服务端 服务端未启动或广播失败 确认服务端输出 adv enable cbk;先启动服务端
扫描到设备但不连接 MAC 地址配置不一致 确认 g_ble_server_addr_connect 与服务端 MAC 11:22:33:44:55:66 一致
连接后立即断开 信号干扰或协议栈未就绪 两块板靠近放置;确认双方 init 延时 3s 已执行
客户端无 ble rev date 输出 服务发现未完成或 Notify 未启用 检查服务发现日志;确认服务端 CCC 描述符已启用 Notify
服务端无 ble rev date 输出 客户端写句柄为 0 或 UUID 不匹配 确认客户端已完成特征发现并匹配 0xEFEF
编译报错找不到 ble_connect_client BUILD.gn 或 config.py 未正确修改 逐步核对 4.2、4.3 节的配置项
两块板烧录了相同固件 未区分服务端/客户端固件 分别编译烧录 d1(服务端)和 d2(客户端)

6、实验扩展

完成基本实验后,可尝试以下扩展练习:

  1. 修改目标 MAC 地址:更改 g_ble_server_addr_connect,配合修改服务端 MAC,观察扫描连接行为;
  2. 修改发送内容:更改 send_date 字符串,验证 Write 发送自定义数据;
  3. 调整发送频率:修改 ble_tx_clientosDelay(100) 的参数,观察收发频率变化;
  4. 按设备名称扫描:修改扫描回调逻辑,改为匹配广播名称 ble_uart_server 而非 MAC 地址;
  5. 断开重连测试:断开 BLE 连接后观察客户端是否自动重新扫描并成功重连;
  6. 手机模拟服务端:使用手机 BLE 调试 App 模拟 GATT 服务端,用本客户端案例连接测试;
  7. 结合后续案例:在 BLE 连接基础上,配合其他蓝牙或网络通信案例实现更复杂的物联网应用。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐