点播,顾名思义就是点对点通信,也就是 2 个设备之间的通讯,不容许有第三个设备收到信息;
组播,就是把网络中的节点分组,每一个组员发出的信息只有相同组号的组员才能收到。
广播,最广泛的,也就是 1 个设备上发出的信息所有设备都能接收到。
一、点播(点对点通讯)
点播描述的就是网络中 2 个节点相互通信的过程。确定通信对象的就是节点的 16bit 短地址。
==========================================
初始化串口(参考协议栈串口实验)
1、
SampleApp.c
#include "MT_UART.h" //串口头文件引用
2、
SampApp.c
SampApp_Init()
SampApp_TransID() = 0;
MT_UartInit();
3、
void MT_UartInit()
uartConfig.baudRate =MT_UART_DEFAULT_BAUDRATE;
uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW;
#define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_115200 //38400
#define MT_UART_DEFAULT_OVERFLOW FALSE //TRUE
4、
用 ZTOOL,串口 0。我们可以在 option——C/C++ 的 CompilerPreprocessor 里面看到,已经默认添加 ZTOOL_P1 预编译。
5、
void SampleApp_Init( uint8 task_id )
MT_UartInit();
MT_UartRegisterTaskID(task_id);//登记任务号
至此,就可以使用
HalUARTWrite(0, "Hello,world\n", 12); //(串口, 字符, 字符个数) 发送数据了。
==========================================
Profile下
AF.h
typedef enum
{
afAddrNotPresent = AddrNotPresent,
afAddr16Bit = Addr16Bit, //点播方式 2
afAddr64Bit = Addr64Bit,
afAddrGroup = AddrGroup, //组播方式 1
afAddrBroadcast = AddrBroadcast /广播方式 15
} afAddrMode_t;
ZComDef.h
enum
{
AddrNotPresent = 0,
AddrGroup = 1,
Addr16Bit = 2,
Addr64Bit = 3,
AddrBroadcast = 15
};
SampleApp.c
afAddrType_t Point_To_Point_DstAddr;//自己定义点对点通信定义
可发现已经存在代码如下:
afAddrType_t SampleApp_Periodic_DstAddr;
afAddrType_t SampleApp_Flash_DstAddr;
分别是广播和组播前面的定义。
1---------------------------------------------
按照格式在组播和广播下面添加自己的点播:
afAddrType_t Point_To_Point_DstAddr;//点对点通信定义
--------------------------------------------------------------------
提示: go to definition of afAddrType_t 可以找到上面的枚举内容。
在SampleApp.c void SampleApp_Init( uint8 task_id ) 里面,
对 Point_To_Point_DstAddr 一些参数进行配置,找到下面的位置,
参考 SampleApp_Periodic_DstAddr 和 SampleApp_Flash_DstAddr 我们进行自己的配置
2--
------------------------------------------------------------------
void SampleApp_Init( uint8 task_id )
// 点对点通讯定义
Point_To_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//点播
Point_To_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
Point_To_Point_DstAddr.addr.shortAddr = 0x0000; //发给协调器
--------------------------------------------------------------------
enum
{
AddrNotPresent = 0,
AddrGroup = 1,
Addr16Bit = 2,
Addr64Bit = 3,
AddrBroadcast = 15
};
#define SAMPLEAPP_ENDPOINT 20
typedef struct
{
union
{
uint16 shortAddr;
ZLongAddr_t extAddr;
} addr;
afAddrMode_t addrMode;
uint8 endPoint;
uint16 panId; // used for the INTER_PAN feature
} afAddrType_t;
3-------------------------------------------------------------------
在SampleApp.c中
添加头文件声明 void SampleApp_SendPointToPointMessage( void );
定义该函数
void SampleApp_SendPointToPointMessage( void )
{
uint8 data[10]={'0','1','2','3','4','5','6','7','8','9'};
if ( AF_DataRequest( &Point_To_Point_DstAddr,
&SampleApp_epDesc,
SAMPLEAPP_POINT_TO_POINT_CLUSTERID, //点播传输编号
10,
data,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
4--------------------------------------------------------------------
之前定义过Point_To_Point_DstAddr。
在SampleApp.h中声明SAMPLEAPP_POINT_TO_POINT_CLUSTERID
#define SAMPLEAPP_MAX_CLUSTERS 3 //2
#define SAMPLEAPP_PERIODIC_CLUSTERID 1
#define SAMPLEAPP_FLASH_CLUSTERID 2
#define SAMPLEAPP_POINT_TO_POINT_CLUSTERID 3
5--------------------------------------------------------------------
周期性点播发送数据
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )
// Send the periodic message
//SampleApp_SendPeriodicMessage();//周期性发送函数
SampleApp_SendPointToPointMessage();//此处替换成点播函数
------------------------------------------------------------------
接收方面
接收 ID 我们在原来基础上改成我们刚定义的 SAMPLEAPP_POINT_TO_POINT_CLUSTERID。
1--------------------------------------------------------------------
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
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;
2--------------------------------------------------------------------
由于协调器不允许给自己点播,故周期性点播初始化时协调器不能初始化。
uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
case ZDO_STATE_CHANGE:
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 );
}
--------------------------------
将修改后的程序分别以协调器、路由器、终端的方式下载到 3 个节点设备中,连接串口。
可以看到只有协调器在一个周期内收到信息。
也就是说路由器和终端均与地址为 0x00(协调器)的设备通信,不与其他设备通信。实现点对点传输。