精简!只讲用户层代码处理逻辑,全程干货无废话,可跟着一步一步配置。
实验现象:协调器板和终端板同时上电组网,组网成功后终端LED灯闪烁。
实验准备:
硬件:两块CC2530开发板
软件:IAR 10以上版本,Zstack 3.0协议包
需要Zstack 3.0协议包或者源码可以在评论区留言或私信我-
按照路径打开Z-Stack 3.0.2\Projects\zstack\HomeAutomation\SampleSwitch\CC2530DB下的SampleSwitch.eww工程。
1.了解组网API函数(重要):
组网函数
bdb_StartCommissioning(uint8 mode)
三种重要的形参在bdb.h文件中定义:
#define BDB_COMMISSIONING_MODE_NWK_STEERING (1<<1)
//加入中心网络模式,通常在协调器中使用
#define BDB_COMMISSIONING_MODE_NWK_FORMATION (1<<2)
//建立中心网络模式,通常在协调器或路由器中使用
#define BDB_COMMISSIONING_MODE_FINDING_BINDING (1<<3)
//绑定与发现功能
网络状态函数
zclSampleSw_ProcessCommissioningStatus(bdbCommissioningModeMsg_t *bdbCommissioningModeMsg)
(下文会提到,知道怎么用就行了)
2.开始组网
打开应用层文件zcl_samplesw.c,在初始化函数zclSampleSw_Init()里添加:
#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 );
#endif
我们可以看到,当我们选择协调器烧写的话,bdb_StartCommissioning函数调用的是BDB_COMMISSIONING_MODE_NWK_FORMATION参数,#ifdef的意思是如果是协调器则创建网络。当我们选择终端烧写的话,调用BDB_COMMISSIONING_MODE_NWK_STEERING加入网络。
其中的NLME_PermitJoiningRequest(255)是允许其他设备加入到由本协调器创建的网络中。
afStatus_t NLME_PermitJoiningRequest(uint8 duration);
- 参数说明:
duration
: 该参数决定了允许设备加入网络的时间长度。具体含义如下:0x00
: 禁止任何设备加入网络。0x01
到0xFE
: 允许设备加入网络的时间(以秒为单位)。例如,0x10
表示允许加入网络 16 秒。0xFF
: 永久允许设备加入网络
那我们如何使编译器知道我们烧写的是协调器还是终端代码呢?
在左上角这里选择CoordinatorEB是协调器,EndDeviceEB是终端。
当选择CoordinatorEB时可以发现 ,Tools目录下的f8wEnde.cfg文件变成灰色了,里面有关EndDevice终端的宏定义失效,以此来区分。
3.组网成功提醒
在zcl_samplesw.h中定义两个用户事件:
#define SAMPLEAPP_TEST_EVT 0x0040 //LED闪烁事件
#define SAMPLEAPP_REJOIN_EVT 0x0050 //重新加入网络事件
LED事件作为组网成功的提示,另一个作为加入网络失败后重新加入的事件
回到zcl_samplesw.c文件中。
找到zclSampleSw_ProcessCommissioningStatus()网络状态函数
我们的需求是如果创建成功,开启LED闪烁事件,如果失败,开启重新加入网络事件,两个事件号我们刚才在h文件中定义过了哦。
添加在case BDB_COMMISSIONING_NWK_STEERING:
if(bdbCommissioningModeMsg->bdbCommissioningStatus == BDB_COMMISSIONING_SUCCESS) //组网成功
{
#ifdef ZDO_COORDINATOR
//在协调器中我们不作显示
#else
//在终端中我们让LED闪烁
osal_start_timerEx(zclSampleSw_TaskID,
SAMPLEAPP_TEST_EVT,
1000); //LED灯闪烁事件,触发时间1S
#endif
}
else
{
#ifdef ZDO_COORDINATOR
//协调器中不做处理
#else
osal_start_timerEx(zclSampleSw_TaskID,
SAMPLEAPP_REJOIN_EVT,
1000
); //让终端重新加入网络
#endif
}
接着我们要在我们的事件中做具体实现了。
找到zclSampleSw_event_loop()函数
在里面添加:
if(events & SAMPLEAPP_TEST_EVT)
{
HalLedBlink(HAL_LED_1,3,50,1000);
return ( events ^ SAMPLEAPP_TEST_EVT);
} //LED灯闪烁事件的具体实现
#ifdef ZDO_COORDINATOR
#else
if( events & SAMPLEAPP_REJOIN_EVT )
{
bdb_StartCommissioning( BDB_COMMISSIONING_MODE_NWK_STEERING |
BDB_COMMISSIONING_MODE_FINDING_BINDING );
return ( events ^ SAMPLEAPP_REJOIN_EVT );
} //终端重新加入网络事件的具体实现
#endif
其中HalLedBlink()是ZStack协议下HAL库封装好的LED灯闪烁代码.
参数1.LED灯端口选择 参数2.闪烁次数 参数3.占空比 参数4.间隔时间
LED灯端口选择我们需要在 hal_board_cfg.h文件中进行软硬件的对接.
我的开发板,LED1接在了P1_0端口
查看hal_board_cfg.h文件中的定义:
配置无误,如果您的LED端口接在P1_2请修改为BV(2) P1_2以此类推
分别把两个开发板选择CoordinatorEB协调器,EndDeviceEB终端烧写。
可以看到终端复位后,加入网络成功,触发LED1闪烁三次.
ZIGBEE组网成功