Zigbee3.0组网(基于CC2530芯片)
3.0协议栈不同于2.5
3.0协议栈里面入网机制进行了改变,虽然底层入网还是一样,但是上层应用变得更简单
使用宏是为了代码复用,用于区分协调器还是终端设备
此初始化函数放在应用层初始化里面
如下函数
void zclGenericApp_Init( byte task_id )
协调器在初始化中添加BDB层初始化,以及创建网络
类似于这样
#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
此时如果协调器正常初始化完成,则已经创建好了网络
但是并没有允许设备加入
需要调用函数允许设备入网,参数位允许时间,正常应用开发中也是这样操作,避免不同网关之间入网冲突
在我代码中我是采用了按键入网,按键按下后执行此函数,并闪烁指示灯
NLME_PermitJoiningRequest(255);
按键操作如下,同样使用宏来区分协调器与终端设备
协调器按下按键后执行允许入网操作并闪灯
终端设备按下按键后执行寻找网络并加入网络操作
闪烁指示灯并在调试窗口打印设备IEEE地址
static void zclGenericApp_HandleKeys( byte shift, byte keys )
{
if(keys & HAL_KEY_SW_6)
{
#ifdef ZDO_COORDINATOR
// bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);
NLME_PermitJoiningRequest(255);
#else
bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_FINDING_BINDING);
uint8 i;
uint8 *xad;
uint8 lcd_buf[Z_EXTADDR_LEN*2+1];
// Display the extended address.
xad = aExtendedAddress + Z_EXTADDR_LEN - 1;
for (i = 0; i < Z_EXTADDR_LEN*2; xad--)
{
uint8 ch;
ch = (*xad >> 4) & 0x0F;
lcd_buf[i++] = ch + (( ch < 10 ) ? '0' : '7');
ch = *xad & 0x0F;
lcd_buf[i++] = ch + (( ch < 10 ) ? '0' : '7');
}
lcd_buf[Z_EXTADDR_LEN*2] = '\0';
printf("%s\r\n",lcd_buf);
#endif
printf("key_down\r\n");
HalLedBlink(HAL_LED_1, 10, 50, 400);
}
}
此处需要注意的是建立网络与入网操作的函数
此函数为bdb层对底层的封装,继承了建网,入网,绑定等主要功能,无需用户层再进行复杂建网,绑定等操作
bdb_StartCommissioning(uint8 mode);
函数参数分别有四种模式,如下图(截图自Z-Stack3.0API手册)
第一种模式为Touchlink
大致意思就是近距离组网,两个设备离得很近的时候按下按键,系统会自动检测信号强度,判断距离,足够近就进行组网绑定
第二个参数为网络操作,强制使用,有两种状态
1.如果设备已经在网络中,那么打开允许入网标志(只有路由器可以打开),允许入网标志指的是一个设备是否允许其他设备通过他加入网络,允许入网一般会有个时间周期,比如60秒,时间到了后就关闭该标志!
2.如果设备没有在网络中,那么尝试寻找一个合适的网络加入,如果加入成功,那么打开允许入网标志。
第三个是建立网络,协调器用的。
第四个是发现并绑定网络,终端设备用的
在这里我代码中只使用了后两个,即创建网络与发现绑定网络
使用案例在上面按键回调函数中已经提及,这里就不再重复
创建并加入网络后,程序就已经完成1/3了
上位机或服务器想对终协调器,终端设备进行控制,便需要用到转口通信,这部分先不写