正常的控制命令等都是使用此网络地址
这个地址也叫短地址
设备入网时会向整个网络广播自己的长短地址,此时协调器可以从广播的数据包中拿到设备的长短地址
获取此地址的方法是读取Devic_annce数据包
方法如下
在系统初始化时注册ZOD消息
如下,第三行便是
#ifdef ZDO_COORDINATOR
zclGenericApp_InitUart();
ZDO_RegisterForZDOMsg ( zclGenericApp_TaskID, Device_annce );
bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);
#else
#endif
在系统任务中添加接收消息回调函数
#ifdef ZDO_COORDINATOR
case ZDO_CB_MSG:
zclGenericApp_processZDOMgs( (zdoIncomingMsg_t *)MSGpkt );
break;
#else
#endif
此部分添加位置如下图
然后便是编写回调函数
从zdoIncomingMsg_t结构体中可以看到device_annce数据包包含的内容
typedef struct
{
osal_event_hdr_t hdr;
zAddrType_t srcAddr;
uint8 wasBroadcast;
cId_t clusterID;
uint8 SecurityUse;
uint8 TransSeq;
uint8 asduLen;
uint16 macDestAddr;
uint8 *asdu;
uint16 macSrcAddr;
} zdoIncomingMsg_t;
其中结构体secAddr中包含的便是长短地址数据
如下
typedef struct
{
union
{
uint16 shortAddr;
ZLongAddr_t extAddr;
} addr;
byte addrMode;
} zAddrType_t;
此时只需在回到函数中定义相同类型数据并赋值此结构体相应成员即可获取长短地址,
但是这里有点问题,长地址虽然有定义但是设备貌似并没有进行发送,所以一直获取不到,
短地址是可以的
方法按如下
static void zclGenericApp_processZDOMgs(zdoIncomingMsg_t *pMsg)
{
switch ( pMsg->clusterID )
{
case Device_annce:
{
uint8 databuf[20];
uint16 shortAddr;
shortAddr = pMsg->srcAddr.addr.shortAddr;
printf("nwkID:%X\r\n",shortAddr);
uint8 i;
uint8 *xad;
uint8 IEEE_buf[Z_EXTADDR_LEN*2+1];
xad = aExtendedAddress+ Z_EXTADDR_LEN - 1;
for (i = 0; i < Z_EXTADDR_LEN*2; xad--)
{
uint8 ch;
ch = (*xad >> 4) & 0x0F;
IEEE_buf[i++] = ch + (( ch < 10 ) ? '0' : '7');
ch = *xad & 0x0F;
IEEE_buf[i++] = ch + (( ch < 10 ) ? '0' : '7');
}
IEEE_buf[Z_EXTADDR_LEN*2] = '\0';
sprintf(databuf,"%s@%x\r\n",IEEE_buf,shortAddr);
HalUARTWrite(HAL_UART_PORT_0,databuf,20);
break;
}
default:
break;
}
}
此时便可以从串口接收到设备入网时的短地址了,
协调器长地址与设备短地址使用@符号进行连接,最后在串口打印,这样上位机便可以区分设备是处于哪一个协调器网络下
同时可以使用短地址对网络内的指定设备进行控制
获取本机IEEE地址方法就有很多了此处省略