在物联网智能家居、工业控制等场景中,Zigbee 技术以其低功耗、高可靠性成为短距离无线通信的核心选择。STM32WB 系列双核微控制器(Arm® Cortex-M4/Cortex-M0+)原生支持 Zigbee 协议,配合 Exegin ZCL(Zigbee Cluster Library)群集模板,可快速构建符合标准的 Zigbee 应用。本文基于意法半导体 AN5498 应用笔记,详解群集模板的核心概念、实操步骤、群集类型及调试要点,助力开发人员高效落地 Zigbee 产品。
1. 核心概述
1.1 群集模板的价值
Zigbee 群集是一组标准化的属性和命令集合,用于实现特定设备功能(如开关控制、温度测量)。Exegin 提供的群集模板已预置 Zigbee PRO 规范([R1])、ZCL 7 规范([R2])定义的强制性属性和命令,且部分已通过 Zigbee 联盟认证测试,开发者无需从零实现协议细节,仅需对接硬件接口或补充应用逻辑即可。
1.2 适用范围与核心依赖
- 硬件:STM32WB 系列微控制器(如 STM32WB55RG、STM32WB75VG);
- 软件:ZSDK(Zigbee Software Development Kit)、Exegin ZCL 群集模板;
- 参考文档:需提前准备 Zigbee PRO 规范([R1])、ZCL 7 规范([R2])、ZSDK API 文档([R3])及智能能源标准([R4],如需)。
1.3 群集分类与架构
(1)群集三大类型
| 群集类型 |
核心作用 |
典型示例 |
| 以应用为中心的群集 |
实现设备核心功能,对接硬件 |
开关(OnOff)、温度测量、颜色控制 |
| 支持群集 |
提供通用辅助功能,支撑其他群集 |
基本群集(设备信息)、群组群集(多设备管理)、报警群集 |
| 特殊专用端点群集 |
提供独立特殊功能,通常位于专属端点 |
Touchlink(配网)、CBKE(智能能源安全)、绿色电源 |
(2)客户端 - 服务器架构
Zigbee 群集的功能交互基于 “客户端 - 服务器” 模型:
- 服务器群集:运行在提供服务的设备上(如灯的 “开关服务器”),暴露属性和命令接口;
- 客户端群集:运行在控制设备上(如遥控器的 “开关客户端”),通过发送命令请求访问服务器功能;
- 端点关联:每个群集实例绑定到唯一端点(端点 ID 范围 1-239,0 及 240-255 为保留值),一个端点可包含多个群集(如 “开关 + 基本 + 报警群集”)。
2. 快速入门清单
开发前需完成以下准备,避免后续流程卡顿:
- 确认应用所需的 ZCL 群集(如智能灯需 “OnOff 群集 + 颜色控制群集 + 基本群集”);
- 规划端点分配(多群集实例需对应多个端点);
- 准备参考文档([R1]-[R4])及 ZSDK 开发环境;
- 明确群集角色(客户端 / 服务器):如遥控器需实现 “OnOff 客户端”,灯需实现 “OnOff 服务器”。
3. 核心操作步骤(从端点到群集落地)
3.1 第一步:创建端点
端点是群集的载体,需先通过 ZSDK API 创建端点并配置 Profile ID(配置文件 ID)和 Device ID(设备 ID),示例代码如下:
#include "zcl.h"
ZbApsmeAddEndpointReqT add_ep_req;
ZbApsmeAddEndpointConfT add_ep_conf;
// 初始化请求结构体(必须归零,避免内存未初始化问题)
memset(&add_ep_req, 0, sizeof(add_ep_req));
memset(&add_ep_conf, 0, sizeof(add_ep_conf));
// 配置端点参数:端点ID=1,家居自动化Profile,开关设备
add_ep_req.endpoint = 1;
add_ep_req.profileId = ZCL_PROFILE_HOME_AUTOMATION;
add_ep_req.deviceId = ZCL_DEVICE_ONOFF_SWITCH;
// 调用API创建端点
ZbZclAddEndpoint(app->zb, &add_ep_req, &add_ep_conf);
- 关键说明:Profile ID 和 Device ID 在
zcl.h中定义(如ZCL_PROFILE_HOME_AUTOMATION=0x0104),需根据设备类型选择。
3.2 第二步:实例化群集
端点创建后,通过群集专属的Alloc函数实例化客户端或服务器群集,示例如下:
(1)服务器群集实例化(如 “OnOff 服务器”)
#include "zcl.onoff.h"
// 定义命令回调结构体(仅实现需要的命令)
struct zcl_onoff_callbacks_t onoff_callbacks = {
.on = app_onoff_on_handler, // 处理“打开”命令
.off = app_onoff_off_handler, // 处理“关闭”命令
.toggle = NULL // 不支持“切换”命令,返回默认响应
};
// 实例化OnOff服务器群集(绑定到端点1)
app->onoff_server = ZbZclOnOffServerAlloc(
app->zb, // ZSDK协议栈指针
1, // 端点ID
&onoff_callbacks, // 命令回调
app // 自定义参数(回调中可获取)
);
// 检查实例化结果
if (app->onoff_server == NULL) {
// 处理创建失败(如内存不足)
}
(2)客户端群集实例化(如 “OnOff 客户端”)
#include "zcl.onoff.h"
// 实例化OnOff客户端群集
app->onoff_client = ZbZclOnOffClientAlloc(
app->zb, // 协议栈指针
1 // 端点ID
);
3.3 第三步:寻址与绑定(实现群集通信)
Zigbee 设备间通信需通过 “绑定” 机制(预配置源 - 目标地址映射),避免重复寻址。绑定可通过以下两种方式实现:
(1)手动绑定(代码配置)
#include "zigbee.aps.h"
ZbApsmeBindReqT bind_req;
memset(&bind_req, 0, sizeof(bind_req));
// 配置绑定参数:源端点、源群集ID、目标地址(绑定表自动匹配)
bind_req.srcEndpoint = 1;
bind_req.clusterId = ZCL_CLUSTER_ONOFF;
bind_req.dstAddr.mode = ZB_APSDE_ADDRMODE_NOTPRESENT; // 使用绑定表
// 发起绑定请求
ZbApsmeBindReq(app->zb, &bind_req, NULL, app);
(2)自动查找与绑定(BDB 机制)
通过 BDB(Binding and Device Binding)自动匹配客户端与服务器群集,步骤如下:
- 目标设备(服务器)进入识别模式(如按下物理按键);
- 发起设备(客户端)调用
ZbStartupFindBindStart()启动查找;
- 发起设备自动扫描并创建绑定,无需手动配置地址。
3.4 第四步:属性与命令处理
(1)属性操作(读取 / 写入)
- 本地属性写入(服务器更新自身属性):
// 写入OnOff服务器的“当前状态”属性(1=打开,0=关闭)
ZbZclAttrIntegerWrite(
app->onoff_server,
ZCL_ONOFF_ATTR_ONOFF, // 属性ID
1 // 属性值
);
- 远程属性读取(客户端访问服务器属性):
void onoff_read_rsp_handler(const ZbZclReadRspT *rsp, void *arg) {
struct application *app = (struct application *)arg;
if (rsp->status == ZCL_STATUS_SUCCESS) {
// 读取服务器“当前状态”属性值
app->remote_onoff_state = *(uint8_t *)rsp->attr[0].value;
}
}
// 发起远程读取请求(通过绑定表发送)
ZbZclReadReqT read_req;
memset(&read_req, 0, sizeof(read_req));
read_req.dst = &ZbApsAddrBinding; // 使用绑定
read_req.count = 1;
read_req.attr[0] = ZCL_ONOFF_ATTR_ONOFF; // 要读取的属性ID
ZbZclReadReq(
app->onoff_client,
&read_req,
onoff_read_rsp_handler,
app
);
(2)命令发送与响应(客户端→服务器)
客户端向服务器发送命令(如 “打开” 命令),示例如下:
// 发送“打开”命令到绑定的服务器
ZbZclOnOffClientOnReq(
app->onoff_client,
&ZbApsAddrBinding, // 绑定地址
NULL, // 命令参数(OnOff命令无额外参数)
NULL, // 响应回调(可选)
app
);
服务器通过回调处理命令并控制硬件,示例如下:
enum ZclStatusCodeT app_onoff_on_handler(
struct ZbZclClusterT *cluster,
struct ZbZclAddrInfoT *src_info,
void *arg
) {
struct application *app = (struct application *)arg;
// 控制硬件:打开LED(示例GPIO操作)
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
// 更新本地属性状态
ZbZclAttrIntegerWrite(cluster, ZCL_ONOFF_ATTR_ONOFF, 1);
return ZCL_STATUS_SUCCESS;
}
4. 三类群集详细使用指南
4.1 以应用为中心的群集(核心功能载体)
此类群集是设备核心能力的体现,需对接硬件接口。STM32WB 支持的主流应用群集及对应头文件如下:
| 群集名称 |
头文件 |
核心用途 |
| OnOff(开关) |
zcl.onoff.h |
设备开关控制(灯、插座) |
| 温度测量 |
zcl.temp.meas.h |
采集并上报温度数据 |
| 颜色控制 |
zcl.color.h |
调节 LED 颜色、色温 |
| 门锁 |
zcl.doorlock.h |
门锁开关、权限管理 |
| 电气测量 |
zcl.elec.meas.h |
电能计量(电压、电流、功率) |
关键扩展:添加可选属性
群集模板默认仅包含强制性属性,如需添加可选属性(如 “开关延迟时间”),可通过ZbZclAttrAppendList实现:
// 定义可选属性列表
static const struct ZbZclAttrT onoff_optional_attrs[] = {
{
ZCL_ONOFF_ATTR_DELAY_OFF, // 可选属性ID:关闭延迟
ZCL_DATATYPE_UNSIGNED_16BIT, // 数据类型
ZCL_ATTR_FLAG_NONE, // 属性标志
0, NULL, {0, 0}, {0, 0}
}
};
// 向已实例化的服务器群集添加可选属性
if (ZbZclAttrAppendList(
app->onoff_server,
onoff_optional_attrs,
ZCL_ATTR_LIST_LEN(onoff_optional_attrs)
) != ZCL_STATUS_SUCCESS) {
// 处理添加失败
}
4.2 支持群集(通用辅助功能)
支持群集不直接实现应用功能,但为其他群集提供必要支撑,以下是常用类型的使用要点:
(1)基本群集(必选)
- 作用:存储设备制造商信息、型号、固件版本等全局信息,协议栈自动为每个端点创建实例;
- 关键 API:
ZbZclBasicWriteDirect(直接写入全局属性):
// 写入制造商名称(Zigbee字符串格式:首字节为长度)
char mfr_name[] = "STMicroelectronics";
uint8_t zb_mfr_str[sizeof(mfr_name) + 1];
zb_mfr_str[0] = sizeof(mfr_name); // 字符串长度
memcpy(&zb_mfr_str[1], mfr_name, sizeof(mfr_name));
// 写入基本群集的“制造商名称”属性(所有端点生效)
ZbZclBasicWriteDirect(
app->zb,
1, // 任意有效端点
ZCL_BASIC_ATTR_MFR_NAME,
zb_mfr_str,
sizeof(zb_mfr_str)
);
(2)群组群集
- 作用:将多个设备归入同一群组,实现多播控制(如 “全开所有灯”);
- 关键操作:通过
ZbApsmeAddGroupReq添加设备到群组,通过群组地址发送命令。
(3)报警群集
- 作用:记录其他群集的报警事件(如温度过高),并通知绑定的客户端;
- 关键 API:
ZbZclClusterSendAlarm(发送报警):
// 温度测量群集发送“温度过高”报警(报警代码0x01)
ZbZclClusterSendAlarm(
app->temp_meas_cluster,
0x01, // 报警代码
NULL, // 附加数据
0 // 附加数据长度
);
4.3 特殊专用端点群集(独立功能模块)
此类群集位于专属端点,由协议栈自动创建或通过配置启用,无需手动实例化:
| 群集类型 |
专属端点 |
启用方式 |
核心作用 |
| Touchlink |
自定义(ZbStartupT 中配置) |
启用 BDB_COMMISSION_MODE_TOUCHLINK |
快速配网(无需手动输入网络信息) |
| CBKE |
默认 240(可修改) |
设置 ZbStartupT.security.cbke.suite_mask |
智能能源安全加密 |
| 绿色电源 |
242 |
非智能能源版本 ZSDK 自动创建 |
低功耗设备供电管理 |
5. 调试与认证要点
5.1 PICS 设置与 ZTT 测试
- PICS(协议实现一致性声明):群集模板包含默认 PICS 配置(标注已实现的属性 / 命令),如需认证,需在 ZTT(Zigbee 测试工具)中手动配置 PICS;
- 操作步骤:打开 ZTT→PICS 选项卡→找到目标群集→勾选已实现的特征(PICS 中为 TRUE 的项)→运行认证测试。
5.2 常见问题排查
- 群集实例化失败:检查端点 ID 是否重复、协议栈指针是否有效、内存是否充足;
- 绑定失败:确认客户端与服务器的群集 ID 一致、目标设备已进入识别模式;
- 命令无响应:检查回调函数是否正确注册、属性 ID / 数据类型是否匹配、绑定表配置是否正确。
6. 实用建议与注意事项
- 内存初始化:所有 ZSDK 结构体(如
ZbApsmeAddEndpointReqT)必须通过memset归零,避免不可预测行为;
- 回调函数设计:仅暴露必要参数(如群集指针),提高回调通用性,避免冗余数据传递;
- 版本兼容性:智能能源应用与非智能能源应用需使用不同 ZSDK 版本(智能能源支持 CBKE,不支持 Touchlink / 绿色电源);
- 属性权限:OTA(远程)只读属性可通过本地 API(如
ZbZclAttrIntegerWrite)修改,灵活适配业务需求。
本文基于 AN5498 第 2 版文档整理,适用于 STM32WB 系列全型号及 ZSDK 最新版本。实际开发中若与芯片手册或 ZSDK 文档存在差异,以意法半导体官网最新资料为准。通过群集模板的标准化开发,可大幅缩短 Zigbee 产品的研发周期,同时保证产品兼容性与可靠性。