目录
一、知识说明
1.ZStack协议栈
a.工作原理
TI公司提供ZStack协议的时候,本质上已经把协议栈当作是一个操作系统来实现的。ZStack将整个协议栈按照功能分成了8层,每一层对应不同的功能代码,在ZStack将每一层当作是一个“任务”task。即ZStack协议栈共有8个任务,并且每一层可以配置至多16个事件。用一个无符号16位整数的位域法(不同的位表示不同的事件),具体的事件的含义和事件的处理方式均由用户自行指定的,同时每个事件可以划分不同的消息,每一个事件最多可以有65535个消息,消息其实就是同一个事件的不同的处理方式。
Z-Stack协议栈是一个 基于任务轮询方式 的操作系统,其任务调度和资源分配由操作系统抽象层OSAL管理着。 总体来看, Z-Stack协议栈只做了两件事情:首先进行系统的初始化,然后启动OSAL操作系统。 在任务轮询过程中,系统将会不断查询每个任务是否有事件发生,如果有事件发生,就执行相应的事件处理函数,如果没有事件发生,则查询下一个任务。
b.产生原因及作用
ZSTask协议栈是为了解决无线传感器网络(WSN)应用程序开发中的一些问题而出现的。WSN是由大量的无线传感器节点组成的网络,这些节点通常具有有限的计算能力、存储能力和能源供应。在WSN中,节点之间需要进行通信和协调,以完成各种任务,如数据采集、监测、控制等。然而,WSN应用程序开发面临着一些挑战,如:
- 复杂的网络拓扑结构和路由算法
- 节点能耗的限制
- 节点之间的通信和协调
为了解决这些问题,ZSTask协议栈提供了一种基于事件驱动的编程模型,以简化WSN应用程序的开发。它使用轻量级消息传递机制来实现任务之间的通信和协调,同时提供了一些常用的网络协议,如路由、MAC和物理层协议。使用ZSTask协议栈,开发人员可以更容易地实现WSN应用程序,提高开发效率,降低开发成本。
ZSTask协议栈可以用于各种WSN应用程序的开发,如环境监测、智能家居、工业自动化等。它可以实现数据采集、数据传输、节点协调等功能,为WSN应用程序提供了一个高效、可靠、灵活的开发平台。
c.工作流程
2. 事件的产生和处理
a.自定义事件
Zstack中的事件,其实就是一个无符号16位的整数其中的一个bit位(事件其实就是用一个整数的不同的bits位来表示不同的事件)。自定义应用层事件,只需要在GenericApp.h(LINE14)文件中,新增一个与其他事件不冲突的宏即可。
#define GENERICAPP_MY_EVT 0x0008
b.osal_set_event立即事件
extern uint8 osal_set_event( uint8 task_id, uint16
event_flag );
@task_id:指定任务ID,表示本事件产生后由哪一层的事件处理
函数来处理。
@event_flag:指定产生的事件
返回值:
成功SUCCESS
失败INVALID_TASK
例如:在应用层产生 GENERICAPP_MY_EVT
osal_set_event(GenericApp_TaskID,GENERICAPP_MY_EVT);
c.osal_start_timerEx延时产生事件
extern uint8 osal_start_timerEx( uint8 task_id,
uint16 event_id, uint16 timeout_value );
@task_id:指定任务ID,表示本事件产生后由哪一层的事件处理
函数来处理。
@event_id:指定产生的事件
@ timeout_value :指定超时事件,单位位ms
返回值:
成功 :SUCCESS
失败:NO_TIMER_AVAIL
调用上述函数产生事件的时候,事件并不会立即就添加到全局变量数组中,而是超时事件到来后,才会产生事件。上述函数本质是配置了一个定时器,当定时器事件到来后,才会将事件添加到全局任务事件数组中。
d.增加事件处理代码
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16
events )
{
...
if ( events & GENERICAPP_MY_EVT )
{
//...
return (events ^ GENERICAPP_SEND_MSG_EVT);
}
}
3.按键初始化
按键有两种方式,轮询和中断,本次实验使用的是外部中断的形式
#define KEY P1_2
void key_init(void)
{
P1SEL &= ~(1<<2);
P1DIR &= ~(1<<2);
P1INP &= ~(1<<2);
P2INP &= ~(1<<6);//第6位置为上拉为0,所有端口1引脚设置为上拉/下拉输入
P1IEN |= 0X04; //P1.2中断使能
PICTL |= 0X02; //P1口下降沿触发
IEN2 |= 0x10; //0001 0000 允许P1口中断
EA = 1; //总中断使能
}
中断是什么?
打断,执行,返回
每个中断处理都要经历这个保存和恢复过程,我们可以抽象出其中的步骤:
1. 保存现场
2. 执行具体的中断服务程序
3. 从中断服务返回
4. 恢复现场
4.ZStack协议栈组网
a.协调器节点coordinatorEB
整个ZStack无线网络中的起始节点,负责产生无线网络,一旦烧写协调器的代码的节点上运行,首要的任务就是产生一个无线网络,并且在该无线网络中,协调器节点的网络地址固定为0x0000(类似于互联网的IP)。
b.路由器节点RouterEB
路由器在ZStack无线网络中,主要是负责拓展无线网络的传输,因为路由器可以作为一个中转站,在路由器加入协调器产生的无线网络后,可以作为父节点介绍其他的路由器或者终端节点加入到当前的无线网络。
路由器的工作如下
1.上电后搜索附近的Zigbee无线网络,并尝试加入该网络
2.负责接收附近其余节点的入网请求,并将允许加入到无线网络
3.除了上述两个工作外,路由器和终端节点功能类似
c.终端节点EndDeviceEB
终端节点是整个Zigbee无线网中最末端的设备,在上电后只能搜索附近的无线网络并申请加入,加入无线网络后通常是负责传感器的数据采集,并且把采集的数据不处理通过无线网络上传到协调器或者路由器。
三者之间的关系是:在实现单播的时候,每两者都可以实现通信,终端和终端通信需要加入路由器
d.信道
Zigbee无线通信,需要高频的载波来提供发射功率,zigbee模块之间要可以正常通信,接收模块和发送模块的频率要一致。Zigbee有27个载波可以进行通信,载波又叫做信道,这些载波的频
率落在某些频率区段,我们把这些区段叫做频段。
2.4G频段 16个信道(从2.4GHZ开始 每隔5MHZ 就是一个信道)
915M频段 896M频率 11个信道
但是TI所有的支持ZIGBEE底层协议的芯片只能在2.4GHZ频段的16个信道进行通信。即11~26信道(0~10信道在915M频段 896M频率)
e.PAN-ID
PANID指网络编号,用于区分不同的 ZigBee 网络。设备的 PANID 值与 ZDAPP_ CONFIG_PAN_ID值的设置有关。
如果协调器的ZDAPP_ CONFIG_PAN_ID设置为 OxFFFF ,则协调器将产生一个随机的 PANID .
如果路由器和终端节点的ZDAPP_ CONFIG_PAN_ID设置为0xFFFF,路由器和终端节点将会在自己的默认信道上随机选择一个网络加人。
如果协调器的ZDAPP_ CONFIG_PAN_ID 设置为非 OxFFFF 值,则协调器根据自身的网络长地址( IEEE 地址)或 ZDAPP_ CONFIG_PAN_ID值随机产生 PANID 。
如果路由器和终端节点ZDAPP_ CONFIG_PAN_ID值设置为非 OxFFFF 值,则会以 ZDAPP_ CONFIG_PAN_ID值作PANID 。
如果协调器的 PANID 的设置值为小于等于 Ox3FFF 的有效值,协调器就会以这个特定的 PANID值建立网络,但是,如果在默认信道上已经有该 PANID 值的网络存在,则协调器会继续搜寻其他PANID ,直到找到网络不冲突为止。这样,就有可能产生一些问题:如果协调器因为在默认信道上发生 PANID冲突而更换 PANID ,而终端节点并不知道协调器已经更换 PANID还是继续加入到 PANID 为 ZDAPP_ CONFIG_PAN_ID值的网络中。
5.zigbee
a.什么是Zigbee
ZigBee是一种近距离、低复杂度的双向无线通信系统,主要用于距离短、功耗低、传输速率不高的电子设备之间进行数据传输,且具有低功耗、低成本、大容量、时延短、可靠性高以及网络拓扑结构灵活的特点。
Zigbee本质就是无线设备之间的一种通信方式,类似于人和人之间用普通话交流,普通话就是一种通信方式。Zigbee,Zigbee通信方式,Zigbee协议说的都是一回事。
Zigbee的主要作用是用来构建无线局域网。
b.各无线通信方式间的比较
蓝牙:功耗比较低,组建网络节点数少(7~8个)
WIFI:通信速率比较大,功耗大,等等
Zigbee:
优点:可以组建大规模的网络,功耗低(TI cc2530正常工作电流8mA,最低工作电流只有几uA)
缺点:通信速率比较小( 250KBPS)
注意:Zigbee只是完成数据通信的工作,要实现具体的使用的功能系统,一般会把Zigbee模块连接到计算机(处理器),计算机通过编好的程序来对整个系统进行监控。
二、代码详解
1.按键初始化
void key_init(void)
{
P1SEL &= ~(1<<2);
P1DIR &= ~(1<<2);
P1INP &= ~(1<<2);
P2INP &= ~(1<<6);//第6位置为上拉为0,所有端口1引脚设置为上拉/下拉输入
P1IEN |= 0X04; //P1.2中断使能
PICTL |= 0X02; //P1口下降沿触发
IEN2 |= 0x10; //0001 0000 允许P1口中断
EA = 1; //总中断使能
}
2.led灯初始化
void led_init(void)
{
P1SEL &= ~0x03;
P1DIR |=0x03;
LED1=0;
LED2=0;
}
3.延时一毫秒
void delay_ms(int ms)
{
int i,j;
for(i=0;i<ms;i++)
for(j=0;j<587;j++);
}
4.外部中断初始化函数
#pragma vector =P1INT_VECTOR
__interrupt void P1_ISR(void)
{
if(P1IFG & 0X04)
{
delay_ms(12);
if(KEY == 0)
{
osal_start_timerEx( GenericApp_TaskID,GENERICAPP_MY_EVT,10);
//产生一个十毫秒的自定义事件GENERICAPP_MY_EVT
}
}
P1IFG=0;
P1IF=0;
}
5.事件处理函数
if ( events & GENERICAPP_MY_EVT )
{
LED1 = !LED1;
LED2 = !LED2;
return (events ^ GENERICAPP_MY_EVT);
}
三、详细代码
链接:https://pan.baidu.com/s/1ZIEbkD3tQ7uHR_J14wTLnA?pwd=8888
提取码:8888