Skip to content

实验一:Z-Stack 简单组网实验 ​

一句话理解

本实验直接利用《2.3 ZigBee 3.0 组网实验》的组网方法完成网络组建,并在此基础上做一件事:在入网成功的位置插入 Terminal(串口终端)打印,把 PAN ID、信道、短地址、父节点等网络信息实时打印到 PC 端,作为组网成果的"验收凭证"。

前置知识 ​

本实验完全基于 2.3 ZigBee 3.0 组网实验 一节的知识,请先按该章节完成:

  1. 裁剪应用层冗余 UI(删除 UI_ 相关内容);
  2. 编写组网代码:
    • 协调器:bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING) + NLME_PermitJoiningRequest(255);
    • 路由器/终端:bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING);
  3. 选择设备角色(CoordinatorEB / RouterEB / EndDeviceEB)编译下载;
  4. 观察协调器屏幕显示 PanID、节点屏幕显示 网络地址与父节点地址。

本实验的增量是:在入网成功的位置,用串口终端打印辅助信息,替代/补充屏幕显示,便于批量验证与记录。

实验目的 ​

  1. 掌握 ZigBee 网络组建全流程(复用 2.3 章节知识:协调器建网、设备入网);
  2. 掌握 在入网成功处插入 Terminal 打印的方法(串口输出网络参数);
  3. 能够用 PC 端串口终端"验收"组网成果(PAN ID 一致、地址分配正确)。

实验器材 ​

器材数量用途
GEC2530 开发板3 块1 协调器 + 1 路由器 + 1 终端
ZigBee 仿真器1 个烧录程序
USB 转串口线1~3 根节点 → PC 串口终端
串口调试助手 / Xshell1 套Terminal 打印观察
IAR EW for 80511 套编译工程

实验原理 ​

组网与终端打印的整体流程 ​

🏛️
协调器建网
bdb_StartCommissioning(NWK_FORMATION)
→ 建网成功 → 终端打印 "NETWORK UP"
入网
🛰️
路由器 / 终端入网
bdb_StartCommissioning(NWK_STEERING)
→ 入网成功 → 终端打印 "JOIN OK"
🔌 串口
💻
PC 串口终端
实时显示每个节点的
PAN ID / 信道 / 短地址 / 父节点

为什么要用终端打印? ​

2.3 章节中组网成果显示在开发板 LCD 屏幕上,但 LCD 字符少、难记录。把同样的信息打印到串口终端,可以:

  • 一次性看到完整网络参数(PAN ID、信道、短地址、父节点、扩展地址);
  • 在 PC 端留存日志,方便实验报告截图与多节点批量验证;
  • 与上位机开发衔接(后续实验六的串口数据链路就是从这里起步)。

打印哪些信息? ​

打印项获取 API含义
PAN ID_NIB.nwkPanId网络号,同一网络内所有节点相同
信道 CH_NIB.nwkLogicalChannel无线通信通道
短地址 AddrNLME_GetShortAddr()入网后分配的 16 位地址
父节点 ParentNLME_GetCoordShortAddr()所挂接的上级节点地址
扩展地址 ExtAddrNLME_GetExtAddr()芯片唯一 64 位地址

实验步骤 ​

步骤 1:按 2.3 章节完成组网工程 ​

  1. 打开 Z-Stack 3.0.1 的 SampleSwitch 工程(与 2.3 章节一致);
  2. 完成 UI 裁剪、组网代码、入网失败自动重连(可选用);
  3. 分别编译 CoordinatorEB / RouterEB / EndDeviceEB 三个角色固件。

步骤 2:编写终端打印函数 ​

在应用层(如 zcl_samplesw.c)添加一个网络信息打印函数:

c
#include <stdio.h>   // 使用 sprintf 需要

/* 打印网络信息到串口终端 */
static void PrintNetworkInfo(uint8 *tag)
{
  uint8 buf[64];
  uint16 panId   = _NIB.nwkPanId;              // 网络号
  uint8  channel = _NIB.nwkLogicalChannel;     // 信道
  uint16 addr    = NLME_GetShortAddr();        // 本节点短地址
  uint16 parent  = NLME_GetCoordShortAddr();   // 父节点地址

  // 组装一行文本: [标签] PAN:0xXXXX CH:X Addr:0xXXXX Parent:0xXXXX
  sprintf((char *)buf, "[%s] PAN:0x%04X CH:%d Addr:0x%04X Parent:0x%04X\r\n",
          tag, panId, channel, addr, parent);

  // 通过串口 0 输出到 PC 终端
  HalUARTWrite(0, buf, osal_strlen((char *)buf));
}

步骤 3:在入网成功处插入打印 ​

方式 A(推荐,通用):在应用层事件循环的 ZDO_STATE_CHANGE 事件中,判断入网成功状态后打印:

c
case ZDO_STATE_CHANGE:
{
  // devState 为设备当前网络状态
  if (devState == DEV_ZB_COORD)
  {
    PrintNetworkInfo("NETWORK UP");   // 协调器建网成功
  }
  else if (devState == DEV_ROUTER || devState == DEV_END_DEVICE)
  {
    PrintNetworkInfo("JOIN OK");      // 路由器/终端入网成功
  }
}
break;

方式 B(与 2.3 章节衔接):在 zclSampleSw_ProcessCommissioningStatus() 的入网成功分支中插入:

c
/* 协调器 */
#ifdef ZDO_COORDINATOR
    /* 建网成功 */
    PrintNetworkInfo("NETWORK UP");
/* 路由器或者终端 */
#else
    /* 入网成功 */
    PrintNetworkInfo("JOIN OK");
#endif

提示

  • 串口初始化已在 2.3 章节的工程预编译中开启(LED、串口、显示屏等功能),无需额外配置;
  • 方式 A 通用性更强(SampleApp / zcl 工程均适用);方式 B 紧贴 2.3 章节的代码位置,二选一即可。

步骤 4:编译下载与终端观察 ​

  1. 三台设备分别编译对应角色固件并下载;
  2. 协调器连接 USB 转串口到 PC,打开串口助手(波特率与固件一致,默认 115200);
  3. 先给协调器上电 → 终端应打印 [NETWORK UP] PAN:0xXXXX CH:XX Addr:0x0000 Parent:0xFFFF;
  4. 再依次给路由器、终端上电 → 终端应打印 [JOIN OK] PAN:0xXXXX ... Addr:0xXXXX Parent:0xXXXX;
  5. 记录三台设备的打印结果。

步骤 5:验证与记录 ​

  1. 对比三台设备打印的 PAN ID 是否一致(同一网络)、信道是否相同;
  2. 对比父节点地址:路由器直连协调器(Parent = 0x0000),终端挂在路由器下(Parent = 路由器短地址);
  3. 将打印内容截图,作为组网成功的"验收凭证"。

在线仿真环节:printf + Terminal I/O 查看辅助信息 ​

在线仿真(连接仿真器、进入 C-SPY 调试会话)过程中,程序里的 printf 输出会实时显示在 IDE 界面的 Terminal I/O 窗口——无需外接串口线,是调试阶段查看辅助信息最直接的方式。

配置步骤(在线仿真) ​

  1. 接线:仿真器连接开发板与 PC(在线仿真必需);
  2. Project → Options → General Options → Library Configuration:Library 选择 Full(完整库,printf 才可用);
  3. 点击 Debug(Ctrl+D) 进入在线仿真调试会话(C-SPY 连接仿真器);
  4. 菜单 View → Terminal I/O 打开 IDE 界面上的 Terminal I/O 窗口;
  5. 全速运行程序,printf 辅助信息实时显示在该窗口。

代码改造:用 printf 打印 ​

把前面的串口打印函数改用 printf(输出到 Terminal I/O 窗口):

c
#include <stdio.h>

/* 用 printf 打印网络信息(输出到 IAR Terminal I/O 窗口) */
static void PrintNetworkInfoTF(uint8 *tag)
{
  uint16 panId   = _NIB.nwkPanId;              // 网络号
  uint8  channel = _NIB.nwkLogicalChannel;     // 信道
  uint16 addr    = NLME_GetShortAddr();        // 本节点短地址
  uint16 parent  = NLME_GetCoordShortAddr();   // 父节点地址

  printf("[%s] PAN:0x%04X CH:%d Addr:0x%04X Parent:0x%04X\r\n",
         tag, panId, channel, addr, parent);
}

入网成功处调用方式不变:

c
case ZDO_STATE_CHANGE:
  if (devState == DEV_ZB_COORD)
    PrintNetworkInfoTF("NETWORK UP");
  else if (devState == DEV_ROUTER || devState == DEV_END_DEVICE)
    PrintNetworkInfoTF("JOIN OK");
  break;

现象

进入调试后,Terminal I/O 窗口实时显示 [NETWORK UP] PAN:0xXXXX CH:X Addr:0x0000 / [JOIN OK] PAN:0xXXXX ...——这就是组网成功的"验收凭证"。

注意

  • Library 必须为 Full,否则 printf 不可用;
  • Terminal I/O 只在**在线仿真调试会话(Debug)**中显示,退出调试窗口内容清空;
  • 若同时接串口,HalUARTWrite 与 printf 可并存,两边都能看。

实验现象与检查点 ​

检查点期望现象(串口终端)
协调器上电[NETWORK UP] PAN:0xXXXX CH:X Addr:0x0000
路由器上电[JOIN OK] PAN:0xXXXX ... Parent:0x0000
终端上电[JOIN OK] PAN:0xXXXX ... Parent:0xXXXX(父节点=路由器)
三台 PAN ID完全相同
入网失败重连(若实现)失败后 1s 自动重试,成功时打印 JOIN OK

常见问题

  • 终端无打印:确认串口已初始化(波特率匹配)、HalUARTWrite 调用无误;部分板型需将板载串口拨码开关拨到 USB 侧;
  • PAN ID 不一致:确认附近无其他协调器抢占,或固定 ZDAPP_CONFIG_PAN_ID;
  • 打印乱码:PC 串口助手的波特率、数据位(8N1)与固件一致;
  • 看不到 JOIN OK:先给协调器上电建网,再给节点上电;必要时按协调器 Reset 键。

思考题 ​

  1. 为什么 NETWORK UP 的地址是 0x0000、父节点是 0xFFFF?协调器在 ZigBee 网络中扮演什么角色?
  2. 终端与路由器的 Parent 地址有何不同?这说明了什么网络拓扑关系?
  3. 如果 10 台设备同时入网,如何用终端打印快速确认"全部入网成功且 PAN ID 一致"?(提示:日志留存、PAN ID 过滤)
  4. 与 2.3 章节的 LCD 屏幕显示相比,串口终端打印有哪些优势?

实验报告要求 ​

  1. 说明本实验复用了 2.3 章节的哪些组网知识;
  2. 粘贴终端打印函数的代码及注释;
  3. 附三台设备的串口终端打印截图,标注 PAN ID / 信道 / 短地址 / 父节点;
  4. 填写网络参数记录表格并分析拓扑关系;
  5. 回答思考题;
  6. 写出遇到的问题及解决办法。

关联知识:2.3 ZigBee 3.0 组网实验、网络层、串口应用

aioteer · 物联网专业课程群

💬AI 伴学配置