zigbee 笔记3

zigbee 笔记3

注册被踢网回调

实际使用的时候发现假如协调器设置了其他信道,默认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个按键

HOLD_AUTO_START

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()

你可能感兴趣的:(zigbee)