EFR32 ZDDC 设备开发

更新时间:
2023-08-09
下载文档

EFR32 ZDDC 设备开发

本文将介绍如何在 EFR32 上使用 ZDDC 协议和 ACOINFO ZigBee 通用设备应用规范开发一个能接入到 EdgerOS 的 ZigBee 智能设备。

硬件准备

EFR32 开发板

EFR32 是 Silicon lab 推出的同时集成 RF 射频收发器和 ARM Cortex M4 内核 MCU 的无线射频 SOC 解决方案。其主频为 40MHz,片上最高输出功率可达 20dBm(Sub1GHz:20dBm,2.4GHZ:19.5dBm)。内置 32KB RAM 和 256KB Flash。拥有丰富的外设资源,其射频部分可同时覆盖 2.4GHz 和 Sub1GHz 频段。

本实验使用的是一块画时科技的 EFR32 开发板,芯片型号为 EFR32MG21A020F768IM32 实物图如下所示:

软件准备

开发 EFR32 需要使用 Simplicity Studio IDE。

下载 IDE 软件包并安装

网盘链接:https://pan.baidu.com/s/1ZbmzPaex95f0cD4CHz4ztg 提取码:lvle

解压 SimplicityStudio-EmberZnet 6.7.8.0-WIN10.7z 文件到 D:\ ,进入 D:\v4 目录双击 studio.exe 打开 IDE ,

出现创建 workspace 失败,不需理会:

点击两次 OK 后会进入选择 workspace 界面,选择或创建 workspace 如下所示:

检查更新后主界面如下所示:

新建工程

点击 File > New > Project ,选择 Silicon Labs AppBuilder Project ,点击 Next 如下所示:

选择 Silicon Labs Zigbee 后点击 Next 如下所示:

选择 EmberZNet 6.7.8.0 GA SoC 6.7.8.0 后点击 Next 如下所示:

选择 ZigbeeMinimal 后点击 Next 如下所示:

设置 Project name 后点击 Next 如下所示:

选择 Part 为 EFR32MG21A020F768IM32 后点击 Finish 如下所示:

至此工程创建完成:

配置工程

选择 ZigbeeMinimalSoc.isc 文件中的 Zigbee Stack 选项,选择 Zigbee Device Type 为 End Device 如下所示:

复制附录中的 acoinfo 自定义 Cluster 扩展规范文件 acoinfo.xml ,拷贝到 D:\v4\developer\sdks\gecko_sdk_suite\v2.7\app\zcl 目录下,Zigbee Stack 选项中点击 Add... ,添加 acoinfo.xml 到工程中,如下所示:

选择 ZCL Clusters 选项,按照下图所示选择 HA On/Off Light :

选择 ZCL Clusters 选项,点击下方 General 中的 Basic 在右侧添加 manufacturer name 为 acoinfo.light.led ,model id 为 acoinfo.zigbee.generic 如下所示:

选择 General 中的 On/Off ,勾选 DIO 通道 1,如下所示:

选择 Lighting 中的 Color Control ,在右侧选择 acoinfo 自定义的六个 attribute ,修改 DIO 通道可用和可写以及 AIO 通道的可用的默认值为 0x00000001,如下所示:

勾选 ZLL 中的 ZLL Commissioning ,以及 acoinfo 中的 acoinfo_aio 中的 AIO 通道 1,如下所示:

选择 HAL 选项中的 Bootloader,设置为 None,如下所示:

选择 Callbacks 选项,选中 Main Init 选项、Hal Button Isr 选项以及 Server Attribute Changed 选项,如下所示:

选择 Includes 选项,点击 Add new 添加一个自定义事件,用于定期上报模拟量通道 1,Command 为 AcoinfoAioReportEventControl ,Callback 为 AcoinfoAioReportEventHandler ,如下所示:

保存后点击右上角 Generate 后会生成代码,如下所示:

双击 ZigbeeMinimalSoc_callbacks.c 文件,在文件末尾加入上面选中的 emberAfMainInitCallback,并延时调用周期上报 AIO 事件,如下所示:

void emberAfMainInitCallback(void)
{
    emberAfCorePrintln("---------------test---------------");
    emberEventControlSetDelayMS(AcoinfoAioReportEventControl, 10000);
}

在上述文件中加入周期上报 AIO 处理函数 AcoinfoAioReportEventHandler ,如下所示:

EmberEventControl AcoinfoAioReportEventControl;
void AcoinfoAioReportEventHandler(void)
{
    // 在下次使用之前禁用该事件
    emberEventControlSetInactive(AcoinfoAioReportEventControl);
  
    float data = 3.14;
    uint8_t * p_data = (uint8_t *)&data;
    uint8_t buf[7] = {0};
    buf[0] = ZCL_ACOINFO_ZB_AIO_ATTR_1_ATTRIBUTE_ID && 0xFF;
    buf[1] = ZCL_ACOINFO_ZB_AIO_ATTR_1_ATTRIBUTE_ID >> 8;
    buf[2] = ZCL_FLOAT_SINGLE_ATTRIBUTE_TYPE;
    for(int i=0;i<4;i++){
        buf[3+i] = *p_data++;
    }
    emberAfFillCommandGlobalServerToClientReportAttributes(ZCL_ACOINFO_ZB_AIO_CLUSTER_ID,
                                                           (uint8_t *)buf, 7);
    emberAfSetCommandEndpoints(1, 1);
    emberAfSendCommandUnicast(EMBER_OUTGOING_DIRECT, 0x0000);

    // 延迟 5 秒后重新触发事件
    emberEventControlSetDelayMS(AcoinfoAioReportEventControl, 5000);
}

在上述文件中加入监听 DIO 值变化回调函数,并加入开关 LED 灯的功能, 如下所示:

void emberAfOnOffClusterServerAttributeChangedCallback(int8u endpoint,
                                                       EmberAfAttributeId attributeId)
{
    EmberAfStatus status;
    uint8_t data[1];

      status = emAfReadAttribute(endpoint,
                                 ZCL_ON_OFF_CLUSTER_ID,
                                 attributeId,
                                 0x40,
                                 0x0000,
                                 data,
                                 1,
                                 NULL);
      if (status == EMBER_ZCL_STATUS_SUCCESS) {
          if(attributeId == ZCL_ACOINFO_ZB_DIO_ATTR_1_ATTRIBUTE_ID){
              if(data[0] == 0x01){
                  halSetLed(1);    // 开启 LED 灯
                  emberAfCorePrintln("led on");
              } else if(data[0] == 0x00) {
                  halClearLed(1); // 关闭 LED 灯
                  emberAfCorePrintln("led off");
              } else {
                  emberAfCorePrintln("data error");
              }
          }
      } else {
          emberAfCorePrintln("read attribute failed... status = %x", status);
      }
}

在上述文件中加入 BUTTON 监听回调函数,检测按下后开始配置入网,如下所示:

void emberAfHalButtonIsrCallback(uint8_t button, uint8_t state)
{
  if (state == BUTTON_RELEASED) {
      emberAfPluginNetworkSteeringStart();
  }
}

双击左侧 custom_efr32mg21a020f768im32.hwconf 文件后点击下方 DefaultMode Peripherals 选项来配置管脚:

根据开发板 Button 设置如下所示:

根据开发板 LED 设置如下所示:

设置日志输出配置如下所示:

取消勾选 Virtual COM Port :

设置 USART0 如下所示:

取消勾选 PTI:

保存后会生成相关硬件配置代码,点击编译生成二进制文件:

烧写镜像

使用 JLink 把开发板连接到 PC,如下所示:

点击右上角 Launcher 进入主页,再点击左侧工具图标,在弹出框中选择 Simplicity Commander 后点击 OK:

选择左侧第三个选项 Flash,然后依次点击上方 Adapter 和 Target 右边的 Connect 按键,点击 Browse 选择对应路径下的 Z3SwitchSoc.hex 文件,点击 Erase chip 擦除,点击 Flash 进行烧写,如下所示:

入网验证

验证前,请参考《 ZDDC 协议介绍》章节中的 ZigBee 设备入网流程,完成以下步骤:

1、进入扫描设备界面,如下图所示:

2、将 EFR32 开发板接入 PC,打开设备管理器,查看 PC 为 EFR32 开发板分配的 COM 号,如下图所示:

使用 PuTTY 作为串口调试工具,打开 PuTTY 进入 PuTTY Configuration 界面,选择 Session 类, Connection type 选择:Serial ,Serial line 为 EFR32 开发板接入 PC 后分配的 COM 号(如 COM23),Speed 设置为 115200,最后点击 Open 按键进入 PuTTY 终端:

3、开发板上电,按下 PD01 执行关联入网操作,串口打印结果如下图所示:

4、此时,EdgerOS 会发现新的设备,点击添加按钮完成新设备的添加:

附录

acoinfo.xml 文件

<configurator>
  <domain name="acoinfo" />
  <cluster>
    <name>acoinfo_aio</name>
    <domain>acoinfo</domain>
    <description>Acoinfo custom cluster</description>
    <code>0x000C</code> 
    <define>ACOINFO_ZB_AIO_CLUSTER</define>
    <client init="false" tick="false">true</client>
    <server init="false" tick="false">true</server>
    <attribute side="server" code="0x2000" define="ACOINFO_ZB_AIO_ATTR_1" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ATTR_1</attribute>
    <attribute side="server" code="0x2001" define="ACOINFO_ZB_AIO_ATTR_2" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ATTR_2</attribute>
    <attribute side="server" code="0x2002" define="ACOINFO_ZB_AIO_ATTR_3" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ATTR_3</attribute>
    <attribute side="server" code="0x2003" define="ACOINFO_ZB_AIO_ATTR_4" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ATTR_4</attribute>
    <attribute side="server" code="0x2004" define="ACOINFO_ZB_AIO_ATTR_5" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ATTR_5</attribute>
    <attribute side="server" code="0x2005" define="ACOINFO_ZB_AIO_ATTR_6" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ATTR_6</attribute>
    <attribute side="server" code="0x2006" define="ACOINFO_ZB_AIO_ATTR_7" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ATTR_7</attribute>
    <attribute side="server" code="0x2007" define="ACOINFO_ZB_AIO_ATTR_8" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ATTR_8</attribute>
  </cluster>

  <clusterExtension code="0x0006"> 
    <attribute side="server" code="0x2000" 
      define="ACOINFO_ZB_DIO_ATTR_1" 
      type="BOOLEAN" min="0x00" max="0x01" writable="true" 
      default="0x00" optional="true">ACOINFO_ZB_DIO_ATTR_1</attribute>
    <attribute side="server" code="0x2001" 
      define="ACOINFO_ZB_DIO_ATTR_2" 
      type="BOOLEAN" min="0x00" max="0x01" writable="true" 
      default="0x00" optional="true">ACOINFO_ZB_DIO_ATTR_2</attribute>
    <attribute side="server" code="0x2002" 
      define="ACOINFO_ZB_DIO_ATTR_3" 
      type="BOOLEAN" min="0x00" max="0x01" writable="true" 
      default="0x00" optional="true">ACOINFO_ZB_DIO_ATTR_3</attribute>
    <attribute side="server" code="0x2003" 
      define="ACOINFO_ZB_DIO_ATTR_4" 
      type="BOOLEAN" min="0x00" max="0x01" writable="true" 
      default="0x00" optional="true">ACOINFO_ZB_DIO_ATTR_4</attribute>
    <attribute side="server" code="0x2004" 
      define="ACOINFO_ZB_DIO_ATTR_5" 
      type="BOOLEAN" min="0x00" max="0x01" writable="true" 
      default="0x00" optional="true">ACOINFO_ZB_DIO_ATTR_5</attribute>
    <attribute side="server" code="0x2005" 
      define="ACOINFO_ZB_DIO_ATTR_6" 
      type="BOOLEAN" min="0x00" max="0x01" writable="true" 
      default="0x00" optional="true">ACOINFO_ZB_DIO_ATTR_6</attribute>
    <attribute side="server" code="0x2006" 
      define="ACOINFO_ZB_DIO_ATTR_7" 
      type="BOOLEAN" min="0x00" max="0x01" writable="true" 
      default="0x00" optional="true">ACOINFO_ZB_DIO_ATTR_7</attribute>
    <attribute side="server" code="0x2007" 
      define="ACOINFO_ZB_DIO_ATTR_8" 
      type="BOOLEAN" min="0x00" max="0x01" writable="true" 
      default="0x00" optional="true">ACOINFO_ZB_DIO_ATTR_8</attribute>
  </clusterExtension>
  
  <clusterExtension code="0x0300"> 
    <attribute side="server" code="0x2000" define="ACOINFO_ZB_DIO_ACTIVE_T_ATTR" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_DIO_ACTIVE_ATTR</attribute>
    <attribute side="server" code="0x2001" define="ACOINFO_ZB_DIO_WRITE_T_ATTR" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_DIO_WRITE_ATTR</attribute>
    <attribute side="server" code="0x2002" define="ACOINFO_ZB_AIO_ACTIVE_T_ATTR" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_ACTIVE_ATTR</attribute>
    <attribute side="server" code="0x2003" define="ACOINFO_ZB_AIO_WRITE_T_ATTR" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_AIO_WRITE_ATTR</attribute>
    <attribute side="server" code="0x2004" define="ACOINFO_ZB_MEM_ACTIVE_T_ATTR" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ACTIVE_ATTR</attribute>
    <attribute side="server" code="0x2005" define="ACOINFO_ZB_MEM_WRITE_T_ATTR" 
      type="INT32U"  min="0x00000000"   max="0xFFFFFFFF"   writable="true"  
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_WRITE_ATTR</attribute>
  </clusterExtension>
  
  <clusterExtension code="0x0500"> 
    <attribute side="server" code="0x2000" 
      define="ACOINFO_ZB_MEM_ATTR_1" 
      type="INT32U" min="0x00000000" max="0xFFFFFFFF" writable="true" 
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ATTR_1</attribute>
    <attribute side="server" code="0x2001" 
      define="ACOINFO_ZB_MEM_ATTR_2" 
      type="INT32U" min="0x00000000" max="0xFFFFFFFF" writable="true" 
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ATTR_2</attribute>
    <attribute side="server" code="0x2002" 
      define="ACOINFO_ZB_MEM_ATTR_3" 
      type="INT32U" min="0x00000000" max="0xFFFFFFFF" writable="true" 
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ATTR_3</attribute>
    <attribute side="server" code="0x2003" 
      define="ACOINFO_ZB_MEM_ATTR_4" 
      type="INT32U" min="0x00000000" max="0xFFFFFFFF" writable="true" 
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ATTR_4</attribute>
    <attribute side="server" code="0x2004" 
      define="ACOINFO_ZB_MEM_ATTR_5" 
      type="INT32U" min="0x00000000" max="0xFFFFFFFF" writable="true" 
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ATTR_5</attribute>
    <attribute side="server" code="0x2005" 
      define="ACOINFO_ZB_MEM_ATTR_6" 
      type="INT32U" min="0x00000000" max="0xFFFFFFFF" writable="true" 
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ATTR_6</attribute>
    <attribute side="server" code="0x2006" 
      define="ACOINFO_ZB_MEM_ATTR_7" 
      type="INT32U" min="0x00000000" max="0xFFFFFFFF" writable="true" 
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ATTR_7</attribute>
    <attribute side="server" code="0x2007" 
      define="ACOINFO_ZB_MEM_ATTR_8" 
      type="INT32U" min="0x00000000" max="0xFFFFFFFF" writable="true" 
      default="0x00000000" optional="true">ACOINFO_ZB_MEM_ATTR_8</attribute>
  </clusterExtension>
</configurator>
文档内容是否对您有所帮助?
有帮助
没帮助