打印
[CC2530]

CC2530基于GenericApp无线收发实验

[复制链接]
1161|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
aoyi|  楼主 | 2019-9-5 11:55 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
实验设备
硬件:PC 机一台;ZB2530(底板、核心板、仿真器、USB 线) 一套
软件:win7 系统,IAR 8.20 集成开发环境

本实验是基于GenericApp无线收发,编者在第2讲也有讲过,当时也是用的TI提供的源码改编的,比较完善,而现在编者将带领大家编写较为简单的协议栈,实现个性化订制,下图为该实验的模型。

图9-1无线收发LED模型

使用特权

评论回复

相关帖子

沙发
aoyi|  楼主 | 2019-9-5 11:56 | 只看该作者
打开工程:
基于GenericApp无线收发实验\Projects\zstack\Samples\GenericApp\CC2530DB。

        OSAL_Example.c

#include "ZComDef.h"
#include "hal_drivers.h"  //硬件驱动头文件
#include "OSAL.h"         //操作系统头文件
#include "OSAL_Tasks.h"   //操作系统任务头文件

#if defined ( MT_TASK )   //串口应用头文件
  #include "MT.h"
  #include "MT_TASK.h"
#endif

#include "nwk.h"          //网络层头文件
#include "APS.h"          //应用支持层头文件
#include "ZDApp.h"        //设备对象头文件

#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  #include "ZDNwkMgr.h"
#endif

#if defined ( ZIGBEE_FRAGMENTATION )
  #include "aps_frag.h"
#endif
#include "Common.h"

// 任务注册
const pTaskEventHandlerFn tasksArr[] = {
  macEventLoop,           //MAC任务循环
  nwk_event_loop,         //网络层任务函数
  Hal_ProcessEvent,       //硬件层函数
#if defined( MT_TASK )
  MT_ProcessEvent,        //串口支持层定义
#endif
  APS_event_loop,         //应用支持层任务事件函数
#if defined ( ZIGBEE_FRAGMENTATION )
  APSF_ProcessEvent,
#endif
  ZDApp_event_loop,       //设备对象层函数
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  ZDNwkMgr_event_loop,
#endif
  GenericApp_ProcessEvent //自己定义的任务处理函数
};

const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );
uint16 *tasksEvents;

void osalInitTasks( void )//完成了任务ID的分配,以及所有任务的初始化
{
  uint8 taskID = 0;
  //分配内存空间
  tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
  osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

  macTaskInit( taskID++ );//MAC层的任务ID号
  nwk_init( taskID++ );   //网络ID分配
  Hal_Init( taskID++ );   //硬件ID分配
#if defined( MT_TASK )
  MT_TaskInit( taskID++ );
#endif
  APS_Init( taskID++ );
#if defined ( ZIGBEE_FRAGMENTATION )
  APSF_Init( taskID++ );
#endif
  ZDApp_Init( taskID++ );
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  ZDNwkMgr_Init( taskID++ );
#endif
  GenericApp_Init( taskID );//自己任务初始化函数
}
第 1-22 行包含一些相关函数的头文件,相对固定不用过多研究
第 24-41 行 tasksArr 数组里面存放所有任务的任务处理函数,如果操作系查询到了该任务的 ID那么就会调用对应的任务处理函数,该数组的顺序必须和 osalInitTasks 函数的初始化顺序相同。
第 43 行 tasksCnt 保存了任务的个数
第 44 行 tasksEvent 这是一个指针,指向了事件标的首地址
第 45-68 行完成了任务 ID 的分配,以及所有任务的初始化。GenericApp_Init( taskID );是自己任务初始化函数。我们程序初始化部分都可写在此函数中,具体详解在协调器程序中给出。


使用特权

评论回复
板凳
aoyi|  楼主 | 2019-9-5 11:56 | 只看该作者
协调器源码分析



使用特权

评论回复
地板
aoyi|  楼主 | 2019-9-5 11:57 | 只看该作者

使用特权

评论回复
5
aoyi|  楼主 | 2019-9-5 11:57 | 只看该作者

使用特权

评论回复
6
aoyi|  楼主 | 2019-9-5 11:57 | 只看该作者

使用特权

评论回复
7
aoyi|  楼主 | 2019-9-5 11:58 | 只看该作者

使用特权

评论回复
8
aoyi|  楼主 | 2019-9-5 11:58 | 只看该作者

使用特权

评论回复
9
aoyi|  楼主 | 2019-9-5 11:58 | 只看该作者
第 1-19 行包含一些相关函数的头文件
第 21-24 行GENERICAPP_CLUSTERID 为簇 ID 列表,消息发送和接收需要用的,如果定义多个簇 ID 就在这里增加,以前的实验我们已增加过了,这里只提一下。
第 26-37 行简单描述符的定义,定义终端号、终端支持的设备 ID、设备描述的版本、终端支持的输入簇数目等信息,格式相对固定。
第 39 行 endPointDesc_t GenericApp_epDesc; //简单描述符。
第 40 行 byte GenericApp_TaskID; //osal 分配的任务 ID 随着用户添加任务的增多而改变。
第 41 行 byte GenericApp_TransID; //消息发送 ID(多消息时有顺序之分)
第 46-58 行 GenericApp_Init 函数,程序初始化部分都可写在此函数
第 60-83 行事件处理函数。
第 85-106 行接收数据。
第 108-125 行发送数据。
以上代码是在 TI GenericApp 例程复制过来的,我们对 GenericApp.c 中的代码进行了裁剪,帮助大家更容易掌握 GenericApp,同时我们把协调器和终端的代码独立开,让初学者不易混淆。 明白了其中的原理后,再去看其它程序那就是小菜一碟了。至于终端只有三个地方不同,我们讲不同处即可,大部分一样。相信学到现在的水平,应该完全可以看懂了


使用特权

评论回复
10
aoyi|  楼主 | 2019-9-5 11:59 | 只看该作者
        终端源码分析

#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"

#include "Common.h"
#include "DebugTrace.h"

#if !defined( WIN32 )
  #include "OnBoard.h"
#endif

/* HAL */
#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
};


使用特权

评论回复
11
aoyi|  楼主 | 2019-9-5 11:59 | 只看该作者
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;
byte GenericApp_TransID;
devStates_t GenericApp_NwkState;

void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void GenericApp_SendTheMessage( void );


使用特权

评论回复
12
aoyi|  楼主 | 2019-9-5 12:00 | 只看该作者
void GenericApp_Init( byte task_id )
{   
    GenericApp_TaskID = task_id;
    GenericApp_NwkState=DEV_INIT;
    GenericApp_TransID = 0;

    GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
    GenericApp_epDesc.task_id = &GenericApp_TaskID;
    GenericApp_epDesc.simpleDesc
        = (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;

    GenericApp_epDesc.latencyReq = noLatencyReqs;
    afRegister( &GenericApp_epDesc );
}


使用特权

评论回复
13
aoyi|  楼主 | 2019-9-5 12:00 | 只看该作者
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{
    afIncomingMSGPacket_t *MSGpkt;

    if ( events & SYS_EVENT_MSG )
    {
        MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
        while ( MSGpkt )
        {
            switch ( MSGpkt->hdr.event )
            {
            case AF_INCOMING_MSG_CMD:
                GenericApp_MessageMSGCB(MSGpkt);
                break;
            case ZDO_STATE_CHANGE:
                GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
                if(GenericApp_NwkState == DEV_END_DEVICE)
                {
                    GenericApp_SendTheMessage();
                }
                break;
            default:
                break;
            }
            osal_msg_deallocate( (uint8 *)MSGpkt );
            MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
        }

        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
    }
    return 0;
}


使用特权

评论回复
14
aoyi|  楼主 | 2019-9-5 12:01 | 只看该作者
void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pkt)
{
    unsigned char buf[3];

    switch ( pkt->clusterId )
    {
    case GENERICAPP_CLUSTERID:
        osal_memset(buf, 0 , 3);
        osal_memcpy(buf, pkt->cmd.Data, 2);
        if(buf[0]=='D' && buf[1]=='1')      
        {
            HalLedBlink(HAL_LED_1, 0, 50, 500);                                   
        }
        else
        {
            HalLedSet(HAL_LED_1,HAL_LED_MODE_ON);                  
        }
        break;
    }
}


使用特权

评论回复
15
aoyi|  楼主 | 2019-9-5 12:01 | 只看该作者
void GenericApp_SendTheMessage(void)
{
    byte SendData[3]="D1";

    afAddrType_t devDstAddr;
    devDstAddr.addrMode=(afAddrMode_t)Addr16Bit;
    devDstAddr.endPoint=GENERICAPP_ENDPOINT;
    devDstAddr.addr.shortAddr=0x0000;

    AF_DataRequest(&devDstAddr,
        &GenericApp_epDesc,
        GENERICAPP_CLUSTERID,
        2,
        SendData,
        &GenericApp_TransID,
        AF_DISCV_ROUTE,
        AF_DEFAULT_RADIUS);
}


使用特权

评论回复
16
aoyi|  楼主 | 2019-9-5 12:02 | 只看该作者
        实验现象
1)选择 CoodinatorEB-Pro, 下载到开发板 A;作为协调器;
2)选择 EndDeviceEB-Pro, 下载到开发板 B;作为终端设备
3)给两块开发板上电,协调器组网,终端联网成功后发“D1”, 协调器收到数据“D1”后Led1 闪烁;同时也发“D1”给终端,终端收到后 Led1 也闪烁。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

100

主题

3306

帖子

3

粉丝