实际使用的时候发现假如协调器设置了其他信道,默认11,这样终端不在同一个信道的话就入不了网,所以协调器和终端的信道必须一致。下面是一些函数,用来切换信道。具体有没有用还没测试过。
ZDO_RegisterForZDOMsg(task_id, Mgmt_Leave_req); //注册自己处理离网回调
case ZDO_CB_MSG:
zclSampleSw_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );处理回调
if ( pMsg->clusterID == Mgmt_Leave_req )//处理被踢出网络事件
{
leavenetwork();//主动离网
}
一般设备都有重置按键,被重置的时候需要离开当前网络,然后重新搜索加入网络
//主动离开网络
void leavenetwork(void)
{
NLME_LeaveReq_t leaveReq;
osal_memset((uint8 *)&leaveReq,0,sizeof(NLME_LeaveReq_t));
osal_memcpy(leaveReq.extAddr,NLME_GetExtAddr(),Z_EXTADDR_LEN);
leaveReq.removeChildren = 1;
leaveReq.rejoin = 0;
leaveReq.silent = 0;
NLME_LeaveReq( &leaveReq );
}
添加自定义按键,主要修改hal_key.h,hal_key.c,hal_board_cfg.h这3个文件,下面我添加一个P0_0按键
hal_key.h
#define HAL_KEY_SW_9 0x0100
hal_key.c
1./* CPU port interrupt */
#define HAL_KEY_CPU_PORT_0_IF P0IF
/* SW_9 is at P0.0 */
#define HAL_KEY_SW_9_PORT P0
#define HAL_KEY_SW_9_BIT BV(0)
#define HAL_KEY_SW_9_SEL P0SEL
#define HAL_KEY_SW_9_DIR P0DIR
/* edge interrupt */
#define HAL_KEY_SW_9_EDGEBIT BV(0)
#define HAL_KEY_SW_9_EDGE HAL_KEY_FALLING_EDGE
/* SW_9 interrupts */
#define HAL_KEY_SW_9_IEN IEN1 /* CPU interrupt mask register */
#define HAL_KEY_SW_9_IENBIT BV(5) /* Mask bit for all of Port_0 */
#define HAL_KEY_SW_9_ICTL P0IEN /* Port Interrupt Control register */
#define HAL_KEY_SW_9_ICTLBIT BV(0) /* P0IEN - P0.6 enable/disable bit */
#define HAL_KEY_SW_9_PXIFG P0IFG /* Interrupt flag at source */
2.void HalKeyInit( void )
...
HAL_KEY_SW_9_SEL &= ~(HAL_KEY_SW_9_BIT); /* Set pin function to GPIO */
HAL_KEY_SW_9_DIR &= ~(HAL_KEY_SW_9_BIT); /* Set pin direction to Input */
...
3.void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback)
...
PICTL &= ~(HAL_KEY_SW_9_EDGEBIT); /* Clear the edge bit */
...
#if (HAL_KEY_SW_9_EDGE == HAL_KEY_FALLING_EDGE)
PICTL |= HAL_KEY_SW_9_EDGEBIT;
#endif
...
HAL_KEY_SW_9_ICTL |= HAL_KEY_SW_9_ICTLBIT;
HAL_KEY_SW_9_IEN |= HAL_KEY_SW_9_IENBIT;
HAL_KEY_SW_9_PXIFG = ~(HAL_KEY_SW_9_BIT);
...
HAL_KEY_SW_9_ICTL &= ~(HAL_KEY_SW_9_ICTLBIT); /* don't generate interrupt */
HAL_KEY_SW_9_IEN &= ~(HAL_KEY_SW_9_IENBIT); /* Clear interrupt enable bit */
4.uint16 HalKeyRead ( void )
if (HAL_PUSH_BUTTON9())
{
keys |= HAL_KEY_SW_9;
}
5.void HalKeyPoll (void)
if (HAL_PUSH_BUTTON9())
{
keys |= HAL_KEY_SW_9;
}
6.void halProcessKeyInterrupt (void)
if (HAL_KEY_SW_9_PXIFG & HAL_KEY_SW_9_BIT) /* Interrupt Flag has been set */
{
HAL_KEY_SW_9_PXIFG = ~(HAL_KEY_SW_9_BIT); /* Clear Interrupt Flag */
valid = TRUE;
}
7.HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
...
if (HAL_KEY_SW_9_PXIFG & HAL_KEY_SW_9_BIT)
{
halProcessKeyInterrupt();
}
HAL_KEY_SW_9_PXIFG = 0;
hal_board_cfg.h
...
/* S9 */
#define PUSH9_BV BV(0)
#define PUSH9_SBIT P0_0
#if defined (HAL_BOARD_CC2530EB_REV17)
#define PUSH9_POLARITY ACTIVE_LOW //什么电平触发
#elif defined (HAL_BOARD_CC2530EB_REV13)
#define PUSH9_POLARITY ACTIVE_LOW
#else
#error Unknown Board Indentifier
#endif
...
#define HAL_PUSH_BUTTON9() (PUSH9_POLARITY (PUSH9_SBIT))
...
当要用到的按键超过8个的时候,有2种方法,1种是使用按键矩阵,这样就可以使用16个按键只使用8个io口;
第2种是我现在使用的方法,就是修改协议栈里面的方法使用2个字节来表示按键,这样就可以使用超过8个按键了;
具体修改如下:
主工程app:
static void zclSampleSw_HandleKeys(byte shift, uint8 keys)--> static void zclSampleSw_HandleKeys(byte shift, UINT16 keys) //改成2个字节,然后修改相应的声明
OnBoard.c:
void OnBoard_KeyCallback ( uint8 keys, uint8 state )-->void OnBoard_KeyCallback ( uint16 keys, uint8 state )//改成2个字节,然后修改相应的声明
uint8 OnBoard_SendKeys( uint8 keys, uint8 state )-->uint8 OnBoard_SendKeys( uint16 keys, uint8 state ) //改成2个字节,然后修改相应的声明
hal_key.c:
uint8 HalKeyRead ( void ){
uint8 keys = 0;
.........
}
-->uint16 HalKeyRead ( void ){
uint16 keys = 0;
................
}//改成2个字节,然后修改相应的声明
void HalKeyPoll (void)
{
uint8 keys = 0;
............
}
--->void HalKeyPoll (void)
{
uint16 keys = 0;
........
}
hal_key.h:
typedef void (*halKeyCBack_t) (uint8 keys, uint8 state);-->typedef void (*halKeyCBack_t) (uint16 keys, uint8 state); //改成2个字节,然后修改相应的声明
修改完了之后就可以用2个字节表示按键了,也就是说,最多可以使用16个按键
zstrack出现上电不搜索入网有2种情况,1上电的时候有设置好的延时入网按键按着。2.配置了HOLD_AUTO_START选项。
当不搜索入网的情况发生了,就意味了ZigBee网络并没有初始化,所以需要手动或者在按键的事件里面写初始化事件,代码很简单:
ZDOInitDevice(0);//打开入网功能
在适当的时候调用这个语句就可以实现延时或者手动入网
1.在预编译选项中增加 WDT_IN_PM1
2.增加喂狗代码段,我是在OSAL.c里面添加的
#define WD_KICK() st( WDCTL = (0xA0 | WDCTL & 0x0F); WDCTL = (0x50 | WDCTL & 0x0F); )
3.保证喂狗周期小于喂狗timeout就可以,比如可在main函数的osal_start_system中添加喂狗函数:
if (errno != ICALL_ERRNO_SUCCESS)
{
ICall_abort();
}
#endif /* USE_ICALL */
#if !defined ( ZBIT ) && !defined ( UBIT )
for(;;) // Forever Loop
#endif
{
osal_run_system();
WD_KICK(); //feed dog
#ifdef USE_ICALL
ICall_wait(ICALL_TIMEOUT_FOREVER);
#endif /* USE_ICALL */
}
可以先离开网络,然后再调用清除nv数据和系统复位
//1.leavenetwork();
//2. zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
//3.SystemReset()