选择信道、设置PAN ID
#define DEFAULT_CHANLIST 0x00000800
DEFAULT_CHANLIST
表明Zigbee模块要工作的网络,当有多个信道参数值进行或操作之后,把结果作为 DEFAULT_CHANLIST
值
对于路由器、终端、协调器的意义:
非0xFFFF
为0xFFFF
当2个模块下载相同的协调器代码,并且指定的PANID参数值为非0xffff时,
先上电的模块可以创建0xFFF8这样一个Zigbee网络,后上电的模块创建一个在0xFFF8基础上加1的网络。
硬件层 :硬件操作相关
网络层 :网络相关的代码
应用层:自己写应用程序部分
- 几乎每一个层都是一个任务,系统为每一个任务分配一个,一个字节的唯一数值编号,每一个任务都能处理一些他们能够处理的事物
- 任务ID:这个数值编号叫做
- 事件:它他们能够处理的事物
/*
*task_id:任务ID
*event_flag:任务事件
*/
uint8 osal_set_event( uint8 task_id, uint16 event_flag )
TestAPP.c
文件中,找到UINT16 TestAPP_ProcessEvent( byte task_id, UINT16 events )
函数osal_set_event(TestAPP_TaskID,TestAPP_SEND_MSG_EVT);
TestAPP_SEND_MSG_EVT
事件的响应代码,进行如下处理: P0DIR |= 0X02;
P0_1 = 0;
P0DIR语句前
和 LS164_BYTE(11)
语句前打断点,然后再路由器的工程下进行编译,然后烧录代码,下载后全速执行、单步调试TestAPP_SEND_MSG_EVT
事件的响应代码,LED2亮/*
*taskID:任务ID
*event_id:任务事件
*timeout_value:超时时间(毫秒),多长时间处理一次
*/
uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value )
osal_start_timerEx(TestAPP_TaskID,TestAPP_SEND_MSG_EVT,2000);
osal_set_event
函数,将osal_start_timerEx
函数写在下面格式为
#define 事件名 0x000?
?可以是十六进制的数,最多定义16个时间 0 ~ F必须保证3个0,位置随意
TestAPP.h
文件中,定义事件格式为 #define 事件名 0x000? ?可以是十六进制的数,最多定义16个时间 0 ~ F
必须保证3个0,位置随意
//格式为 #define 事件名 0x000? ?可以是十六进制的数,最多定义16个时间 0 ~ F
//必须保证3个0,位置随意
#define TestAPP_EVT 0x0002
TestAPP.c
文件中,找到刚才的UINT16 TestAPP_ProcessEvent( byte task_id, UINT16 events )
函数,在最后一个事件响应代码下,添加新的事件响应代码 if ( events & TestAPP_EVT ){
//初始化要全面,因为使用的是TI官方代码移植的,他官方例程中可能也配置了这个IO口,我们在这里重新配置的时候必须要全面配置,否则这个IO口可能默认不是通用IO
P0SEL &=0XEF;//1110 1111
P0DIR |= 0X10;
P0_4 = 0;
return (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
,将下面的函数添加到下面// 定义一个名为keyChange_t的结构体指针msgPtr
keyChange_t *msgPtr;
//定义按键响应消息
msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
if ( msgPtr ){
// 将消息头部的事件设置为KEY_CHANGE
msgPtr->hdr.event = KEY_CHANGE;
// 将键值设置为3
msgPtr->keys=3;
//将发送给TestAPP_TaskID任务的消息压入消息队列,并响应系统事件osal_set_event(TestAPP_TaskID,SYS_EVENT_MSG);
osal_msg_send( TestAPP_TaskID, (uint8 *)msgPtr );
}
Key.c
根据自己的实际情况,更改里面的文件名和事件名
#include
#include "TestApp.h"
#include "OSAL_Timers.h"
extern unsigned char TestAPP_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(TestAPP_TaskID,TestAPP_EVT,25);
}
P1IFG =0;
P1IF=0;
}
#pragma vector=P2INT_VECTOR
__interrupt void Key4_ISR()//P2_0
{
if(P2IFG & 0X01)
{
osal_start_timerEx(TestAPP_TaskID,TestAPP_EVT,25);
}
P2IFG =0;
P2IF=0;
}
#pragma vector=P0INT_VECTOR
__interrupt void Key5_ISR()//P0_5
{
if(P0IFG & 0X20)
{
osal_start_timerEx(TestAPP_TaskID,TestAPP_EVT,25);
}
P0IFG =0;
P0IF=0;
}
Key.h
#ifndef KEY_H
#define KEY_H
void KeysIntCfg();
#endif
osal_start_system();
之前】HAL_ISR_FUNCTION( halKeyPort2Isr, P2INT_VECTOR )
和HAL_ISR_FUNCTION( halKeyPort0Isr, P0INT_VECTOR )
TestAPP.c
文件中的之前定义的TestAPP_EVT
事件响应进行修改,如下所示 if ( events & TestAPP_EVT ){
P0SEL &=0XEF;//1110 1111
P0DIR |= 0X10;
P0_4 ^= 1;
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 ^ TestAPP_EVT);
}
配置项目工程,可以生成hex,之前在生成工程里面说过如何设置
在f8w2530.xc
文件中,将下面两行的注释去掉