1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > ZigBee无线传感器网络远程数据采集系统设计

ZigBee无线传感器网络远程数据采集系统设计

时间:2022-12-21 13:09:34

相关推荐

ZigBee无线传感器网络远程数据采集系统设计

ZigBee无线传感器网络远程数据采集系统设计

原理:

在实验中,协调器节点负责建立网络,路由器节点与终端节点申请加入网络,然后周期性地采集温度、电压等发送给协调器,协调器通过串口将数据发送给PC机。

协调器与路由器、采集终端编码:(实验采用CC2530-EB开发板)

//Coordinator.c

#include "OSAL.h"

#include "AF.h"

#include "ZDApp.h"

#include"ZDObject.h"

#include "ZDProfile.h"

#include <string.h>

#include"Coordinator.h"

#include"DebugTrace.h"

#include "Sensor.h"

#if !defined(WIN32)

#include"OnBoard.h"

#endif

#include"hal_lcd.h"

#include"hal_led.h"

#include"hal_key.h"

#include"hal_uart.h"

const cId_tGenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS]=

{

GENERICAPP_CLUSTERID

};

//简单设备描述符(描述一个ZigBee设备节点)

const SimpleDescriptionFormat_tGenericApp_SimpleDesc=

{

GENERICAPP_ENDPOINT,

GENERICAPP_PROFID,

GENERICAPP_DEVICEID,

GENERICAPP_DEVICE_VERSION,

GENERICAPP_FLAGS,

GENERICAPP_MAX_CLUSTERS,

(cId_t*)GenericApp_ClusterList,

0,

(cId_t *)NULL

};

endPointDesc_tGenericApp_epDesc;//节点描述符

byte GenericApp_TaskID;//任务优先级

byte GenericApp_TransID;//数据发送序列号。

voidGenericApp_MessageMSGCB(afIncomingMSGPacket_t *pckt);//消息处理函数

voidGenericApp_SendTheMessage(void);//数据发送函数

void GenericApp_Init(bytetask_id)//任务初始化函数

{

GenericApp_TaskID =task_id;//初始化任务优先级(任务优先级有协议栈的操作系统OSAL分配)

GenericApp_TransID =0; //发送数据包的序号初始化为0

//对节点描述符进行初始化

GenericApp_epDesc.endPoint=GENERICAPP_ENDPOINT;

GenericApp_epDesc.task_id=&GenericApp_TaskID;

GenericApp_epDesc.simpleDesc=(SimpleDescriptionFormat_t*)&GenericApp_SimpleDesc;

GenericApp_epDesc.latencyReq=noLatencyReqs;

afRegister(&GenericApp_epDesc);//afRegister()对节点的描述符进行注册。注册后,才能使用OSAL提供的系统服务。

halUARTCfg_t uartConfig;//该结构体变量是实现 串口的配置

//串口的初始化

uartConfig.configured=TRUE;

uartConfig.baudRate=HAL_UART_BR_115200;//波特率

uartConfig.flowControl=FALSE; //流控制

HalUARTOpen(0,&uartConfig); //串口是否打开

}

//消息处理函数

UINT16GenericApp_ProcessEvent(byte task_id,UINT16 events)

{

afIncomingMSGPacket_t* MSGpkt;//MSGpkt用于指向接收消息结构体的指针

if(events&SYS_EVENT_MSG)

{

MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID);

while(MSGpkt)

{

switch(MSGpkt->hdr.event)

{

case AF_INCOMING_MSG_CMD: //接受到新数据的消息的ID是AF_INCOMING_MSG_CMD,这个宏是在协议栈中定义好的值为0x1A

//接受到的是无线数据包

GenericApp_MessageMSGCB(MSGpkt);//功能是完成对接受数据的处理

break;

default:

break;

}

osal_msg_deallocate((uint8 *)MSGpkt);//接收到的消息处理完后,释放消息所占的存储空间

MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID);

//处理完一个消息后,再从消息队列里接受消息,然后对其进行相应处理,直到所有消息处理完

}

return (events ^ SYS_EVENT_MSG);

}

return 0;

}

//数据处理函数

voidGenericApp_MessageMSGCB(afIncomingMSGPacket_t *pkt)

{

RFTX rftx;

unsigned char changeline[2]={0x0A,0x0D};//回车换行符的ASICC码

switch(pkt->clusterId)

{

case GENERICAPP_CLUSTERID:

osal_memcpy(&rftx,pkt->cmd.Data,sizeof(rftx));//把pkt->cmd.Data的数据复制到buffer

HalUARTWrite(0,rftx.databuf,sizeof(rftx));//向串口发送数据包

HalUARTWrite(0,changeline,2);//输出回车换行符

break;

}

}

//Coordinator.h

#ifndef COORDINATOR_H

#define COORDINATOR_H

#ifdef __cplusplus

extern "C"

{

#endif

#include "ZComDef.h"

#define GENERICAPP_ENDPOINT 10

#define GENERICAPP_PROFID 0x0F04

#define GENERICAPP_DEVICEID 0x0001

#defineGENERICAPP_DEVICE_VERSION 0

#define GENERICAPP_FLAGS 0

#defineGENERICAPP_MAX_CLUSTERS 1

#define GENERICAPP_CLUSTERID 1

#defineGENERICAPP_SEND_MSG_TIMEOUT 5000

#defineGENERICAPP_SEND_MSG_EVT 0x0001

typedef union h

{

unsigned char databuf[18];

struct RFRXBUF{

unsigned char head[2];

unsigned char type[3];

unsigned char myNWK[4];//存储本节点网络地址

unsigned char pNWK[4];//存储父节点网络地址

unsigned char value[4];

unsigned char tail;//命令尾

}BUF;

}RFTX;

extern void GenericApp_Init( bytetask_id );

extern UINT16GenericApp_ProcessEvent( byte task_id, UINT16 events );

#ifdef __cplusplus

}

#endif

#endif /* GENERICAPP_H */

//Enddevice.c

#include "OSAL.h"

#include "AF.h"

#include "ZDApp.h"

#include "ZDObject.h"

#include "ZDProfile.h"

#include <string.h>

#include "Coordinator.h"

#include "DebugTrace.h"

#if !defined(WIN32)

#include "OnBoard.h"

#endif

#include "hal_lcd.h"

#include "hal_led.h"

#include "hal_key.h"

#include"Sensor.h"

#include "hal_uart.h"

#define SEND_DATA_EVENT 0x01 //定义发送事件id为0x01

const cId_tGenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS]=

{

GENERICAPP_CLUSTERID

};

//初始化端口描述符

const SimpleDescriptionFormat_tGenericApp_SimpleDesc=

{

GENERICAPP_ENDPOINT,

GENERICAPP_PROFID,

GENERICAPP_DEVICEID,

GENERICAPP_DEVICE_VERSION,

GENERICAPP_FLAGS,

0,

(cId_t*)NULL,

GENERICAPP_MAX_CLUSTERS,

(cId_t*)GenericApp_ClusterList

};

endPointDesc_t GenericApp_epDesc;//节点描述符

byte GenericApp_TaskID; //任务优先级

byte GenericApp_TransID; //数据发送序列号

devStates_t GenericApp_NwkState;//保存节点状态

voidGenericApp_MessageMSGCB(afIncomingMSGPacket_t* pckt);//消息处理函数的声明

void GenericApp_SendTheMessage(void); //数据发送函数的声明

voidsendTemp(void);

void sendVdd(void);

void To_string(uint8 *dest,char * src,uint8length);

//任务初始化函数

void GenericApp_Init(byte task_id)

{

GenericApp_TaskID = task_id;//初始化任务优先级

GenericApp_NwkState =DEV_INIT;//初始化为DEV_INIT,表节点没有连接到ZigBee网络

GenericApp_TransID =0; //发送数据包的序列号初始化为0

//对节点描述符进行初始化

GenericApp_epDesc.endPoint=GENERICAPP_ENDPOINT;

GenericApp_epDesc.task_id =&GenericApp_TaskID;

GenericApp_epDesc.simpleDesc=(SimpleDescriptionFormat_t*)&GenericApp_SimpleDesc;

GenericApp_epDesc.latencyReq=noLatencyReqs;

//afRegister()函数将节点描述符进行注册,注册后才可以使用OSAL提供的系统服务

afRegister(&GenericApp_epDesc);

}

//消息处理函数

UINT16 GenericApp_ProcessEvent(bytetask_id,UINT16 events)

{

afIncomingMSGPacket_t* MSGpkt;

if(events&SYS_EVENT_MSG)

{

MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID);

while(MSGpkt)

{

switch(MSGpkt->hdr.event)

{

case ZDO_STATE_CHANGE:

GenericApp_NwkState=(devStates_t)(MSGpkt->hdr.status);//读取节点的设备类型

if((GenericApp_NwkState==DEV_END_DEVICE)||(GenericApp_NwkState==DEV_ROUTER))

{

//当中断节点加入网络后使用osal_set_envent()函数设置SEND_DATA_EVENT事件,当事件发生时,执行事件处理函数

osal_set_event(GenericApp_TaskID,SEND_DATA_EVENT);//添加用户自定义任务事件(以任务号对应事件的形式添加)

}

break;

default:

break;

}

osal_msg_deallocate((uint8*)MSGpkt); // 接收到的消息处理完后,释放消息所占的存储空间

MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID);

} //处理完一个消息后,再从消息队列里接受消息,然后对其进行相应处理,直到所有消息处理完

return (events^SYS_EVENT_MSG);

}

if(events&SEND_DATA_EVENT)//(区分事件 )

{

sendTemp();

sendVdd();

osal_start_timerEx(GenericApp_TaskID,SEND_DATA_EVENT,5000);

//定时器,三个参数:

//一参:表定时事件到后,那个任务对其作出响应

//二参:表时间达到后,什么事件发生,该事件的处理函数中实现数据的发送(用户应用)。

//三参:定时的时间数量,单位毫秒。

return (events^SEND_DATA_EVENT);//清除事件标志(该事件已被处理)

}

return 0;

}

//温度检测函数

void sendTemp()

{

RFTX rftx;

uint16 tempvalue ;

uint16 nwk;

tempvalue = readTemp();//读取温度数据

rftx.BUF.value[0] = 'W';//表示温度数据

rftx.BUF.value[1] = tempvalue /10+'0';

rftx.BUF.value[2] = tempvalue %10+'0';//将温度数据转换为ASCII码

rftx.BUF.value[3] = '*';

osal_memcpy(rftx.BUF.head,"&&",2);

if(GenericApp_NwkState == DEV_ROUTER)//路由器加入网络

{

osal_memcpy(rftx.BUF.type,"ROU",3);

}

if(GenericApp_NwkState == DEV_END_DEVICE)//终端节点加入网络

{

osal_memcpy(rftx.BUF.type,"END",3);

}

nwk= NLME_GetShortAddr();

To_string(rftx.BUF.myNWK,(uint8 *)&nwk,2);

nwk= NLME_GetCoordShortAddr();

To_string(rftx.BUF.pNWK,(uint8 *)&nwk,2);

rftx.BUF.tail = '&';//填充命令尾

afAddrType_t my_DstAddr;

my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;//使用单播格式

my_DstAddr.endPoint=GENERICAPP_ENDPOINT;//目的端口号

my_DstAddr.addr.shortAddr=0x0000;//协调器网络地址为0x0000

AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,

GENERICAPP_CLUSTERID,//簇号

18, //发送的数据长度

(uint8 *)&rftx, //发送数据缓冲区

&GenericApp_TransID, //发送序列号

AF_DISCV_ROUTE,

AF_DEFAULT_RADIUS);//调用数据发送函数AF_DataRequest()进行数据发送

}

//电压检测函数

void sendVdd()

{

RFTX rftx;

uint16 vddvalue ;

uint16 nwk;

vddvalue = 69*getVddvalue()/256;

rftx.BUF.value[0] = 'V';//表示电压数据

rftx.BUF.value[1] = vddvalue /10+'0';

rftx.BUF.value[2] ='.';

rftx.BUF.value[3] = vddvalue %10+'0';

if(GenericApp_NwkState == DEV_ROUTER)

{

osal_memcpy(rftx.BUF.type,"ROU",3);

}

if(GenericApp_NwkState == DEV_END_DEVICE)

{

osal_memcpy(rftx.BUF.type,"END",3);

}

nwk= NLME_GetShortAddr();

To_string(rftx.BUF.myNWK,(uint8 *)&nwk,2);

nwk= NLME_GetCoordShortAddr();

To_string(rftx.BUF.pNWK,(uint8 *)&nwk,2);

rftx.BUF.tail = '&';

afAddrType_t my_DstAddr;

my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;

my_DstAddr.endPoint=GENERICAPP_ENDPOINT;

my_DstAddr.addr.shortAddr=0x0000;

AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,

GENERICAPP_CLUSTERID,

18,

(uint8 *)&rftx,

&GenericApp_TransID,

AF_DISCV_ROUTE,

AF_DEFAULT_RADIUS);

}

//将二进制数据转化成十六进制

void To_string(uint8 *dest,char * src,uint8length)

{

uint8 *xad;

uint8 i = 0;

uint8 ch;

xad = src +length -1;

for(i=0;i<length;i++,xad--)

{

ch = (*xad>>4)&0x0f;

dest[i<<1] = ch + ((ch<10) ?'0':'7');

ch = *xad &0x0f;

dest[(i<<1)+1] = ch +((ch<10)?'0':'7');

}

}

// Sensor.c

#include "Sensor.h"

#include <ioCC2530.h>

#define ADC_REF_115V 0X00

#define ADC_DEC_256 0X20

#define ADC_CHN_TEMP 0X0e

#define ADC_DEC_064 0X00

#define ADC_CHN_VDD3 0X0F

int8 readTemp(void)

{

static uint16 reference_voltage;

static uint8 bCalibrate =TRUE;

unsigned char tmpADCCON3=ADCCON3;

uint16 value;

int8 temp;

ATEST =0X01;//使能温度传感器

TR0|= 0X01;//连接温度传感器

ADCIF=0;

ADCCON3=(ADC_REF_115V|ADC_DEC_256|ADC_CHN_TEMP );

while(!ADCIF);

ADCIF=0;

value =ADCL;

value|=((uint16)ADCH)<<8;

value>>=4;

ADCCON3=tmpADCCON3;

if(bCalibrate) //记录第一次读取的温度值,用于校正温度数据

{

reference_voltage=value;

bCalibrate=FALSE;

}

temp=22+((value-reference_voltage)/4);

return temp;

}

unsigned int getVddvalue(void){

unsigned int value;

unsigned char tmpADCCON3;

ADCIF=0;

ADCCON3=(ADC_REF_115V|ADC_DEC_064|ADC_CHN_VDD3 );

while(!ADCIF);

value=ADCH;

ADCCON3=tmpADCCON3;

return (value);

}

// Sensor.h

#ifndef SENSOR_H

#define SENSOR_H

#include <hal_types.h>

extern int8 readTemp(void);

extern unsigned int getVddvalue(void);

typedef struct {

char Head;//命令头

char value[2];

char Tail;//命令尾

}BUFer;

typedef struct {

BUFer BUF;

}TEMPERATURE;

#endif

// OSAL_GenericApp.c

#include "ZComDef.h"

#include "hal_drivers.h"

#include "OSAL.h"

#include "OSAL_Tasks.h"

#if defined ( MT_TASK )

#include "MT.h"

#include "MT_TASK.h"

#endif

#include "nwk.h"

#include "APS.h"

#include "ZDApp.h"

#if defined ( ZIGBEE_FREQ_AGILITY ) ||defined ( ZIGBEE_PANID_CONFLICT )

#include "ZDNwkMgr.h"

#endif

#if defined ( ZIGBEE_FRAGMENTATION )

#include "aps_frag.h"

#endif

#include "Coordinator.h"

// The order in this table must beidentical to the task initialization calls below in osalInitTask.

const pTaskEventHandlerFn tasksArr[] = {

macEventLoop,

nwk_event_loop,

Hal_ProcessEvent,

#if defined( MT_TASK )

MT_ProcessEvent,

#endif

APS_event_loop,

#if defined ( ZIGBEE_FRAGMENTATION )

APSF_ProcessEvent,

#endif

ZDApp_event_loop,

#if defined ( ZIGBEE_FREQ_AGILITY ) ||defined ( ZIGBEE_PANID_CONFLICT )

ZDNwkMgr_event_loop,

#endif

GenericApp_ProcessEvent//任务的事件处理函数

};

const uint8 tasksCnt = sizeof( tasksArr ) /sizeof( tasksArr[0] );//定义变量保存任务总个数

uint16 *tasksEvents;//定义变量指向事件表首地址

void osalInitTasks( void )

{

uint8 taskID = 0;

tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);

osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

macTaskInit( taskID++ );

nwk_init( taskID++ );

Hal_Init( taskID++ );

#if defined( MT_TASK )

MT_TaskInit( taskID++ );

#endif

APS_Init( taskID++ );

#if defined ( ZIGBEE_FRAGMENTATION )

APSF_Init( taskID++ );

#endif

ZDApp_Init( taskID++ );

#if defined ( ZIGBEE_FREQ_AGILITY ) ||defined ( ZIGBEE_PANID_CONFLICT )

ZDNwkMgr_Init( taskID++ );

#endif

GenericApp_Init( taskID );//任务的初始化函数

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。