本节内容主要说明广播和组播的工作过程,通过协调器节点发送数据到路由节点、终端节点,然后路由、终端节点把接收的数据通过串口显示到PC串口上位机。
开发板:使用七彩光子开发的ZigBee节点
编辑软件:IAR7.2 for 8051
上位机:XCOM
SampleApp.c
SampleApp.h
ZDApp.h
//以下为协调器过程=====================================================
1、初始化设备为协调器设备;初始化用户任务SampleApp_Init()。
2、网络状态发生改变,进入SampleApp_ProcessEvent(),用户任务处理函数。
3、进入系统事件–>网络状态改变事件,此过程一直循环,直到网络明确为止,即协调器建立网络成功、终端或路由加入网络成功(身份验证成功)。协调器网络过程889,路由2227,终端2226。
typedef enum
{
DEV_HOLD, // Initialized - not started automatically
DEV_INIT, // Initialized - not connected to anything
DEV_NWK_DISC, // Discovering PAN's to join
DEV_NWK_JOINING, // Joining a PAN
DEV_NWK_REJOIN, // ReJoining a PAN, only for end devices
DEV_END_DEVICE_UNAUTH, // Joined but not yet authenticated by trust center
DEV_END_DEVICE, // Started as device after authentication
DEV_ROUTER, // Device joined, authenticated and is a router
DEV_COORD_STARTING, // Started as Zigbee Coordinator
DEV_ZB_COORD, // Started as Zigbee Coordinator
DEV_NWK_ORPHAN // Device has lost information about its parent..
} devStates_t;
4、网络组建成功后,协调器启动定时器任务
if(SampleApp_NwkState == DEV_ZB_COORD)
{
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_SEND_PERIODIC_MSG_EVT, //定时触发的事件
SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT);
}
5、时间到后,出发用户任务处理函数,进入SAMPLEAPP_SEND_PERIODIC_MSG_EVT事件,执行SampleApp_SendFlashMessage(0)函数或 SampleApp_SendPeriodicMessage()函数。
// SampleApp_SendPeriodicMessage();
SampleApp_SendFlashMessage(0);
// Setup to send message again in normal period (+ a little jitter)
osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
(SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );
// return unprocessed events 返回未处理的事件
void SampleApp_SendFlashMessage( uint16 flashTime ) //组播发送
{
byte dat[10]="1234567890";
HalLedSet(HAL_LED_1,HAL_LED_MODE_OFF);
HalLedSet(HAL_LED_1,HAL_LED_MODE_BLINK);
if ( AF_DataRequest( &SampleApp_Flash_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_FLASH_CLUSTERID,
10,
dat,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
SampleApp_Flash_DstAddr:组播参数配置信息
SampleApp_epDesc:端点描述符
SAMPLEAPP_FLASH_CLUSTERID:传输事件
SampleApp_TaskID:任务ID
//以下为终端、路由过程===================================================
1、2、3与协调器一样的过程。
4、不需要定时周期的发送任务,故生成定时器任务。等待接收无线消息。
注:从协调器组播发送数据到终端时,ZigBee协议中有明确的规定,组播不能发送给maxRxOnWhenIdle等于FALSE的设备,而终端的这个属性默认是FALSE。在f8wconfig.cfg文件中,-DRFD_RCVC_ALWAYS_ON=FALSE改为TRUE。
5、接收消息,进入SampleApp_ProcessEvent()函数中SYS_EVENT_MSG系统事件,系统事件的接收数据事件AF_INCOMING_MSG_CMD,进入SampleApp_MessageMSGCB()函数。
6、数据处理
case SAMPLEAPP_FLASH_CLUSTERID: //收到组播数据
#if defined(ZDO_COORDINATOR)
//enter the coordinator program
#else
osal_memset(buf, 0 , 32);
osal_memcpy(buf, pkt->cmd.Data, 10);
HalUARTWrite(0,buf,10);
HalLedSet(HAL_LED_1,HAL_LED_MODE_OFF);
HalLedSet(HAL_LED_1,HAL_LED_MODE_BLINK);
#endif
break;
由于协调器节点,也是同一个组内的节点,故当协调器也下载此段代码时,协调器也会把接收的数据发送给上位机。为了达到实验效果,故区分设备操作。
总结:至此组播的整个通信过程已经完成。同理广播的也是整个过程,只不过,广播是使用的广播的配置参数信息。组播时,同一个组内的节点可以接收到消息,不同组内的节点接收不到消息,仅限于同一个网络。
扩展:加入组和退出组
aps_Group_t *grp;
grp = aps_FindGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
if ( grp )
{
// Remove from the group
aps_RemoveGroup( SAMPLEAPP_ENDPOINT, SAMPLEAPP_FLASH_GROUP );
HalUARTWrite(0,"Remove",strlen("Remove"));
}
else
{
// Add to the flash group
aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );
HalUARTWrite(0,"Add",strlen("Add"));
}
可以参考本例的实验代码。
https://download.csdn.net/download/qq_43443455/11052705
传输编号定义
#define SAMPLEAPP_PERIODIC_CLUSTERID 1 //广播传输编号
#define SAMPLEAPP_FLASH_CLUSTERID 2 //组播传输编号
一、 广播
1、广播参数配置
SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;//模式为广播
SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;//指定端点号
SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;//指定目的网络地址为广播地址
二、组播
1、组播参数配置
SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; //组寻址
SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; //指定端点号
SampleApp_Flash_DstAddr.addr.shortAddr = 0x0002;//SAMPLEAPP_FLASH_GROUP;//组号0x0001
2、添加组,并登记到APS层
SampleApp_Group.ID = 0x0001;//组号
osal_memcpy( SampleApp_Group.name, “Group 2”, 7 );//设定组名
aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );//把该组登记添加到APS中
三、其他重要配置
1、端点描述符参数配置
SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; //指定端点号
SampleApp_epDesc.task_id = &SampleApp_TaskID; //SampleApp 描述符的任务ID
SampleApp_epDesc.simpleDesc
= (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;//SampleApp简单描述符
SampleApp_epDesc.latencyReq = noLatencyReqs; //延时策略
2、注册端点,AF登记端点描述符
afRegister( &SampleApp_epDesc );