11 Z-Stack协议栈使用
f8wConfig.cfg文件
选择信道、设置PAN ID
选择信道
#define DEFAULT_CHANLIST 0x00000800
DEFAULT_CHANLIST
表明Zigbee模块要工作的网络,当有多个信道参数值进行或操作之后,把结果作为 DEFAULT_CHANLIST
值
对于路由器、终端、协调器的意义:
- 路由器和终端:
- 可以在参与或操作的这些信道上选择一个相对于我来说最佳的网络,加入进去
- 协调器
- 可以在参与或操作的这些信道上选择一个最佳的信道并在这个信道上创建自己的Zigbee网络
选择PAN ID
-
非0xFFFF
- 路由器和终端:必须要加入到PANID为参数值这样一个Zigbee无线局域网
- 协调器:要创建一个网络,并且把这个参数值作为这个网络的PANED
-
为0xFFFF
- 路由器和终端:在加入网络的时候没有PANID的限制
- 协调器:可以随机生成一个值,把这个随机值作为这个网络的PANED
当2个模块下载相同的协调器代码,并且指定的PANID参数值为非0xffff时,
先上电的模块可以创建0xFFF8这样一个Zigbee网络,后上电的模块创建一个在0xFFF8基础上加1的网络。
响应任务事件
硬件层 :硬件操作相关
网络层 :网络相关的代码
应用层:自己写应用程序部分
- 几乎每一个层都是一个任务,系统为每一个任务分配一个,一个字节的唯一数值编号,每一个任务都能处理一些他们能够处理的事物
- 任务ID:这个数值编号叫做
- 事件:它他们能够处理的事物
1 | /* |
在工程中进行测试
- 在
TestAPP.c
文件中,找到UINT16 TestAPP_ProcessEvent( byte task_id, UINT16 events )
函数 - 在之前写的三种模式的测试代码下添加如下语句
1 | osal_set_event(TestAPP_TaskID,TestAPP_SEND_MSG_EVT); |
- 在该函数中进行向下找,看到对
TestAPP_SEND_MSG_EVT
事件的响应代码,进行如下处理:
1 | P0DIR |= 0X02; |
- x 1%第八题2A = [2, 4, 5, 8, 10];3B = [4, 6, 9, 3, 4];4n = length(A);56result = 0;78for i = 1:n9 result = result + A(i) * B(n - i + 1);10end1112disp(result);matlab
- 实验现象:跳到
TestAPP_SEND_MSG_EVT
事件的响应代码,LED2亮
软件定时器响应事件
1 | /* |
实验验证
1 | osal_start_timerEx(TestAPP_TaskID,TestAPP_SEND_MSG_EVT,2000); |
- 注释掉刚才写的
osal_set_event
函数,将osal_start_timerEx
函数写在下面
- 编译下载,观察实验现象
- 延时2秒后亮
定义事件
格式为
#define 事件名 0x000?
?可以是十六进制的数,最多定义16个时间 0 ~ F必须保证3个0,位置随意
实验验证
- 在
TestAPP.h
文件中,定义事件
格式为 #define 事件名 0x000? ?可以是十六进制的数,最多定义16个时间 0 ~ F
必须保证3个0,位置随意
1 | //格式为 #define 事件名 0x000? ?可以是十六进制的数,最多定义16个时间 0 ~ F |
- 如下
- 在
TestAPP.c
文件中,找到刚才的UINT16 TestAPP_ProcessEvent( byte task_id, UINT16 events )
函数,在最后一个事件响应代码下,添加新的事件响应代码
1 | if ( events & TestAPP_EVT ){ |
- 添加本事件的响应事件函数
- 编译,下载,灯亮
初始化要全面,因为使用的是TI官方代码移植的,他官方例程中可能也配置了这个IO口,我们在这里重新配置的时候必须要全面配置,否则这个IO口可能默认不是通用IO
消息
在ZSTACK里,任务事件定义的特点决定了,每一个任务最多只能处理16种不同的事件,而系统在运行时候有许多事务需要处理,如果每一个实物处理都定义成1个事件,那么16种事件肯定是不够用,所有引入消息。
消息的处理事务的原理:
定义了一个事件#define SYS_EVENT_MSG 0x8000 // A message is waiting event
当需要应用层任务来处理某个事务的时候,首先给应用层任务发送一个消息
掉osal_set_event(SDApp_TaskID,SYS_EVENT_MSG);
那么这样一来,应用层就会进入SYS_EVENT_MSG处理,在这个事件处理里判断到底刚刚引发我们产生SYS_EVENT_MSG事件是哪一种类型的消息,然后根据消息的类型做相应的处理。
而消息的类型可以自己定义,这样一来消息的类可以很多,那么应用层任务处理的事物种类就很多了。
实验验证
- 将
TestAPP.c
文件中的void TestAPP_HandleKeys( byte shift, byte keys )
函数下的所有内容清空,然后调用数码管显示函数
- 在
TestAPP_ProcessEvent
函数注释掉之前调用的osal_start_timerEx
,将下面的函数添加到下面
1 | // 定义一个名为keyChange_t的结构体指针msgPtr |
- 编译,下载,数码管显示按键数字,表示无误
按键实验(协议栈实现)
- 添加封装好的代码到工程中
Key.c
根据自己的实际情况,更改里面的文件名和事件名
1 |
|
Key.h
1 |
|
- 引用头文件,初始化。【初始化函数一定要放到
osal_start_system();
之前】
- 屏蔽官方例程中的中断函数。【hal-target-CC2530EB-drivers】里面的
HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR )
和HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
- 将
TestAPP.c
文件中的之前定义的TestAPP_EVT
事件响应进行修改,如下所示
1 | if ( events & TestAPP_EVT ){ |
- 下载,实验现象:按下按键灯亮灭交替,数码管显示按键编号
使用协议栈生成hex文件注意
-
配置项目工程,可以生成hex,之前在生成工程里面说过如何设置
-
在
f8w2530.xc
文件中,将下面两行的注释去掉