通过前面两节的简单介绍,可能我们还是不知道具体怎样去建立一个zigbee网络,下面我将简单的创建一个无线温度检测实验,通过利用终端节点采集温度数据,并无线发送给协调器,协调器接收到数据后,通过串口发送给上位机,这里的上位机可以是一个简单的串口调试小助手,网上有很多这样的小程序,你们随意下载一个就行。
首先安装z-stack,安装好之后,打开上一讲(zigbee学习笔记(二))的最后我讲的那个工程,即GenericApp.eww,打开之后会看见左侧有很多文件夹,打开APP文件夹,将GenericApp.c和GenericApp.h删除,然后创建以下几个文件,并将一下文件添加到工程里里面去:
Coordinator.c Coordinator.h Enddevice.c Sensor.c Sensor.h
各个文件的代码如下:
coordinator.h
#ifndef COORDINATOR_H
#define COORDINATOR_H
#include "ZComDef.h"
#define GENERICAPP_ENDPOINT 20
#define GENERICAPP_PROFID 0x0F04
#define GENERICAPP_DEVICEID 0X0001
#define GENERICAPP_DEVICE_VERSION 0
#define GENERICAPP_FLAGS 0
#define GENERICAPP_MAX_CLUSTERS 1
#define GENERICAPP_CLUSTERID 1
extern void GenericApp_Init(byte task_id);
extern UINT16 GenericApp_ProcessEvent(byte task_id,UINT16 events);
extern void rxCB(uint8 port,uint8 event);
typedef union h
{
uint8 TEMP[4];
struct RFRXBUF
{
unsigned char Head;
unsigned char value[2];
unsigned char Tail;
}BUF;
}TEMPERATURE;
#endif
coordinator.c
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include
#include "Coordinator.h"
#include "DebugTrace.h"
#if !defined( WIN32 )
#include "OnBoard.h"
#endif
/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{
GENERICAPP_CLUSTERID
};
const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{
GENERICAPP_ENDPOINT, // int Endpoint;
GENERICAPP_PROFID, // uint16 AppProfId[2];
GENERICAPP_DEVICEID, // uint16 AppDeviceId[2];
GENERICAPP_DEVICE_VERSION, // int AppDevVer:4;
GENERICAPP_FLAGS, // int AppFlags:4;
GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters;
(cId_t *)GenericApp_ClusterList, // byte *pAppInClusterList;
0, // byte AppNumInClusters;
(cId_t *)NULL // byte *pAppInClusterList;
};
endPointDesc_t GenericApp_epDesc;
byte GenericApp_TaskID;
byte GenericApp_TransID;
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void GenericApp_SendTheMessage( void );
void GenericApp_Init( uint8 task_id )
{
halUARTCfg_t uartConfig;
GenericApp_TaskID = task_id;
//GenericApp_NwkState = DEV_INIT;
GenericApp_TransID = 0;
// Device hardware initialization can be added here or in main() (Zmain.c).
// If the hardware is application specific - add it here.
// If the hardware is other parts of the device add it in main().
//GenericApp_DstAddr.addrMode = (afAddrMode_t)AddrNotPresent;
//GenericApp_DstAddr.endPoint = 0;
//GenericApp_DstAddr.addr.shortAddr = 0;
// Fill out the endpoint description.
GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
GenericApp_epDesc.task_id = &GenericApp_TaskID;
GenericApp_epDesc.simpleDesc
= (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
GenericApp_epDesc.latencyReq = noLatencyReqs;
// Register the endpoint description with the AF
afRegister( &GenericApp_epDesc );
uartConfig.configured =TRUE;
uartConfig.baudRate =HAL_UART_BR_115200;
uartConfig.flowControl =FALSE;
uartConfig.callBackFunc=NULL;
HalUARTOpen(0,&uartConfig);
}
uint16 GenericApp_ProcessEvent( byte task_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 AF_INCOMING_MSG_CMD:
GenericApp_MessageMSGCB(MSGpkt);
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
// Next
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
// Discard unknown events
return 0;
}
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
unsigned char buffer[2] ={0x0A,0X0D};
TEMPERATURE temperature;
//unsigned char buffer[10];
switch ( pkt->clusterId )
{
case GENERICAPP_CLUSTERID:
//osal_memcpy(buffer,pkt->cmd.Data,10);
//HalUARTWrite(0,buffer,10);
osal_memcpy(&temperature,pkt->cmd.Data,sizeof(temperature));
HalUARTWrite(0,(uint8*)&temperature,sizeof(temperature));
HalUARTWrite(0,buffer,2);
break;
}
}
enddevice.c
#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include
#include "Coordinator.h"
#include "DebugTrace.h"
#if !defined( WIN32 )
#include "OnBoard.h"
#endif
/* HAL */
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"
#define SEND_DATA_EVENT 0X01
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{
GENERICAPP_CLUSTERID
};
const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{
GENERICAPP_ENDPOINT, // int Endpoint;
GENERICAPP_PROFID, // uint16 AppProfId[2];
GENERICAPP_DEVICEID, // uint16 AppDeviceId[2];
GENERICAPP_DEVICE_VERSION, // int AppDevVer:4;
GENERICAPP_FLAGS, // int AppFlags:4;
0, // byte AppNumInClusters;
(cId_t *)NULL, // byte *pAppInClusterList;
GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters;
(cId_t *)GenericApp_ClusterList // byte *pAppInClusterList;
};
endPointDesc_t GenericApp_epDesc;
byte GenericApp_TaskID;
byte GenericApp_TransID;
devStates_t GenericApp_NwkState;
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void GenericApp_SendTheMessage( void );
int8 readTemp(void);
void GenericApp_Init( byte task_id )
{
GenericApp_TaskID = task_id;
GenericApp_NwkState = DEV_INIT;
GenericApp_TransID = 0;
GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
GenericApp_epDesc.task_id = &GenericApp_TaskID;
GenericApp_epDesc.simpleDesc
= (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
GenericApp_epDesc.latencyReq = noLatencyReqs;
// Register the endpoint description with the AF
afRegister( &GenericApp_epDesc );
}
uint16 GenericApp_ProcessEvent( byte task_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)
{
osal_set_event(GenericApp_TaskID,SEND_DATA_EVENT);
}
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
// Next
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if(events & SEND_DATA_EVENT)
{
GenericApp_SendTheMessage();
osal_start_timerEx(GenericApp_TaskID,SEND_DATA_EVENT,1000);
return (events ^ SEND_DATA_EVENT);
}
// Discard unknown events
return 0;
}
void GenericApp_SendTheMessage(void )
{
//unsigned char theMessageData[10] ="hongzecai";
uint8 tvalue;
TEMPERATURE temperature;
temperature.BUF.Head='&';
tvalue=readTemp();
temperature.BUF.value[0]=tvalue/10+'0';
temperature.BUF.value[1]=tvalue%10+'0';
temperature.BUF.Tail='c';
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,
sizeof(temperature),
//10,
(uint8 *)&temperature,
//theMessageData,
&GenericApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS);
//HalLedBlink(HAL_LED_2,0,50,500);
}
sensor.h
#ifndef SENSOR_H
#define SENSOR_H
#include
extern int8 readTemp(void);
#endif
sensor.c
#include "Sensor.h"
#include
#define HAL_ADC_REF_115V 0X00
#define HAL_ADC_DEC_256 0X20
#define HAL_ADC_CHN_TEMP 0X0E
int8 readTemp(void)
{
static uint16 reference_voltage;
static uint8 bCalibrate=TRUE;
uint16 value;
int8 temp;
ATEST=0X01;
TR0 |=0X01;
ADCIF=0;
ADCCON3=(HAL_ADC_REF_115V|HAL_ADC_DEC_256|HAL_ADC_CHN_TEMP);
while(!ADCIF);
ADCIF=0;
value=ADCL;
value |=((uint16)ADCH)<<8;
value >>=4;
if(bCalibrate)
{
reference_voltage=value;
bCalibrate=FALSE;
}
temp=22+((value-reference_voltage)/4);
return temp;
}
添加完之后就可以进行编译了,首先编译的是协调器,在workspace下面的下拉列表里面选择coordinatorEB 另外右键enddevice.c 在options里面选择Exclude from build 另外的sensor.c和sensor.h也是如此,因为这三个文件是终端节点的,所以在协调器编译时,不需要将这两个编译进去,便宜成功后,就可以进行仿真下载了
协调器下载后,拿另外一个终端插上仿真器,在workspace下面的下拉列表里选择enddeviceEB 利用上面的方法,将coordiator.c文件排除在外,然后在进行编译链接,下载到终端里面去,将协调器插到电脑上,同时打开串口小助手,设置波特率为115200,数据位8位,停止位一位 检验位0位 给终端节点上电之后就可看到界面在不停的显示温度 格式为 &**C
添加了上面这些文件,整个网络就运行起来了,那么这些代码到底什么意思呢 下面我们一起来一一学习。
首先第一步是协调器,先创建一个coordinator.h的头文件,这里面的一些包含的头文件都是之前generApp.h文件里面的,并宏定义了一些后面要用到的变量,这里先不做过多的解释。完成了头文件的创建之后,就是coordinator.c文件得编程,首先也是包含的一些头文件,