首页 > 学院 > 开发设计 > 正文

08 ZStack初步接触

2019-11-08 18:33:19
字体:
来源:转载
供稿:网友

版本说明

Zstack 0.0.1 .. Zstack 1.5.1a

mesh:之前版本的升级版 HA: 专门给智能家庭 SE: 智能能源 .. 在应用部分作了规定!

新建工程模板

复制ZStack协议栈整个文件夹到一个合适的位置,比如E盘根目录,尽量不含中文以及路径不要太长!

在复制好的协议栈文件夹中删除多余的文件夹及文件!其中包括: (1)Documents (2)Tools (3)Getting Started Guide - CC2530 (4)msvcr71.dll 将上述四个文件(夹)删除

删除ZStack-CC2530-2.3.0-1.4.0/PRojects/zstack/Samples多余的文件夹 (1)SampleApp (2)SimpleApp

修改工程相关的名字 (1)将文件夹名GenericAPP改为SimonApp (2)将ZStack-CC2530-2.3.0-1.4.0/Projects/zstack/Samples/SimonApp/Source目录下的三个源文件名分别改为(原文件名的GenericApp全部改为SimonApp): SimonApp.c SimonApp.h OSAL_SimonApp.c

将上述源代码里的GenericAPP改为SimonApp。利用具体编辑器的全部替换功能!

将ZStack-CC2530-2.3.0-1.4.0/Projects/zstack/Samples/SimonApp/CC2530DB目录下的工程文件名GenericAPP修改为SimonApp: SimonApp.ewd SimonApp.ewp SimonApp.eww

将上述三个工程文件里的GenericAPP改为SimonApp。利用具体编辑器的全部替换功能!

利用IAR打开eww文件,即可打开自定义的工程!

重点关心APP文件夹以及ZMain文件夹!!!

选项卡剖析

为什么选项卡不同就会导致代码功能差异那么大,出现协调器 路由器和终端?

配置文件里有如下语句: -DZDO_COORDINATOR // Coordinator Functions 相当于#define ZDO_COORDINATOR 因为我们选项选择不同,就会导致参与编译的配置文件不同,配置不同就会导致部分宏定义不同,宏定义不同就会导致工程里某些宏的值不同,这些宏值不同就会影响程序执行的流程,就会导致出现不同的功能,所以有了不同功能的代码版本 协调器 路由器终端

2.在选项卡里每一种版本模块都貌似有2个分为不带-Pro和带Pro 他们的区别是什么?

Zigbee协议在发展过程中经历了3个版本,其中Zigbee在07出的是最新的规范,这个规范有2个版本,ZIgbee2007 ZigbeePRO ,他们之间的区别是,功能基本相同,PRO版本功能稍微强大,咱们一般都选PRO

添加自定义模块文件

将LED以及按键等模块文件添加到工程!要在osal_start_system之前重新初始化相关硬件模块!!记得在各C文件中添加头文件!

注意: (1)取消掉工程里面的编译选项下的require protype! (2)每一次配置/重新分配设备角色以后都需要重新取消掉上述选项

添加数码管

头文件:

#ifndef __74LS164_8LED_H__#define __74LS164_8LED_H__#include<ioCC2530.h>#define LS164_DATA P1_3#define LS164_CLK P1_2#define UCHAR unsigned char void LS164_Cfg(void);void LS164_BYTE(UCHAR Data);//P1.3 DATA P1.2 CLK#endif

实现文件:

#include<ioCC2530.h>#include"74LS164_8LED.h"static UCHAR LED_Map[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x00,/ 0x39,/*'C'协调器*// 0x77,/*'R'路由器*// 0x79/*'E'终端*/};void LS164_Cfg(void){ P1SEL &=~0x0C;//xxxx 00xx 配置为普通IO模式 P1DIR |=0x0C;//xxxx 11xx 配置为输出模式}void LS164_BYTE(UCHAR Index) //P1.3 DATA P1.2 CLK{ UCHAR i=0; UCHAR Data=LED_Map[Index]; for(;i<8;i++) { if(0x80 & Data) { LS164_DATA=1; } else { LS164_DATA=0; } Data=Data << 1; LS164_CLK=0; LS164_CLK=1; }}添加按键

头文件:

#ifndef SD_KEY_H#define SD_KEY_Hvoid KeysIntCfg();#endif

实现文件:

#include<iocc2530.h>#include "SimonApp.h"#include "OSAL_Timers.h"#include "SD_Key.h"extern unsigned char SimonApp_TaskID;void delay(){ int i,j; for(i=0;i<1000;i++) for(j=0;j<30;j++);}void KeysIntCfg(){//Key3 Key4 Key5 P1SEL &=~0X02; P1DIR &=~0X02; IEN2|=0x10;//开P1IE组中断 P1IEN|=0x02;//开Key3组内中断 PICTL|=0x02;//设置P1_1为下降沿 P2SEL &=~0X01; P2DIR &=~0X01; IEN2|=0x02; P2IEN|=0x01; PICTL|=0x08;//设置P2_0为下降沿 P0SEL &=~0X20; P0DIR &=~0X20; P0IE=1;//或者写成 IEN1|=0x20 P0IEN|=0x20; PICTL|=0x01;//设置P0_5为下降沿 EA=1; //开总中断}#pragma vector=P1INT_VECTOR__interrupt void Key3_ISR() //P1_1{ if(P1IFG & 0X02) { osal_start_timerEx(SimonApp_TaskID,SimonApp_MY_EVT,25); } P1IFG =0; P1IF=0;}#pragma vector=P2INT_VECTOR__interrupt void Key4_ISR()//P2_0{ if(P2IFG & 0X01) { osal_start_timerEx(SimonApp_TaskID,SimonApp_MY_EVT,25); } P2IFG =0; P2IF=0;}#pragma vector=P0INT_VECTOR__interrupt void Key5_ISR()//P0_5{ if(P0IFG & 0X20) { osal_start_timerEx(SimonApp_TaskID,SimonApp_MY_EVT,25); } P0IFG =0; P0IF=0;}

在应用层中自定义一个事件类型处理按键事件(在SimonApp_ProcessEvent函数进行事件类型的判断和调用相应的处理函数):

if ( events & SimonApp_MY_EVT ) { if(0==P1_1) {//按钮3按下 LS164_BYTE(3); } if(0==P2_0) {//按钮4按下 LS164_BYTE(4); } if(0==P0_5) {//按钮5按下 LS164_BYTE(5); } return (events ^ SimonApp_MY_EVT); }

关于按键中断,还需要将ZStack自带的初始化按键中断的代码屏蔽,否则有两个中断入口函数会冲突,无法正常使用按键功能!!!屏蔽hal_key.c里面的HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )函数以及HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR )函数。

关于信道

在配置文件f8wConfig.cfg中有如下内容:

/* Default channel is Channel 11 - 0x0B */// Channels are defined in the following:// 0 : 868 MHz 0x00000001// 1 - 10 : 915 MHz 0x000007FE// 11 - 26 : 2.4 GHz 0x07FFF800////-DMAX_CHANNELS_868MHZ 0x00000001//-DMAX_CHANNELS_915MHZ 0x000007FE//-DMAX_CHANNELS_24GHZ 0x07FFF800//-DDEFAULT_CHANLIST=0x04000000 // 26 - 0x1A//-DDEFAULT_CHANLIST=0x02000000 // 25 - 0x19//-DDEFAULT_CHANLIST=0x01000000 // 24 - 0x18//-DDEFAULT_CHANLIST=0x00800000 // 23 - 0x17//-DDEFAULT_CHANLIST=0x00400000 // 22 - 0x16//-DDEFAULT_CHANLIST=0x00200000 // 21 - 0x15//-DDEFAULT_CHANLIST=0x00100000 // 20 - 0x14//-DDEFAULT_CHANLIST=0x00080000 // 19 - 0x13//-DDEFAULT_CHANLIST=0x00040000 // 18 - 0x12//-DDEFAULT_CHANLIST=0x00020000 // 17 - 0x11//-DDEFAULT_CHANLIST=0x00010000 // 16 - 0x10//-DDEFAULT_CHANLIST=0x00008000 // 15 - 0x0F//-DDEFAULT_CHANLIST=0x00004000 // 14 - 0x0E//-DDEFAULT_CHANLIST=0x00002000 // 13 - 0x0D//-DDEFAULT_CHANLIST=0x00001000 // 12 - 0x0C-DDEFAULT_CHANLIST=0x00000800 // 11 - 0x0B

相当于: #define DEFAULT_CHANLIST 0x00000800

DEFAULT_CHANLIST 表明Zigbee模块要工作的网络,当有多个信道参数值进行或操作之后,把结果作为 DEFAULT_CHANLIST 值,那么对于路由器和终端 协调器的意义分别是什么

路由器和终端: 我可以在参与或操作的这些信道上选择一个相对于我来说最佳的网络,加入进去 协调器 我可以在参与或操作的这些信道上选择一个最佳的信道并在这个信道上创建自己的Zigbee网络

关于PANID

非0xFFFF 路由器和终端 我必须要加入到PANID为参数值这样一个Zigbee无线局域网

协调器来说,我要创建一个网络,并且把这个参数值作为这个网络的PANED

为0xFFFF 路由器和终端 在加入网络的时候没有PANID的限制 协调器 我可以随机生成一个值,把这个随机值作为这个网络的PANED

当2个模块下载相同的协调器代码,并且指定的PANID参数值为非0xffff,后果会怎样? 先上电的模块可以创建0xFFF8这样一个Zigbee网络,后上电的模块创建一个在0xFFF8基础上加1的网络。

ROOT

NOROOT表示如果此部分代码从来没有被调用到,那么这部分代码会被linker抛弃。一般来讲,除了startup和中断的代码都应该设为NOROOT。默认的模式为ROOT,即linker不会抛弃。

重要函数

uint8 osal_set_event( uint8 task_id, uint16 event_flag )

(1)在ZSTACK里按照代码按照功能来划分,分成不同的层,比如,硬件操作相关硬件层 网络相关的代码叫网络层 自己写应用程序部分叫应用层

(2)几乎每一个层都是一个任务,系统为每一个任务分配一个字节的唯一数值编号(任务ID)

(3)每一个任务都能处理一些他们能够处理的事务

(4)我们把这个数值编号叫做任务ID

(5)它们能够处理的事务叫做事件

(6)该函数就是通知任务ID为task_id的任务处理event_flag事件

uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value )

(1)在ZSTACK里,任务/事件定义的特点决定了,每一个任务最多只能处理16种不同的事件 (2)而系统在运行时候有许多事务需要处理,如果每一个事务处理都定义成1个事件,那么16种事件肯定是不够用,所有引入消息。 (3)只定时一次,定时溢出以后不再定时,需要重新启动定时器!与timerUpdate函数有关(软件定时器链表)

通过消息处理事务的原理:

(1)OSAL定义了一个系统默认的事件 #define SYS_EVENT_MSG 0x8000 // A message is waiting event

(2)可以自定义一个事件

(3)当需要应用层任务来处理某个事务的时候,首先给应用层任务发送一个消息–调用osal_set_event(SimonApp_TaskID,SYS_EVENT_MSG);

(4)那么这样一来,应用层就会进入SYS_EVENT_MSG处理,在这个事件处理里判断到底刚刚引发我们产生SYS_EVENT_MSG事件是哪一种类型的消息,然后根据消息的类型做相应的处理。

(5)而消息的类型可以自己定义,这样一来消息的类可以很多,那么应用层任务处理的事物种类就很多了。一般消息的类型放在消息体MSGpkt->hdr.event成员里!所以根据hdr.event判断消息类型!!

if(SDApp_NwkState == DEV_ZB_COORD) {//如果本模块成为了协调器,会进入到这来来 LS164_BYTE(11); keyChange_t *msgPtr; msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );//定义个按钮改变的消息 if ( msgPtr ) { msgPtr->hdr.event = KEY_CHANGE;//给这个消息填写相关的值,类型是按钮状态改变KEY_CHANGE msgPtr->keys=3;//消息里面的内容是3 osal_msg_send( SDApp_TaskID, (uint8 *)msgPtr );//把发送给应用层SDApp_TaskID的消息投到消息队列,并且osal_set_event( SDApp_TaskID, SYS_EVENT_MSG ); } // osal_set_event(SDApp_TaskID,SDApp_SEND_MSG_EVT); osal_start_timerEx(SDApp_TaskID,SDApp_MY_EVT,3000); }

生成HEX文件

配置截图

这里写图片描述

这里写图片描述

修改配置文件

在f8w2530.xcl里面,取消掉// Include these two lines when generating a .hex file for banked code model:下面的注释,最后如下内容:

// Include these two lines when generating a .hex file for banked code model:-M(CODE)[(_CODEBANK_START+_FIRST_BANK_ADDR)-(_CODEBANK_END+_FIRST_BANK_ADDR)]*/_NR_OF_BANKS+_FIRST_BANK_ADDR=0x8000
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表