ZigBee初探

ZigBee初探

1、环境

硬件:
	开发板:CC2530-256
	端口调试助手:CCDebuger
软件:
	集成开发环境:IAR Embedded Workbench IDE 8051
	串口调试软件:SSCOM5.12.1
	协议栈:Z-stack2.4

IAR Workbench:https://www.iar.com/iar-embedded-workbench/#!?architecture=8051

Z-Stack2.4:https://download.csdn.net/download/qq_30033537/13631492

更新的Z-stack:Z-STACK A fully compliant ZigBee 3.x solution: Z-Stack | TI.com

以上软件的安装不一一介绍,IAR Workbench需要版权,自行百度安装。

2、Z-Stack

将Z-stack2.4下载之后解压。

2.1、目录介绍

image-20201211100705013

1、Components

该目录只要是存放了协议栈的程序文件,如hal、mac、osal等。

在一个标准Z-stack我们可以找到对应,如下图:

2、Documents

顾名思义,就是说明文档存放的目录。存放了TI提供的大量的说明文件,想要深入学习Z-stack可以通过这个目录学习,但是都是英文文档。

image-20201211101320490

3、Tools

一些工具,我们不重点管这个

4、Project【重要】

这对我们来说是最重要的一个目录,里面存放了我们开发用的项目。

并且,我们开发的项目必须放到该目录下才能与Components目录下的协议栈文件关联使用,否则在IAR IDE编译时会找不到文件。

image-20201211101703454

对于初学者我们重点学习Samples目录下的文件

2.2、快速开发

接下来,我们重点关注Samples下的项目文件,通过GenericApp快速示例程序,我们快速搭建一个入门案例。

1、进入GenericApp目录

image-20201211101808569

2、进入CC2530DB

image-20201211101825264

3、eww项目文件

image-20201211101908094

4、导入项目

image-20201211102020985

5、项目结构介绍

image-20201211102708706

我们重点关注的是App部分,下面我们修改示例代码实现第一个程序。

GenericApp.h

该文件我们展示不需要修改,里面定义了一些宏定义以及需要的头文件

#ifndef GENERICAPP_H
#define GENERICAPP_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "ZComDef.h"
#define GENERICAPP_ENDPOINT           10
#define GENERICAPP_PROFID             0x0F04
#define GENERICAPP_DEVICEID           0x0001
#define GENERICAPP_DEVICE_VERSION     0
#define GENERICAPP_FLAGS              0
#define GENERICAPP_MAX_CLUSTERS       1
#define GENERICAPP_CLUSTERID          1
#define GENERICAPP_SEND_MSG_TIMEOUT   5000     // Every 5 seconds
#define GENERICAPP_SEND_MSG_EVT       0x0001
extern void GenericApp_Init( byte task_id );
extern UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events );
#ifdef __cplusplus
}
#endif
#endif 

GenericApp.c

该文件是我们重点的编码对象,里面集成了:

设备描述、设备初始化、消息处理等

#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include "GenericApp.h"
#include "DebugTrace.h"
#if !defined( WIN32 )
  #include "OnBoard.h"
#endif
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"

const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{
  GENERICAPP_CLUSTERID
};
// 简单设备描述符:定义了设备ID等信息
const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{
  GENERICAPP_ENDPOINT,              //  int Endpoint;
  GENERICAPP_PROFID,                //  uint16 AppProfId[2];
  GENERICAPP_DEVICEID,              //  uint16 AppDeviceId[2];
  GENERICAPP_DEVICE_VERSION,        //  int   AppDevVer:4;
  GENERICAPP_FLAGS,                 //  int   AppFlags:4;
  GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;
  (cId_t *)GenericApp_ClusterList,  //  byte *pAppInClusterList;
  GENERICAPP_MAX_CLUSTERS,          //  byte  AppNumInClusters;
  (cId_t *)GenericApp_ClusterList   //  byte *pAppInClusterList;
};

endPointDesc_t GenericApp_epDesc;
byte GenericApp_TaskID;   
devStates_t GenericApp_NwkState;
byte GenericApp_TransID;  
afAddrType_t GenericApp_DstAddr;
// 函数头
void GenericApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg );
void GenericApp_HandleKeys( byte shift, byte keys );
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void GenericApp_SendTheMessage( void );
// 任务初始化函数
void GenericApp_Init( byte task_id )
{
  GenericApp_TaskID = task_id;			// 任务优先级
  GenericApp_NwkState = DEV_INIT;		
  GenericApp_TransID = 0;				// 数据包序列号
  GenericApp_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;	// 发送模式:点播
  GenericApp_DstAddr.endPoint = 0;		 
  GenericApp_DstAddr.addr.shortAddr = 0;
  // 下面是设备描述符的初始化
  GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
  GenericApp_epDesc.task_id = &GenericApp_TaskID;
  GenericApp_epDesc.simpleDesc
            = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
  GenericApp_epDesc.latencyReq = noLatencyReqs;
  // 将节点描述符注册以便于OSAL为其提供服务
  afRegister( &GenericApp_epDesc );
}
// 事件处理函数
// 在该函数中我们通过osal_msg_receive( GenericApp_TaskID )函数拿到发生的事件
// 通过判断事件发生的类型:如ZDO_STATE_CHANGE,状态改变类型
// 实现不同逻辑:如亮灯:HalLedSet( HAL_LED_2, HAL_LED_MODE_ON );
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{
  afIncomingMSGPacket_t *MSGpkt;
  afDataConfirm_t *afDataConfirm;
  byte sentEP;
  ZStatus_t sentStatus;
  byte sentTransID;       
  (void)task_id;  
  if ( events & SYS_EVENT_MSG )
  {
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
    while ( MSGpkt )
    {
      switch ( MSGpkt->hdr.event )
      {
        // 设备状态改变处理逻辑:如上电等
        case ZDO_STATE_CHANGE:
          GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
          if ( (GenericApp_NwkState == DEV_ZB_COORD)
              || (GenericApp_NwkState == DEV_ROUTER)
              || (GenericApp_NwkState == DEV_END_DEVICE) )
          {
            // 亮灯
            HalLedSet( HAL_LED_2, HAL_LED_MODE_ON );
          }
          break;
		// 其他处理逻辑
        default:
          break;
      }
      osal_msg_deallocate( (uint8 *)MSGpkt );
      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
    }
    return (events ^ SYS_EVENT_MSG);
  }
  if ( events & GENERICAPP_SEND_MSG_EVT )
  {
    GenericApp_SendTheMessage();
    osal_start_timerEx( GenericApp_TaskID,
                        GENERICAPP_SEND_MSG_EVT,
                      GENERICAPP_SEND_MSG_TIMEOUT );
    return (events ^ GENERICAPP_SEND_MSG_EVT);
  }
  return 0;
}

对于提供的示例程序,我们进行精简,得到以上的程序

以上程序实现了开机亮灯的效果。

6、编译运行

通过CCDebuger将CC2530连接到电脑,在项目中依次编译、连接、运行

image-20201211104800682

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值