
🧠关键词: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 Connect 或 LightBlue
扫描并连接名为 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



![[office] excel表头怎么制作- - 宋马](https://pic.songma.com/blogimg/20250821/5da5f747a1fd415ea3ab2a9fbec3edee.jpg)















暂无评论内容