/***考试周,我抓紧把ZigBee的记录补一下,其实早就做了,被学院的事情耽搁了,博客一直没写,这两天给他补上************/
前言: Zigbee 的通讯方式主要有三种点播、组播、广播。点播,顾名思义就是点对点通信,也就是 2 个设备之间的通讯,不容许有第三个设备收到信息;组播,就是把网络中的节点分组,每一个组员发出的信息只有相同组号的组员才能收到。广播,最广泛的也就是 1 个设备上发出的信息所有设备都能接收到。这也是 ZigBee 通信的基本方式。
点播(点对点通讯)
点播描述的就是网络中 2 个节点相互通信的过程。确定通信对象的就是节点的 16bit 短地址。
首先,在AF.H文件中,可以看到这段代码
1 typedef enum
2 {
3 afAddrNotPresent = AddrNotPresent,
4 afAddr16Bit = Addr16Bit,
5 afAddr64Bit = Addr64Bit,
6 afAddrGroup = AddrGroup,
7 afAddrBroadcast = AddrBroadcast
8 } afAddrMode_t;
该类型是一个枚举类型:
当 addrMode= Addr16Bit 时,对应点播方式;
当 addrMode= AddrGroup 时,对应组播方式;
当 addrMode= AddrBroadcast 时,对应广播方式;
打开SampleApp.c加入点对点通信定义
afAddrType_t Point_To_Point_DstAddr;//点对点通信定义
//go to definition of afAddrType_t 可以找到刚才的枚举内容
对 Point_To_Point_DstAddr 一些参数进行配置 加入如下代码
// 点对点通讯定义
Point_To_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//点播
Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
Point_To_Point_DstAddr.addr.shortAddr = 0x0000; //发给协调器
第三行的意思是点播的发送对象是 0x0000,也就是协调器的地址。节点和协调器点对点通讯。
添加自己的点对点发送函数,在 SampleAPP.c 最后加入下面代码
void SampleApp_SendPointToPointMessage( void )
{
uint8 data[]="Hello Tian!";
if ( AF_DataRequest( &Point_To_Point_DstAddr,
&SampleApp_epDesc,
SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
sizeof(data),
data,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
/***********************添加完之后记得在SampleApp.c文件开头添加函数声明****************/
加入 SAMPLEAPP_POINT_TO_POINT_CLUSTERID 的定义如所示:
#define SAMPLEAPP_POINT_TO_POINT_CLUSTERID 3//传输编号
添加接收函数
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
uint16 flashTime;
switch ( pkt->clusterId )
{
case SAMPLEAPP_POINT_TO_POINT_CLUSTERID:
HalUARTWrite(0,"I get data\n",11);//用于提示有数据
HalUARTWrite(0, &pkt->cmd.Data[0],10); //打印收到数据
HalUARTWrite(0,"\n",1); //回车换行,便于观察
break;
case SAMPLEAPP_FLASH_CLUSTERID:
flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
break;
}
}
注册周期发送事件
SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
if ( //(SampleApp_NwkState == DEV_ZB_COORD)|| //协调器不给自己点播
(SampleApp_NwkState == DEV_ROUTER)
|| (SampleApp_NwkState == DEV_END_DEVICE) )
{
// Start sending the periodic message in a regular interval.
osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
}
else
{
// Device is no longer in the network
}
/*由于协调器不允许给自己点播,故周期性点播初始化时协调器不能初始化*/
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
{
SampleApp_SendPointToPointMessage();//周期性发送函数
// 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
return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
}
将修改后的程序分别以协调器、路由器、终端的方式下载到 3 个节点设备中,连接串口。可以看到只有协调器在一个周期内收到信息。也就是说路由器和终端均与地址为 0x00(协调器)的设备通信,不与其他设备通信。实现点对点传输。