多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
>[success] 导师视频讲解:[**去听课**](https://www.bilibili.com/video/BV1k34y1D7Vz?p=39) >[success] **技术支持说明:** >**1**.一般以自主学习为主 > **2**.可到官方问答社区中提问:[**去提问**](https://bbs.csdn.net/forums/zigbee) > **3**.工程师**会尽快**解答社区问题,但他们是一线开发,【**难以保证**】解答时效,解答辛苦,感谢理解! <br/> ## **实验简介** 在学习完AF层通信API后,本章将以实验的方式讲解如何使用这些API,实验设备包含一个协调器和一个路由器(或终端),内容是: 1. 路由器(或终端)定时地通过点对点的方式向协调器发送数据。 2. 让路由器(或终端)加入到一个组中。 3. 协调器定时地发送广播数据和组播数据。 <br/> ## **设备初始化** 打开配套的SampleSwitch工程代码,在zcl\_samplesw.c文件中的应用层初始化函数zclSampleSw\_Init()的末尾,添加以下代码: ``` #ifdef ZDO_COORDINATOR bdb_StartCommissioning( BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING ); NLME_PermitJoiningRequest(255); // Broadcast osal_start_timerEx(zclSampleSw_TaskID, SAMPLEAPP_BROADCAST_EVT, SAMPLEAPP_BROADCAST_PERIOD); // groupcast osal_start_timerEx(zclSampleSw_TaskID, SAMPLEAPP_GROUPCAST_EVT, SAMPLEAPP_GROUPCAST_PERIOD); #else bdb_StartCommissioning( BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING ); // Add group aps_Group_t group = { .ID = GROUP_ID, .name = "", }; aps_AddGroup(SAMPLESW_ENDPOINT, &group); // P2P osal_start_timerEx(zclSampleSw_TaskID, SAMPLEAPP_P2P_EVT, SAMPLEAPP_P2P_PERIOD); #endif ``` 添加后如图所示。 ![](https://img.kancloud.cn/5f/5e/5f5e5e8219fcae38fe0f7f1af59ab4c2_1680x1007.png =500x) ### **协调器角色初始化** 在协调器角色下,首先调用了bdb\_StartCommissioning()创建一个ZigBee网络,然后调用NLME\_PermitJoiningRequest(255)允许其他设备加入到这个网络中。接着调用osal_start_timerEx()产生了一个广播事件和组播事件。其中的事件和对应的事件周期的定义在zcl_samplesw.h文件中,代码如下: ``` //广播事件 #define SAMPLEAPP_BROADCAST_EVT 0x0080 #define SAMPLEAPP_BROADCAST_PERIOD 5000 //组播事件 #define SAMPLEAPP_GROUPCAST_EVT 0x0100 #define SAMPLEAPP_GROUPCAST_PERIOD 3000 ``` <br/> **终端(或路由器角色)初始化** 在终端(或路由器)角色下,首先调用了bdb\_StartCommissioning()加入ZigBee网络,然后创建一个组,创建一个组的代码如下: ``` // Add group aps_Group_t group = { .ID = GROUP_ID, .name = "", }; ``` 其中的GROUP\_ID的定义同样在zcl\_samplesw.c文件中,代码如下: ``` // GroupId #define GROUP_ID 21 ``` ### 接着调用aps\_AddGroup()加入到这个组中,代码如下: ``` aps_AddGroup( SAMPLESW_ENDPOINT,//端点号 &group);//待加入的组 ``` 最后,调用osal\_start\_timerEx()启动一个点对点通信事件,这个事件和事件周期的定义在zcl_samplesw.h文件中,代码如下: ``` // P2P #define SAMPLEAPP_P2P_EVT 0x0100 #define SAMPLEAPP_P2P_PERIOD 3000 ``` <br/> ## **协调器的事件处理** 应用层初始化函数zclSampleSw\_Init()中,协调器角色设备产生了一个广播事件SAMPLEAPP_BROADCAST_EVT 和一个组播事件SAMPLEAPP_GROUPCAST_EVT,因此需要编写对应的事件处理代码。 ### 在zcl\_samplesw.c文件中的应用层事件处理函数zclSampleSw\_event\_loop()添加对应的事件处理代码: ``` // Broadcast event if ( events & SAMPLEAPP_BROADCAST_EVT ) { zclSampleSw_AF_Broadcast(CLUSTER_BROADCAST, 10, "Broadcast"); osal_start_timerEx(zclSampleSw_TaskID, SAMPLEAPP_BROADCAST_EVT, SAMPLEAPP_BROADCAST_PERIOD); return ( events ^ SAMPLEAPP_BROADCAST_EVT ); } // Groupcast event if ( events & SAMPLEAPP_GROUPCAST_EVT ) { zclSampleSw_AF_Groupcast(GROUP_ID, CLUSTER_GROUPCAST, 10, "Groupcast"); osal_start_timerEx(zclSampleSw_TaskID, SAMPLEAPP_GROUPCAST_EVT, SAMPLEAPP_GROUPCAST_PERIOD); return ( events ^ SAMPLEAPP_GROUPCAST_EVT ); } ``` 添加后如图所示。 ![](https://img.kancloud.cn/4a/6a/4a6ab3eff6861cc75fbe298419edddc2_1680x1008.png =500x) ### 在广播事件处理中,首先调用了zclSampleSw\_AF\_Broadcast()发送一个广播信息,代码如下: ``` zclSampleSw_AF_Broadcast( CLUSTER_BROADCAST,//Cluster ID 10,//待发送数据的长度 "Broadcast");//待发送数据的内容 ``` ### 接着再次调用osal\_start\_timerEx()重新产生一个广播事件。 ### 组播事件的处理也是类似的,同样是调用zclSampleSw\_AF\_Broadcast()发送一个组播,然后调用osal\_start\_timerEx()重新产生一个组播事件。 ### 其中的CLUSTER\_BROADCAST和CLUSTER\_GROUPCAST,再加上在下文将会讲到的CLUSTER_P2P都是Cluster ID,是由笔者自定义的,代码如下: ``` #define CLUSTER_P2P 0 #define CLUSTER_BROADCAST 1 #define CLUSTER_GROUPCAST 2 ``` 可以看到这3个Cluster ID本质上就是一个宏定义,并且它的值就是0、1和2。 <br/> ## **终端(或路由器)的事件处理** 应用层初始化函数zclSampleSw\_Init()中,终端(或路由器)角色设备产生了一个点对点通信事件,因此需要编写对应的事件处理代码。 ### 在zcl\_samplesw.c文件中的应用层事件处理函数zclSampleSw\_event\_loop()添加对应的事件处理代码。 ``` // P2P Event if ( events & SAMPLEAPP_P2P_EVT ) { zclSampleSw_AF_P2P(0x0000, CLUSTER_P2P, 4, "P2P"); osal_start_timerEx(zclSampleSw_TaskID, SAMPLEAPP_P2P_EVT, SAMPLEAPP_P2P_PERIOD); return ( events ^ SAMPLEAPP_P2P_EVT ); } ``` 添加后如图所示。 ![](https://img.kancloud.cn/97/ab/97ab920e284d450a804c18ebb5ccc0f2_1680x990.png =500x) ### 在点对点通信事件处理中,首先调用了zclSampleSw\_AF\_Broadcast()发送一个点对点信息,代码如下: ``` zclSampleSw_AF_P2P( 0x0000,//目标设备的网络地址 CLUSTER_P2P,//Cluster ID 4,//待发送数据的长度 "P2P");//待发送数据的内容 ``` 其中的网络地址0x0000是协调器的网络地址。跟广播和组播事件处理类似,在发送数据之后,调用osal_start_timerEx()重新产生一个点对点通信事件。 <br/> ## **接收和处理数据** 前面讲解了如何发送数据,接下来讲解如何接收数据。ZigBee设备在组网成功之后,接收到数据时会产生一个系统事件AF\_INCOMING\_MSG\_CMD表示现在接收到数据了。 ### 打开zcl\_samplesw.c文件,可以找到一个应用层事件处理函数zclSampleSw\_event\_loop(),如图所示。 ![](https://img.kancloud.cn/f9/66/f96646ddaa894e451e82a0ba6259d53b_1680x1010.png =500x) ### 可以看到,系统事件处理代码中已经包含了对系统事件AF\_INCOMING\_MSG\_CMD的识别了,开发者只需要在接收到这个事件后进行相应的处理就可以了。 ### 笔者已经定义一个数据处理函数zclSampleSw\_AF\_RxProc()来处理接收到的数据了,代码如下: ``` /* * @param MSGpkt 接收到数据 */ static void zclSampleSw_AF_RxProc(afIncomingMSGPacket_t *MSGpkt) { /*计数器,记录接收到的点对点通信数据包个数*/ static uint8 p2pCnt = 0; /*计数器,记录接收到的广播通信数据包个数*/ static uint8 bcCnt = 0; /*计数器,记录接收到的组播通信数据包个数*/ static uint8 gcCnt = 0;   switch( MSGpkt->clusterId )  // 判断接收到的数据包的Cluster ID,后续章节将会详细讲解Cluster ID {   case CLUSTER_P2P: p2pCnt++;  // 接收到P2P数据包,进行计数 // 把接收到的数据和计数器的值显示在屏幕上 HalLcdWriteStringValue((char *)MSGpkt->cmd.Data,p2pCnt,10,3); break;     case CLUSTER_BROADCAST:   bcCnt++;  // 接收到广播数据包,进行计数 HalLcdWriteStringValue((char *)MSGpkt->cmd.Data,bcCnt,10,3);   break;     case CLUSTER_GROUPCAST:   gcCnt++;  // 接收到组播数据包,进行计数 HalLcdWriteStringValue((char *)MSGpkt->cmd.Data,gcCnt,10,4);   break;   default:   break;   }   } ``` ### 代码中用到了之前定义的3个Cluster ID,它们可以用来标识利用不同的通信方式发送过来的数据包,含义如下: ### * CLUSTER_P2P:在P2P通信方式时发送 * CLUSTER_BROADCAST:在广播通信方式时发送 * CLUSTER_GROUPCAST:在组播方式时发送 <br/> ## **仿真调试** 1.选择RouterEB(或者EndDeviceEB)角色编译工程,并把固件下载到标准板中。 ### 2.选择CoordinatorEB角色编译工程,并把固件下载到Mini板中。 ### 3.给Mini板上电后,Mini板即会自动创建网络。 ### 3.给标准板上电后,即会自动加入到由Mini板创建网络中。 ### 4.Mini板和标准板均会接收到数据包,如图所示。 * Mini板 ![](https://img.kancloud.cn/d4/a6/d4a6b4447f5207b1ac8970462bf2adaa_286x276.png =150x) ### * 标准板 ![](https://img.kancloud.cn/47/b2/47b20a1728ae36b4340aa7e41414fef1_734x294.png =300x) <br/> <br/> ## **项目定制** * 如需项目定制开发,可扫码添加项目经理好友(注明“**项目定制**”) * 定制范围:**NB-IoT**、**CATn(4G)**、**WiFi**、**ZigBee**、**BLE Mesh**以及**STM32**、**嵌入式Linux**等IoT技术方案 * 善学坊官网:[www.sxf-iot.com](https://www.sxf-iot.com/) ![](https://img.kancloud.cn/ca/73/ca739f92cab220a3059378642e3bd502_430x430.png =200x) * 非项目定制**勿扰**,此处**非**技术支持