ZigBee组网学习笔记(七)--协议栈网络管理

ZigBee 协议栈网络管理内容主要是对新加入的设备节点的设备管理。
我们都知道每个 CC2530 芯片出厂时候都有一个全球唯一的 32 位 MAC 地址。


实验现象:
路由器(编号 1)、终端设备(编号 2)发送自己的定义的设备号给协调器,
协调器通过接收到的设备号判断设备类型,并且获取设备的短地址,通过串口打印出来。 

要实现协调器收集数据的功能,可以使用点播方式传输数据, 点播地址为协调器地址( 0x0000),
避免了路由器和终端之间的互传,减少网络数据拥塞。

在点播程序的基础上完成本实验。

==========================================
初始化串口(参考协议栈串口实验)

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); //(串口, 字符, 字符个数)  发送数据了。
==========================================
点播部分(参考网络通讯--点播)
1、
afAddrType_t SampleApp_Periodic_DstAddr;
afAddrType_t SampleApp_Flash_DstAddr;
按照格式在组播和广播下面添加自己的点播:
---------------
afAddrType_t   Point_To_Point_DstAddr;//点对点通信定义
---------------
2、
void SampleApp_Init( uint8 task_id ) 里面, 对 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;    //发给协调器
---------------
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 )
  {
  }
}
4、
在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();//此处替换成点播函数

6、
接收 ID 我们在原来基础上改成我们刚定义的 SAMPLEAPP_POINT_TO_POINT_CLUSTERID。
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;

7、
由于协调器不允许给自己点播,故周期性点播初始化时协调器不能初始化。
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 );
}
==========================================
---------------------------------------------------------------

发送方:修改SampleApp_SendPointToPointMessage()
SampleApp.c
void SampleApp_SendPointToPointMessage( void )
{
uint8 device;      //设备类型变量
if ( SampleApp_NwkState == DEV_ROUTER)
device=0x01;  //编号1表示路由器  
else if (SampleApp_NwkState == DEV_END_DEVICE)
device=0x02;  //编号2表示终端  
else
device=0x03;  //编号3表示出错
  
if ( AF_DataRequest( &Point_To_Point_DstAddr,  //发送设备类型编号   点播
                       &SampleApp_epDesc,
                       SAMPLEAPP_POINT_TO_POINT_CLUSTERID,
                       1,
                       &device,
                       &SampleApp_TransID,
                       AF_DISCV_ROUTE,
                       AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}


数据接收:
我们对接收到的数据进行判断,区分路由器和终端设备。然后在数据包中取出 16 位短地址。通过串口打印出来。
短地址在数据包里的存放位置。依次是 pkt--- srcAddr---shortAddr

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )

typedef struct
{
afAddrType_t  srcAddr;     /* Source Address, if endpoint is STUBAPS_INTER_PAN_EP,
                               it's an InterPAN message */
} afIncomingMSGPacket_t;

typedef struct
{
  union
  {
    uint16      shortAddr;
    ZLongAddr_t extAddr;
  } addr;
  afAddrMode_t addrMode;

} afAddrType_t;

SampleApp.cpp
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{

uint16  flashTime,  temp;
  
//16进制转ASCII码表
uint8 asc_16[16]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
                     
switch ( pkt->clusterId )
{
case SAMPLEAPP_POINT_TO_POINT_CLUSTERID:  
temp=pkt->srcAddr.addr.shortAddr; //读出数据包的16位短地址
if( pkt->cmd.Data[0]==1 ) //路由器        
HalUARTWrite(0,"ROUTER ShortAddr:0x",19); //提示接收到数据
if( pkt->cmd.Data[0]==2 ) //终端
HalUARTWrite(0,"ENDDEVICE ShortAddr:0x",22); //提示接收到数据 
     
/****将短地址分解,ASC码打印*****/
      HalUARTWrite(0,&asc_16[temp/4096],1);
      HalUARTWrite(0,&asc_16[temp%4096/256],1);
      HalUARTWrite(0,&asc_16[temp%256/16],1);
      HalUARTWrite(0,&asc_16[temp%16],1);      
      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;
}
}

将修改后的程序分别以协调器、路由器、终端的方式下载到 3 个 或以上设备,协调器连接到 PC 机。上电后每个设备往协调器发送自身编号,协调器通过串口打印出来。

利用同样的方法可以将 MAC 地址、 PANID 等读取出来。或者自行设定预定义节点编号进行网络管理。 

例如读取  PANID 
  panTemp= pkt->srcAddr.panId;

HalUARTWrite(0,"PAN ID:0x",9);
      HalUARTWrite(0,&asc_16[panTemp/4096],1);
       HalUARTWrite(0,&asc_16[panTemp%4096/256],1);
       HalUARTWrite(0,&asc_16[panTemp%256/16],1);
       HalUARTWrite(0,&asc_16[panTemp%16],1);
       HalUARTWrite(0,"\n",1);
 MAC 地址
pkt->srcAddr.addr.extAddr




  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃果冻不吐果冻皮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值