【Zephyr 系列 6】使用 Zephyr + BLE 打造蓝牙广播与连接系统(STEVAL-IDB011V1 实战)

🧠关键词:Zephyr、BLE、广播、连接、GATT、低功耗蓝牙、STEVAL-IDB011V1
📌适合人群:希望基于 Zephyr 实现 BLE 通信的嵌入式工程师、蓝牙产品开发人员


🧭 前言:为什么选择 Zephyr 开发 BLE?

在传统 BLE 开发中,我们大多依赖于厂商 SDK(如 Nordic SDK、BlueNRG SDK、Dialog SDK 等),这带来以下几个问题:

问题 描述
开发分裂 各厂商接口不统一
文档不一致 学习曲线陡峭
移植困难 工程难以重用
工具受限 多为 Windows/Keil

Zephyr BLE 栈完全开源,支持多个 BLE 芯片平台基于主线 Bluetooth Core Spec 5.3,同时集成了 Host Stack(HCI、L2CAP、GATT、GAP)与 Controller 抽象,是目前最具潜力的 BLE 通信框架之一。


🧰 本篇目标与功能设计

我们将使用 ST 官方 BLE 板 STEVAL-IDB011V1,搭建一个蓝牙外围设备(Peripheral)系统,支持如下功能:

配置广播参数(名称、间隔、功率)

设置 GATT 服务(包含一个可读写的特征)

手机 App 可连接该设备,并发送/接收数据

所有操作使用 Zephyr BLE API 实现,代码清晰可移植


🛠 硬件与软件准备

项目 描述
板子 STEVAL-IDB011V1(BlueNRG-LP)
芯片 ST BlueNRG-355
连接方式 USB 转串口(PA9/PA8)
烧录方式 ST-Link 或 CMSIS-DAP
Zephyr SDK v0.16.3
Zephyr 版本 v3.5 或以上推荐
手机 App LightBlue / nRF Connect(用于测试)

📁 项目结构

zephyr-ble-demo/
├── app/
│   ├── src/
│   │   ├── main.c
│   │   ├── ble_service.c
│   │   └── ble_service.h
│   ├── prj.conf
│   └── CMakeLists.txt

📄 prj.conf 配置说明

# 基础模块
CONFIG_GPIO=y
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_PRINTK=y

# BLE 栈
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="ZEPHYR_BLE_DEMO"
CONFIG_BT_DEVICE_APPEARANCE=833
CONFIG_BT_MAX_CONN=1

# GATT 特征支持
CONFIG_BT_GATT_CLIENT=n
CONFIG_BT_GATT_SERVICE_CHANGED=y
CONFIG_BT_GATT_DYNAMIC_DB=y

# 低功耗
CONFIG_PM=y
CONFIG_PM_DEVICE=y

📄 CMakeLists.txt

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(ble_demo)
target_sources(app PRIVATE src/main.c src/ble_service.c)

🧠 蓝牙系统结构图(PlantUML)

 

📄 main.c

#include <zephyr.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include "ble_service.h"

void main(void)
{
    printk("Starting BLE Peripheral Demo...
");

    int err = bt_enable(NULL);
    if (err) {
        printk("Bluetooth init failed (%d)
", err);
        return;
    }

    printk("Bluetooth ready. Starting advertising...
");

    ble_service_init();  // 初始化 GATT 服务

    // 广播数据配置
    const struct bt_data ad[] = {
        BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
        BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, strlen(CONFIG_BT_DEVICE_NAME))
    };

    // 开始广播
    err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
    if (err) {
        printk("Advertising failed to start (%d)
", err);
        return;
    }

    printk("Advertising successfully started
");
}

📄 ble_service.h

#ifndef BLE_SERVICE_H_
#define BLE_SERVICE_H_

void ble_service_init(void);

#endif

📄 ble_service.c

#include <zephyr/types.h>
#include <stddef.h>
#include <sys/printk.h>
#include <bluetooth/gatt.h>

// 回调函数
static ssize_t write_rx(struct bt_conn *conn,
                        const struct bt_gatt_attr *attr,
                        const void *buf,
                        uint16_t len, uint16_t offset, uint8_t flags)
{
    printk("Received data: ");
    for (int i = 0; i < len; i++) {
        printk("%c", ((char *)buf)[i]);
    }
    printk("
");
    return len;
}

// GATT 特征
BT_GATT_SERVICE_DEFINE(custom_svc,
    BT_GATT_PRIMARY_SERVICE(BT_UUID_DECLARE_16(0x180F)),
    BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_16(0x2A19),
                           BT_GATT_CHRC_WRITE_WITHOUT_RESP,
                           BT_GATT_PERM_WRITE, NULL, write_rx, NULL),
    BT_GATT_CHARACTERISTIC(BT_UUID_DECLARE_16(0x2A1C),
                           BT_GATT_CHRC_NOTIFY,
                           BT_GATT_PERM_NONE, NULL, NULL, NULL),
);

// 初始化函数
void ble_service_init(void)
{
    printk("Custom BLE service initialized
");
}

📱 手机测试流程

打开手机上的 nRF ConnectLightBlue

扫描并连接名为 ZEPHYR_BLE_DEMO 的设备

进入 GATT 服务,找到两个特征:

可写:用于发送数据(写入后串口打印)

可通知:后续可用于透传数据给手机

发送数据,如 “HELLO”,终端应打印:

Received data: HELLO

⚡ 性能与功耗测试建议

测试项 方法 目标
连接功耗 万用表测 VCC 电流 确认连接后约 <5mA
广播功耗 停止连接、仅广播 电流应约 1~3mA
低功耗模式 配合 PM 模块 可配置 Sleep / Stop 模式

🧩 常见问题解析

问题 原因 解决方案
手机无法扫描到设备 广播未启动或名称为空 检查 bt_le_adv_start() 返回值
手机连接后无响应 GATT 服务未注册或 UUID 错误 检查 BT_GATT_SERVICE_DEFINE()
写入数据不打印 没有配置回调或权限设置不当 确认 BT_GATT_PERM_WRITE 设置
断开连接后无法重连 广播未重新启用 可在 bt_conn_cb 中添加断开后重启广播逻辑

📚 下一篇预告:《Zephyr BLE 数据透传系统设计与实现(支持双向数据通道)》

你将学到:

完整 BLE 串口透传系统

使用 Notify 通知机制实现回传

状态同步 + Buffer 队列管理策略

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容