运行Zigbee例程Word文档下载推荐.docx

上传人:b****6 文档编号:21914897 上传时间:2023-02-01 格式:DOCX 页数:14 大小:520.35KB
下载 相关 举报
运行Zigbee例程Word文档下载推荐.docx_第1页
第1页 / 共14页
运行Zigbee例程Word文档下载推荐.docx_第2页
第2页 / 共14页
运行Zigbee例程Word文档下载推荐.docx_第3页
第3页 / 共14页
运行Zigbee例程Word文档下载推荐.docx_第4页
第4页 / 共14页
运行Zigbee例程Word文档下载推荐.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

运行Zigbee例程Word文档下载推荐.docx

《运行Zigbee例程Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《运行Zigbee例程Word文档下载推荐.docx(14页珍藏版)》请在冰豆网上搜索。

运行Zigbee例程Word文档下载推荐.docx

按键操作几乎在每个例程中都会用到,故此处以按键驱动的修改为例,演示HAL的修改。

先了解下Ti和无线龙扩展板的不同之处。

Ti的CC2430EB原理图在Ti文档SWRU133.pdf(位于SWRU133.zip中)。

Page29是按键电路的原理图,如图1

图1(左上角是元件图)

CC2430EB的按键其实是摇杆,上下左右四个方向和电阻网络相连,通过放大电路送到CC2430的P0.6脚,经AD采样后判断摇杆摆向哪个方向,按键编号为SW1~SW4摇杆也可像普通按键一样按下,产生一个直流电平变化,接到P0.5脚,按键编号为SW5。

除此之外,还有一个独立按键连到P0.1脚,按键编号为SW6。

无线龙的开发板则是用六个独立按键,上下左右四个按键和电阻网络相连,接P0.6,由AD采样得出是哪个键被按下。

还有两个按键OK、Cancel分别直接和P0.5、P0.4相连。

由于Ti和无线龙上下左右四个按键的电阻网络有差异,AD采样值有所不同,要予以修改。

还有修改SW5、SW6的读取为的无线龙地OK、Cancel两个按键。

要修改的文件为hal_key.c,要修改的部分宏定义、uint8HalKeyRead()、voidHalKeyPoll()。

修改SW6的引脚定义,行156中的HAL_KEY_BIT1改为HAL_KEY_BIT4

156:

#defineHAL_KEY_SW_6_BITHAL_KEY_BIT4

修改uint8HalKeyRead()中的SW5、SW6有关的内容,注释掉以下语句

#ifdefined(HAL_KEY_SW_6_ENABLE)

if(!

(HAL_KEY_SW_6_PORT&

HAL_KEY_SW_6_BIT))/*Keyisactivelow*/

{

keys|=HAL_KEY_SW_6;

}

#endif

#ifdefined(HAL_KEY_SW_5_ENABLE)

if(HAL_KEY_SW_5_PORT&

HAL_KEY_SW_5_BIT)/*Keyisactivehigh*/

keys|=HAL_KEY_SW_5;

在对应位置添加

if(P0_5==0)

{

keys|=0x04;

}

if(P0_4==0)

keys|=0x20;

修改用于判断哪个方向键被按下的P0.6采样值,do{}while中的条件语句注释掉,取之以下内容

if((adc>

=0x55)&

&

(adc<

=0x70))

ksave0|=HAL_KEY_UP;

elseif((adc>

=0x40)&

=0x50))

ksave0|=HAL_KEY_DOWN;

=0x18)&

=0x30))

ksave0|=HAL_KEY_LEFT;

elseif(adc<

=10)

ksave0|=HAL_KEY_RIGHT;

else

修改voidHalKeyPoll()中的有关的内容,修改同HalKeyRead()。

再把voidHalKeyEnterSleep(void)中所有内容注释掉,将uint8HalKeyExitSleep(void)中的

HAL_KEY_SW_5_INP|=HAL_KEY_SW_5_BIT;

/*Setpininputmodetotri-state*/

注释掉,以上就完成了按键有关Hal修改。

二、Zigbee工程设置

下面将以运行一个工程<

GenericApp>

为例,介绍Zigbee工程设置。

CC2430的开发环境为IAR,相信接触过MSP430的朋友对其不会陌生,有关Zigbee工程的设置实际上就是通过IAR的工程设置完成的。

打开<

Projects/zstack/Samples/GenericApp/CC2430DB>

下的GenericApp.eww。

打开工程后,界面如图2

图2

同一个工程中包含的多个project,根据开发板的类型(EB和DB)、Zigbee网络中的节点类型(Coordinator、Router和EndDevice)一共有六个project,我们只需用到CoordinatorEB和EndDeviceEB这两个project。

先把project选择为CoordinatorEB,在GenericApp-CoordinatorEB上右击,选择Options…进入工程设置界面,选择C/C++Compiler->

Preprocessor,设置预编译项。

去掉LCD_SUPPORTED=DEBUG,HAL_UART在GenericApp中可加可不加,如图3所示

图3

通过条件编译选项设定是否添加相关的硬件驱动和调试选项,去掉LCD_SUPPORTED=DEBUG的原因是Ti的开发板和无线龙开发板的LCD接口不一样,而我们又没有修改相关Hal文件,无法使用LCD显示,加入HAL_UART的原因是我们将使用串口作为调试信息的输出。

三、Zigbee工程启动流程解析

用户相关的应用程序代码是在App类的文件当中,其与Zigbee是如何关联起来的呢?

如何调配处理器时间去处理应用程序、响应外设和进行无线收发呢?

Ti协议栈通过了一个小型的操作系统实现了复杂多样的事件处理。

CC2430具有128KBROM、8KBRAM,如此大的空间为SOC(SystemOnChip)提供了有力保障。

操作系统的API介绍在《OSALAPI_F8W-2003-0002_》中,在这个操作系统中提供了消息管理、任务同步、定时器管理、中断管理、任务管理、内存管理、电院管理和非易失内存管理等功能。

用户的应用程序要以任务(task)的方式注册到系统中,一个task对应于自己的事件处理函数(eventprocessor)。

task的添加,event和task的关联,事件处理函数和对应task的关联将在以下的流程解析中讲解。

1、main()

编译工程(快捷键F7),将模块连接到PC,调试工程(快捷键Ctrl+D)。

进入到函数的入口——main()函数,位于ZMainGroup的ZMain.c中。

在main()中完成了相关硬件和软件的初始化,作为重点,我们要关注的是

190:

osal_init_system();

206:

osal_start_system();

//NoReturnfromhere

我们先来看osal_init_system()。

在osal_init_system右击,选择Gotodefinitionofosal_init_system,追踪其定义(注意“追踪”的方法,下文所述的追踪都是指用这个方法)。

2、osal_init_system()

osal_init_system()定义在OSALGroup的OSAL.c中,进行了操作系统相关的初始化工作,需要重点关注的是

927:

osalInitTasks();

追踪其定义。

3、osalInitTasks()和添加task到OS

osalInitTasks()定义在AppGroup的OSAL_GenericApp.c中,函数内容如下

voidosalInitTasks(void)

uint8taskID=0;

tasksEvents=(uint16*)osal_mem_alloc(sizeof(uint16)*tasksCnt);

osal_memset(tasksEvents,0,(sizeof(uint16)*tasksCnt));

macTaskInit(taskID++);

nwk_init(taskID++);

Hal_Init(taskID++);

#ifdefined(MT_TASK)

MT_TaskInit(taskID++);

APS_Init(taskID++);

ZDApp_Init(taskID++);

GenericApp_Init(taskID);

在这个函数中,我们看到了将task添加到系统的过程,每添加一个task,taskID就加1。

最后一句GenericApp_Init()正是关注的重点,追踪它。

4、GenericApp_Init()和注册event到task中

GenericApp_Init()位于GenericApp.c中,完成了endPoint的设定和注册、按键事件的注册,即把相关的enevt和相关的task进行了关联,当发生这些event时,会由和相应task关联的事件处理函数进行处理。

到此,已经了解了如何添加task、如何关联event和task,那么task和事件处理函数的关联又是如何进行的呢?

先找找GenericApp_Init对应的事件处理函数,解决这个问题,要回到ZMain.c中main()里的osal_start_system(),追踪它吧!

5、osal_start_system()和task及事件处理函数的关联

osal_start_system()定义在OSAL.c中。

osal_start_system()中最有可能是执行事件处理函数的就是行977了

977:

events=(tasksArr[idx])(idx,events);

tasksArr是函数数组,idx代表task的id,events代表相应的事件,猜测正确吗,追踪它。

在OSAL_GenericApp.c中找到了tasksArr的定义,内容如下

constpTaskEventHandlerFntasksArr[]={

macEventLoop,

nwk_event_loop,

Hal_ProcessEvent,

MT_ProcessEvent,

APS_event_loop,

ZDApp_event_loop,

GenericApp_ProcessEvent

};

如果追踪里面的数组成员,它们都是事件处理函数,注意,里面的成员顺序和osalInitTasks()中task的添加顺序是一样的,即task的ID和其对应的事件处理函数在tasksArr中的序号是一样的,这样在调用(tasksArr[idx])(idx,events)时,完成了task和对应的事件处理函数的关联。

6、事件处理

上面我们了解了task和对应事件处理函数关联方式,我们重点分析下用户自定义task的事件处理函数GenericApp_ProcessEvent()。

通过行233

233:

if(events&

SYS_EVENT_MSG)

和行300

300:

GENERICAPP_SEND_MSG_EVT)

可知,起码有两类事件:

SYS_EVENT_MSG和GENERICAPP_SEND_MSG_EVT,显然,SYS_EVENT_MSG是协议栈已经定义好的系统事件,而GENERICAPP_SEND_MSG_EVT就是用户自定义的事件了。

事件号是一个16bit的常量,使用独热码(one-hotcode)编码,方便进行event的提取,这样一个task中最多可以有16个event,SYS_EVENT_MSG已经占用了0x8000,故自定义的事件只能有16个。

由于事件号使用独热码,故事件的提取和清除可以用简单的位操作指令实现。

事件提取events&

GENERICAPP_SEND_MSG_EVT,事件清除events^GENERICAPP_SEND_MSG_EVT。

系统事件包函了各种系统消息(message),系统事件中的消息号是一8bit常量,定义在ZComDef.h中,

322:

#defineSPI_INCOMING_ZTOOL_PORT0x21//RawdatafromZToolPort(notimplemented)

323:

#defineSPI_INCOMING_ZAPP_DATA0x22//RawdatafromtheZAPPport(seeserialApp.c)

324:

#defineMT_SYS_APP_MSG0x23//RawdatafromanMTSysmessage

325:

#defineMT_SYS_APP_RSP_MSG0x24//RawdataoutputforanMTSysmessage

326:

327:

#defineAF_DATA_CONFIRM_CMD0xFD//Dataconfirmation

328:

#defineAF_INCOMING_MSG_CMD0x1A//IncomingMSGtypemessage

329:

#defineAF_INCOMING_KVP_CMD0x1B//IncomingKVPtypemessage

330:

#defineAF_INCOMING_GRP_KVP_CMD0x1C//IncomingGroupKVPtypemessage

331:

332:

#defineKEY_CHANGE0xC0//KeyEvents

333:

334:

#defineZDO_NEW_DSTADDR0xD0//ZDOhasreceivedanewDstAddrforthisapp

335:

#defineZDO_STATE_CHANGE0xD1//ZDOhaschangedthedevice'

snetworkstate

336:

#defineZDO_MATCH_DESC_RSP_SENT0xD2//ZDOmatchdescriptorresponsewassent

337:

#defineZDO_CB_MSG0xD3//ZDOincomingmessagecallback

用户可以自定义系统事件的消息范围为0xE0~0xFF,现只针对SYS_EVENT_MSG中的两个处理函数进行说明。

AF_INCOMING_MSG_CMD:

当模块接收到属于自己的无线数据信息时,就会触发AF_INCOMING_MSG_CMD消息,由相关的处理函数处理接收到的信息。

ZDO_STATE_CHANGE:

当网络状态改变时就会触发此消息,其在这个工程中的作用是,当节点建立网络(作为协调器)、加入网络(作为终端)时,运行

osal_start_timerEx(GenericApp_TaskID,

GENERICAPP_SEND_MSG_EVT,

GENERICAPP_SEND_MSG_TIMEOUT);

osal_start_timerEx()的作用是启动一系统定时器,当其溢出(GENERICAPP_SEND_MSG_TIMEOUT)时,会触发task(GenericApp_TaskID)的事件(GENERICAPP_SEND_MSG_EVT)。

又看到事件GENERICAPP_SEND_MSG_EVT了,它是用户定义的事件,分析之。

if(events&

//Send"

the"

message

GenericApp_SendTheMessage();

//Setuptosendmessageagain

osal_start_timerEx(GenericApp_TaskID,

//returnunprocessedevents

return(events^GENERICAPP_SEND_MSG_EVT);

以上就是GENERICAPP_SEND_MSG_EVT的处理函数,先分析总的流程,GenericApp_SendTheMessage()发送信息,osal_start_timerEx()重新启动一系统定时器,同样是指向task(GenericApp_TaskID)的事件(GENERICAPP_SEND_MSG_EVT),返回时要注意清除当前事件(events^GENERICAPP_SEND_MSG_EVT),否则会反复处理同一个事件,陷入死循环。

四、Zigbee应用模型

对数据进行收发还需对Zigbee的应用模型有所了解。

Profile和Endpoint是Zigbee应用层中有关应用模型的,概念,先给出这两个概念的官方的定义:

ApplicationProfilesareanagreementonaseriesofmessagesdefininganapplicationspace(forexample,“HomeAutomation”or“SmartEnergy”)

EndpointsarealogicalextensionaddedtoasingleZigBeeradiowhichpermitssupportformultipleapplications,addressedbytheEndpointnumber(1-240)

KeyRelationships:

Maximumof240EndpointsperZigBeeDevice(Endpoint0isreservedtodescribethegenericdevicecapabilitiesandEndpoint255isreservedforbroadcastingtoallendpoints,Endpoints241-254arereservedforfutureuse)

OneApplicationProfiledescribedperEndpoint。

我个人的理解是:

某个具体的应用(application)的相关操作被定义成一个profile,profile和应用层的结合通过endpoint来实现,一个zigbee设备有240个endpoint。

在GenericApp_Init(bytetask_id)中有以下相关的定义

GenericApp_epDesc.endPoint=GENERICAPP_ENDPOINT;

GenericApp_epDesc.task_id=&

GenericApp_TaskID;

GenericApp_epDesc.simpleDesc

=(SimpleDescriptionFormat_t*)&

GenericApp_SimpleDesc;

GenericApp_epDesc.latencyReq=noLatencyReqs;

追踪相关的变量可知使用类型endPointDesc_t描述endpoint的类型,其定义在AF.h中

typedefstruct

byteendPoint;

byte*task_id;

//PointertolocationoftheApplicationtaskID.

SimpleDescriptionFormat_t*simpleDesc;

afNetworkLatencyReq_tlatencyReq;

}endPointDesc_t;

需要进一步了解的是SimpleDescriptionFormat_t,其定义也在AF.h中

byteEndPoint;

uint16AppProfId;

uint16AppDeviceId;

byteAppDevVer:

4;

byteReserved:

//AF_V1_SUPPORTusesforAppFlags:

4.

byteAppNumInClusters;

cId_t*pAppInClusterList;

byteAppNumOutClusters;

cId_t*pAppOutClusterList;

}SimpleDescriptionFormat_t;

里面有AppProfId,即为ProfileId,可以从这个结构中看到,profile中有In、Out两种类型的Cluster,Cluster此处可理解为操作,每类Cluster对应着一个ClusterList,list中的每个成员对应一种操作,GenericApp的GenericApp_SimpleDesc为

constSimpleDescriptionFormat_tGenericApp_SimpleDesc=

GENERICAPP_ENDPOINT,//intEndpoint;

GENERICAPP_PROFID,//uint16AppProfId[2];

GENERICAPP_DEVICEID,//uint16AppDeviceId[2];

GENERICAPP_DEVICE_VERSION,//intAppDevVer:

GENERICAPP_FLAGS,//intAppFlags:

GENERICAPP_MAX_CLUSTERS

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 院校资料

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1