当前位置: 代码迷 >> 综合 >> ZigBee组网学习笔记(六)--网络通讯(点播)
  详细解决方案

ZigBee组网学习笔记(六)--网络通讯(点播)

热度:4   发布时间:2024-01-09 19:29:12.0
点播,顾名思义就是点对点通信,也就是 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(协调器)的设备通信,不与其他设备通信。实现点对点传输。