什么是zigbee
无线传感网络的无线通信技术可以采用zigbee,蓝牙,wifi和红外
Zigbee技术是一种短距离,低复杂度,低功耗,低成本,低数据速率的双向无线通信技术,是一组基于IEEE802.15.4无线标准研制开发的有组网,安全和应用软件方面的通信技术
Zigbee应用范围
智能家居 - 对家用电器的控制和家庭娱乐系统的管理
楼宇自动化 - 整合并集中管理照明,采暖,制冷和安全和采集周围环境
工业自动化 - 利用传感器采集工业生产过程中的数据并进行分析和处理,提高工业产生的安全性
医学领域 - 将借助于各种传感器和Zigbee网络,准确而且实时的检测每个病人的血压,体温和心跳速度等信息
Zigbee协议体系结构
我们在学习网络的时候了解到网络的软件架构是按照分层的思想设计的,每个层负责不同功能,如典型的有OSI协议参考模型以及TCP/IP协议模型
zigbee协议也是在OSI参考模型上,结合无线网络的特点,采用分层思想实现
Zigbee标准将网络节点按照功能分为 协调器 (Coordinator),路由器(Router), 终端设备(EndDevice)
协调器:
为每个设备分配一个唯一的网络地址
为整个网络选择一个唯一的16位的PAN ID(个域网标志符),通过这个ID,网络中的设备就可以通过网络地址来相互通信
初始化,终止,转发网络中的信息
路由器:
允许设备加入网络,扩展网络覆盖的物理范围和数据包路由的功能
终端设备
主要负责无线网络数据的采集
点亮LED的硬件电路
寄存器 :
程序 代码:
#include "iocc2530.h"
#define LED1 P1_0
#define LED2 P1_1
#define LED3 P1_4
#define LED_NO 0
#define LED_OFF 1
void led_init(void);
void delay(unsigned int time);
int mian(void)
{
led_init();
while(1)
{
LED1 = LED_ON;
delay(10);
LED1 = LED_OFF;
delay(10);
LED2 = LED_ON;
delay(10);
LED2 = LED_OFF;
delay(10);
LED3 = LED_ON;
delay(10);
LED3 = LED_OFF;
delay(10);
}
}
void led_init(void)
{
P1SEL &= ~(1 << 0); //普通I/O口
P1DIR |= (1 << 0); //输出模式
LED1 = LED_OFF; //关灯
P1SEL &= ~(1 << 1);
P1DIR |= (1 << 1);
LED2 = LED_OFF;
P1SEL &= ~(1 << 4);
P1DIR |= (1 <<4);
LED3 = LED_OFF;
}
void delay(unsigned int time)
{
unsigned int i,j;
for(i = 0; i < time; i++)
{
for(j = 0; j < 10000; j++)
{
}
}
}
串口通信:
添加头文件:
#include "MT_UART.H"
#include "string.h"
在 void SampleApp_Init(uint8 task_id)函数里添加
MT_UartInit();
在 void SampleApp_Init(uint8 task_id)函数里添加
HalUARTWrite(0,"",strlen())
协议栈
OSAL
Zigbee协议栈的实时操作系统
操作系统抽象层 - Operating System Abstraction Layer
作用: 任务调度,资源分配和管理
关键字:任务与事件
taskCnt ——任务个数
taskEvents —— 指向事件表首地址的指针
taskArry —— 数组,数组中的每个元素都指向事件处理函数的指针
协议栈运行机制
入口在Zmain文件下,Zmain.c的main函数中,其中包含了各种硬件和协议栈的初始化,直到调用osal_start_system()函数,协议栈才开始真正运行起来
int main(void)
{
//...
//...
osal_start_system(); //No Return from here
return 0; //Shouldn't get here
}
在 OSAL_SampleApp.c 中找 SampleApp_ProcessEvent
#define SYS_EVENT_MSG 0x8000
#define SAMPLEAPP_SEND_PERIODIC_MSG_EVT 0x0001
//如果这俩个事件同时发生,则events = 0x8001
//异或运算,同为0 , 异为 1
events ^ SYS_EVENT_MSG = 0x001 //则只剩下后一个事件
events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT = 0x8000 //只剩下前一个事件
if (events & SYS_EVENT_MSG)
{
//...
//...
}
设备间对话
功能要求
协调器组建 PAN 网络
协调器组网成功后会周期性广播“ I am coordinator device” 5s
终端设备节点加入该PAN网络,加入网络成功后周期性广播字节串“I am endpoint device” 5s
实现过程
void SampleApp_SendPeriodicMessage(void)
{
if(AF_DataRaquest(&SampleApp_Periodic_DstAddr,
&SampleApp_eqDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
1,
(uint8 *)&SampleAppPeriodicCounter,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS) == afStatus_SUCCESS)
{
}
else
{
}
}
发送数据函数
AF_DataRequest(afAddrType_t * dstAddr, //目标设备地址
endPointDesc_t * srcFP, //端口描述符
uint16 cID, //命令号
uint16 len, //数据长度
uint8 * buf, //数据
uint8 * transID, //发送数据包序列号
uint8 options, //有效位掩码的发送选项 一般设 AF_DISCV_ROUTE
uint8 radius) //传送跳数或半径 一般设 AF_DEFAULT_RADIUS
地址结构体
typedef struct
{
union
{
uint16 shortAddr; //网络地址,该地址是设备在加入网络时由协议栈分配的
ZLongAddr_t extAddr; //64位扩展地址,全球唯一
}addr;
afAddrMode_t addrMode; //地址模式(广播,组播,单播)
byte endPoint; //端口号,可供范围1 ~ 240
uint16 panId; //一个无线网络的网络号
}afAddrType_t;
发送模式结构体
typedef enum
{
afAddrNotPresent = AddrNotPresent, //当前地址不存在
afAddr16Bit = Addr16Bit, //用于单播
afAddr64Bit = Addr64Bit, //用于单播
afAddrGroup = AddrGroup, //用于组播
afAddrBroadcast = AddrBroadcast //用于广播
}afAddrMode_t;
端口描述符
typedef struct
{
byte endPoint; //端口号
byte * task_id; //指定哪一个任务
SimpleDescriptionFormat_t * simpleDesc; //设备简单描述符
afNetwordkLatencyReq_t latencyReq; //延时请求
}endPointDesc_t;
设备简单描述符
typedef struct
{
byte EndPoint; //端口号
uint16 AppProfld; //规范号,一个规范定义一个应用领域,
uint16 AppDeviceId; //设备类型ID
byte AppDevVer:4; //应用设备版本号
byte Reserved:4; //保留位
byte AppNumInClusters; //输入簇的列表
cId_t *pAppInClusterList; //输入簇的列表
byte AppNumOutClusters; //输出簇的个数
cId_t *pAppOutClusterList; //输出簇的列表
}SimpleDescriptionFormat_t;
规范
在Zigbee网络中进行数据收发都是建立在应用规范基础上,每个应用规范都有一个ID来标识,应用规范又可以分为公共规范和制造商特定规范,公共规范ID的范围是0x0000 ~ 0x7FFF,制造商特定规范ID的范围0xBF00 ~ 0xFFFF
簇(cluster)
簇是一个应用领域下的一个特定对象,例如:智能家居中有这个调光器需要一些命令,实现这些操作需要不同的命令,多个操作命令的集合叫簇
在设备简单描述符中需要填充输入簇和输出簇,填充时需要注意:
消息发送方需把命令放在输出簇里,那么消息接受方需要把同样的命令放在输入簇里,之前的设备间第一次通话,由于输入簇和输出簇是一样的,所以协调器和终端设备间也能正常通信