如何在协议栈中构建自己的 Zigbee 网络指示灯
2017-09-09 16:21
267 查看
这篇文章主要讲解,如何构建自己的网络指示灯,实现设备在网时亮灯,脱网时灭灯这个效果。
解决这个问题主要分两个步骤:
1)建立指示灯的底层驱动代码。
2)替换掉官方的网络指示灯应用代码。
一、建立指示灯底层驱动代码
这个太简单了,不多解释,只贴代码。
LED.c 文件
二、替换掉官方的网络指示灯应用代码
在 Zigbee 官方的协议栈中也有网络指示灯的功能,其应用现象是协调器形成局域网失败时,网络指示灯闪烁,协调器形成局域网后,网络指示灯常亮;路由器和终端节点在未入网时,网络指示灯闪烁,入网后,网络指示灯常亮。其中终端节点在失去其父节点,重新请求入网时,网络指示灯会闪烁,当然这种情况就可以看做终端节点已经脱离网络了。
Zigbee 官方的协议栈中,网络指示灯使用的端口是 P1_4。顺着这个线索我们来看看 Z-STACK 的代码吧。
我们可以在协议栈中搜索“P1_4”关键字,可以看到:
“Hal_board_cfg.h”文件和“Mac_radio_defs.c”文件都用到了“P1_4”。我们先来看看“Hal_board_cfg.h”文件。
“Hal_board_cfg.h”:
在这里可以看出 P1_4 引脚是官方开发板上 LED3 的驱动引脚。
我们再看下“Mac_radio_defs.c”文件。
“Mac_radio_defs.c”:
这里的 P1_4 被用作 PA CC2591 和 CC2590 的引脚。所以当你添加“HAL_PA_LNA”之类的预编译来开启PA功能时,协议栈原本的网络指示灯就不能用了,这时候我们就要将网络指示灯改为别的IO口操作。
现在我们就顺着 LED3 的线索来看看 LED3 在哪些地方有应用。我们在协议栈中搜索“HAL_LED_3”可以看到有这几处应用了 LED3:
我们在查看上面的每一个文件后可以发现网络指示灯的关键代码在“ZDApp.c”的3个函数当中。
1)ZDO_NetworkFormationConfirmCB()
我们可以在这个函数中添加自己的网络指示灯应用代码。更改代码如下:
2)ZDO_StartRouterConfirmCB()
更改程序如下:
其修改代码如下:
在上面三个函数中添加自己的应用代码就能实现自己的网络指示灯应用功能了,如有疑问或补充,可在博客下方留言哦。
解决这个问题主要分两个步骤:
1)建立指示灯的底层驱动代码。
2)替换掉官方的网络指示灯应用代码。
一、建立指示灯底层驱动代码
这个太简单了,不多解释,只贴代码。
LED.c 文件
/******************************************************************** * * 文件名:LED.c * * 文件描述:指示灯驱动文件 * * 创建人:Jesse_黄嘉伟;QQ:3524999324 * * 版本号: * * 修改记录: * ********************************************************************/ #include <iocc2530.h> #include "LED.h" /********************************************************************* * MACROS */ /********************************************************************* * CONSTANTS */ /********************************************************************* * TYPEDEFS */ /********************************************************************* * GLOBAL VARIABLES */ /********************************************************************* * GLOBAL FUNCTIONS */ /********************************************************************* * LOCAL VARIABLES */ /********************************************************************* * LOCAL FUNCTIONS */ /********************************************************************* * EXTERN VARIABLES */ /********************************************************************* * EXTERN FUNCTIONS */ /************************************************************************ * 函数名:void Init_IndicatorLight(void) * 功能:初始化指示灯 * 参数:none * 返回值:none * 调用函数:none * 引用全局变量:none * 函数全局变量:none * 作者:黄嘉伟 * 时间:2017/2/18 * 最后修改时间: * 说明: *************************************************************************/ void Init_IndicatorLight(void) { // 网络指示灯 P0_7;入网时亮,未入网时灭;低电平亮,高电平灭 P0SEL &= ~(1<<7); // 通用IO口 P0DIR |= (1<<7); // IO口方向输出 CLOSE_NWKLIGHT(); // 指示灯灭 } /************************************************************************ * 函数名:void Control_IndicatorLight(uint8_t light, uint8_t state) * 功能:控制指示灯亮灭 * 参数: light:指示灯 state:指示灯状态 * 返回值:none * 调用函数:none * 引用全局变量:none * 函数全局变量:none * 作者:黄嘉伟 * 时间:2017/2/18 * 最后修改时间: * 说明: *************************************************************************/ void Control_IndicatorLight(uint8 light, uint8 state) { switch(light) { case LIGHT_NEK: { if(state==LIGHT_ON) { OPEN_NWKLIGHT(); } if(state==LIGHT_OFF) { CLOSE_NWKLIGHT(); } } break; default: break; } }LED.h 文件
/******************************************************************** * * 文件名:LED.c * * 文件描述:指示灯驱动文件 * * 创建人:Jesse_黄嘉伟;QQ:3524999324 * * 版本号: * * 修改记录: * ********************************************************************/ #ifndef __LED_H #define __LED_H #include "ZComDef.h" /********************************************************************* * MACROS */ // 指示灯 IO 口 #define NEKLIGHT P0_7 // 指示灯类型 #define LIGHT_NEK 0x01 // 指示灯状态 #define LIGHT_ON 0x01 #define LIGHT_OFF 0x00 #define OPEN_NWKLIGHT() (NEKLIGHT=0) #define CLOSE_NWKLIGHT() (NEKLIGHT=1) /********************************************************************* * CONSTANTS */ /********************************************************************* * TYPEDEFS */ /********************************************************************* * VARIABLES */ /********************************************************************* * FUNCTIONS */ void Init_IndicatorLight(void); void Control_IndicatorLight(uint8 light, uint8 state); #endif
二、替换掉官方的网络指示灯应用代码
在 Zigbee 官方的协议栈中也有网络指示灯的功能,其应用现象是协调器形成局域网失败时,网络指示灯闪烁,协调器形成局域网后,网络指示灯常亮;路由器和终端节点在未入网时,网络指示灯闪烁,入网后,网络指示灯常亮。其中终端节点在失去其父节点,重新请求入网时,网络指示灯会闪烁,当然这种情况就可以看做终端节点已经脱离网络了。
Zigbee 官方的协议栈中,网络指示灯使用的端口是 P1_4。顺着这个线索我们来看看 Z-STACK 的代码吧。
我们可以在协议栈中搜索“P1_4”关键字,可以看到:
“Hal_board_cfg.h”文件和“Mac_radio_defs.c”文件都用到了“P1_4”。我们先来看看“Hal_board_cfg.h”文件。
“Hal_board_cfg.h”:
在这里可以看出 P1_4 引脚是官方开发板上 LED3 的驱动引脚。
我们再看下“Mac_radio_defs.c”文件。
“Mac_radio_defs.c”:
这里的 P1_4 被用作 PA CC2591 和 CC2590 的引脚。所以当你添加“HAL_PA_LNA”之类的预编译来开启PA功能时,协议栈原本的网络指示灯就不能用了,这时候我们就要将网络指示灯改为别的IO口操作。
现在我们就顺着 LED3 的线索来看看 LED3 在哪些地方有应用。我们在协议栈中搜索“HAL_LED_3”可以看到有这几处应用了 LED3:
我们在查看上面的每一个文件后可以发现网络指示灯的关键代码在“ZDApp.c”的3个函数当中。
1)ZDO_NetworkFormationConfirmCB()
/********************************************************************* * @fn ZDO_NetworkFormationConfirmCB * * @brief This function reports the results of the request to * initialize a coordinator in a network. * * @param Status - Result of NLME_NetworkFormationRequest() * * @return none */ void ZDO_NetworkFormationConfirmCB( ZStatus_t Status ) { nwkStatus = (byte)Status; if ( Status == ZSUCCESS ) { // LED on shows Coordinator started HalLedSet ( HAL_LED_3, HAL_LED_MODE_ON ); // 组网成功,点亮网络指示灯 // LED off forgets HOLD_AUTO_START HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF); #if defined ( ZBIT ) SIM_SetColor(0xd0ffd0); #endif if ( devState == DEV_HOLD ) { // Began with HOLD_AUTO_START devState = DEV_COORD_STARTING; } } #if defined(BLINK_LEDS) else { // 组网失败,闪烁网络指示灯 HalLedSet ( HAL_LED_3, HAL_LED_MODE_FLASH ); // Flash LED to show failure } #endif osal_set_event( ZDAppTaskID, ZDO_NETWORK_START ); }上述函数为协调器网络形成确认回调函数,从上面代码我们可以看出,当协调器形成网络成功时,网络指示灯常亮,形成网络失败时,网络指示灯闪烁。
我们可以在这个函数中添加自己的网络指示灯应用代码。更改代码如下:
/********************************************************************* * @fn ZDO_NetworkFormationConfirmCB * * @brief This function reports the results of the request to * initialize a coordinator in a network. * * @param Status - Result of NLME_NetworkFormationRequest() * * @return none */ void ZDO_NetworkFormationConfirmCB( ZStatus_t Status ) { nwkStatus = (byte)Status; if ( Status == ZSUCCESS ) { /* * ----- commented by Jesse_黄嘉伟 2017/09/09 ------ * // LED on shows Coordinator started HalLedSet ( HAL_LED_3, HAL_LED_MODE_ON ); * */ /* ------ Added by Jesse_黄嘉伟 2017/09/09 ----- */ // 组网成功,点亮网络指示灯 Control_IndicatorLight(LIGHT_NEK, LIGHT_ON); /* ----------------------------------------- */ // LED off forgets HOLD_AUTO_START HalLedSet (HAL_LED_4, HAL_LED_MODE_OFF); #if defined ( ZBIT ) SIM_SetColor(0xd0ffd0); #endif if ( devState == DEV_HOLD ) { // Began with HOLD_AUTO_START devState = DEV_COORD_STARTING; } } /* * ----- commented by Jesse_黄嘉伟 2017/09/09 ------ * #if defined(BLINK_LEDS) else { HalLedSet ( HAL_LED_3, HAL_LED_MODE_FLASH ); // Flash LED to show failure } #endif * */ /* ------ Added by Jesse_黄嘉伟 2017/09/09 ----- */ else { // 组网失败,熄灭网络指示灯 Control_IndicatorLight(LIGHT_NEK, LIGHT_OFF); } /* ----------------------------------------- */ osal_set_event( ZDAppTaskID, ZDO_NETWORK_START ); }还有另外2个回调函数,分别是:ZDO_StartRouterConfirmCB() 和 ZDO_JoinConfirmCB()。
2)ZDO_StartRouterConfirmCB()
/********************************************************************* * @fn ZDO_StartRouterConfirmCB * * @brief This function reports the results of the request to * start functioning as a router in a network. * * @param Status - Result of NLME_StartRouterRequest() * * @return none */ void ZDO_StartRouterConfirmCB( ZStatus_t Status ) { nwkStatus = (byte)Status; if ( Status == ZSUCCESS ) { // LED on shows Router started HalLedSet ( HAL_LED_3, HAL_LED_MODE_ON ); // 入网成功,点亮网络指示灯 // LED off forgets HOLD_AUTO_START HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF); if ( devState == DEV_HOLD ) { // Began with HOLD_AUTO_START devState = DEV_END_DEVICE; } } #if defined(BLINK_LEDS) else { // 入网失败,闪烁网络指示灯 HalLedSet( HAL_LED_3, HAL_LED_MODE_FLASH ); // Flash LED to show failure } #endif osal_set_event( ZDAppTaskID, ZDO_ROUTER_START ); }上述函数是路由器入网结果确认回调函数,路由器入网成功则点亮网络指示灯,路由器入网失败则闪烁网络指示灯。
更改程序如下:
/********************************************************************* * @fn ZDO_StartRouterConfirmCB * * @brief This function reports the results of the request to * start functioning as a router in a network. * * @param Status - Result of NLME_StartRouterRequest() * * @return none */ void ZDO_StartRouterConfirmCB( ZStatus_t Status ) { nwkStatus = (byte)Status; if ( Status == ZSUCCESS ) { /* * ----- commented by Jesse_黄嘉伟 2017/09/09 ------ * // LED on shows Router started HalLedSet ( HAL_LED_3, HAL_LED_MODE_ON ); * */ /* ------ Added by Jesse_黄嘉伟 2017/09/09 ----- */ // 入网成功,点亮网络指示灯 Control_IndicatorLight(LIGHT_NEK, LIGHT_ON); /* ----------------------------------------- */ // LED off forgets HOLD_AUTO_START HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF); if ( devState == DEV_HOLD ) { // Began with HOLD_AUTO_START devState = DEV_END_DEVICE; } } /* * ----- commented by Jesse_黄嘉伟 2017/09/09 ------ * #if defined(BLINK_LEDS) else { HalLedSet( HAL_LED_3, HAL_LED_MODE_FLASH ); // Flash LED to show failure } #endif * */ /* ------ Added by Jesse_黄嘉伟 2017/09/09 ----- */ else { // 入网失败,熄灭网络指示灯 Control_IndicatorLight(LIGHT_NEK, LIGHT_OFF); } /* ----------------------------------------- */ osal_set_event( ZDAppTaskID, ZDO_ROUTER_START ); }3)ZDO_JoinConfirmCB()
/********************************************************************* * @fn ZDO_JoinConfirmCB * * @brief This function allows the next hight layer to be notified * of the results of its request to join itself or another * device to a network. * * @param Status - Result of NLME_JoinRequest() * * @return none */ void ZDO_JoinConfirmCB( uint16 PanId, ZStatus_t Status ) { (void)PanId; // remove if this parameter is used. nwkStatus = (byte)Status; if ( Status == ZSUCCESS ) { // LED on shows device joined HalLedSet ( HAL_LED_3, HAL_LED_MODE_ON ); // 入网成功,点亮网络指示灯 // LED off forgets HOLD_AUTO_START HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF); if ( (devState == DEV_HOLD) ) { // Began with HOLD_AUTO_START devState = DEV_NWK_JOINING; } if ( !ZG_SECURE_ENABLED ) { // Notify to save info into NV ZDApp_NVUpdate(); } } else { // 入网失败,闪烁网络指示灯 #if defined(BLINK_LEDS) HalLedSet ( HAL_LED_3, HAL_LED_MODE_FLASH ); // Flash LED to show failure #endif } // Pass the join confirm to higher layer if callback registered if (zdoCBFunc[ZDO_JOIN_CNF_CBID] != NULL ) { zdoJoinCnf_t joinCnf; joinCnf.status = Status; joinCnf.deviceAddr = _NIB.nwkDevAddress; joinCnf.parentAddr = _NIB.nwkCoordAddress; zdoCBFunc[ZDO_JOIN_CNF_CBID]( (void*)&joinCnf ); } // Notify ZDApp ZDApp_SendMsg( ZDAppTaskID, ZDO_NWK_JOIN_IND, sizeof(osal_event_hdr_t), (byte*)NULL ); }上述函数为终端设备入网结果确认回调函数,入网成功则点亮网络指示灯,入网失败则闪烁网络指示灯。
其修改代码如下:
/********************************************************************* * @fn ZDO_JoinConfirmCB * * @brief This function allows the next hight layer to be notified * of the results of its request to join itself or another * device to a network. * * @param Status - Result of NLME_JoinRequest() * * @return none */ void ZDO_JoinConfirmCB( uint16 PanId, ZStatus_t Status ) { (void)PanId; // remove if this parameter is used. nwkStatus = (byte)Status; if ( Status == ZSUCCESS ) { /* * ----- commented by Jesse_黄嘉伟 2017/09/09 ------ * // LED on shows Router started HalLedSet ( HAL_LED_3, HAL_LED_MODE_ON ); * */ /* ------ Added by Jesse_黄嘉伟 2017/09/09 ----- */ // 入网成功,点亮网络指示灯 Control_IndicatorLight(LIGHT_NEK, LIGHT_ON); /* ----------------------------------------- */ // LED off forgets HOLD_AUTO_START HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF); if ( (devState == DEV_HOLD) ) { // Began with HOLD_AUTO_START devState = DEV_NWK_JOINING; } if ( !ZG_SECURE_ENABLED ) { // Notify to save info into NV ZDApp_NVUpdate(); } } else { /* * ----- commented by Jesse_黄嘉伟 2017/09/09 ------ * #if defined(BLINK_LEDS) HalLedSet ( HAL_LED_3, HAL_LED_MODE_FLASH ); // Flash LED to show failure #endif * */ /* ------ Added by Jesse_黄嘉伟 2017/09/09 ----- */ // 入网失败,熄灭网络指示灯 Control_IndicatorLight(LIGHT_NEK, LIGHT_OFF); /* ----------------------------------------- */ } // Pass the join confirm to higher layer if callback registered if (zdoCBFunc[ZDO_JOIN_CNF_CBID] != NULL ) { zdoJoinCnf_t joinCnf; joinCnf.status = Status; joinCnf.deviceAddr = _NIB.nwkDevAddress; joinCnf.parentAddr = _NIB.nwkCoordAddress; zdoCBFunc[ZDO_JOIN_CNF_CBID]( (void*)&joinCnf ); } // Notify ZDApp ZDApp_SendMsg( ZDAppTaskID, ZDO_NWK_JOIN_IND, sizeof(osal_event_hdr_t), (byte*)NULL ); }
在上面三个函数中添加自己的应用代码就能实现自己的网络指示灯应用功能了,如有疑问或补充,可在博客下方留言哦。
相关文章推荐
- 深度学习 13. 能力提升, 一步一步的介绍如何自己构建网络和训练,利用MatConvNet(二),思路整理
- 深度学习12:能力提升, 一步一步的介绍如何自己构建网络和训练,利用MatConvNet
- 【深度学习】笔记7: CNN训练Cifar-10技巧 ---如何进行实验,如何进行构建自己的网络模型,提高精度
- 如何构建自己的网游基本构架
- 如何构建一个带有自己标签的Eclipse?
- 如何通过序列化在网络间传递对象,网络协议:轻松定义自己的网络通讯协议
- 如何在ArcGIS Online中构建自己的应用程序模板中级篇-解析数据
- Android开发培训之如何使用该框架来构建自己的应用
- 6、神经网络自己如何判断预测结果是否准确呢?
- 如何查看自己的网络是否支持IPV6?
- [转]如何提高自己的竞争力:构建个人的知识管理体系
- 如何构建自己的python package
- 如何构建自己的交易系统
- 如何在ArcGIS Online中构建自己的应用程序模板高级篇-利用数据
- 问题二:zigbee 网络如何设置PANID??
- JavaScript——如何构建自己的JS库?
- 如何构建自己的团队
- 如果你是来12306系架,你如何实现? ——关于构建安全、稳定、高吞吐量的火车票网络售票系统几个方面(1)前引
- javascript专题:如何构建自己的js库
- 网络时代如何尽量保证自己不被骗?(二)一个诈骗短信的例子