效果是协调器建立网络后,终端加入网络并向协调器发送字符串,协调器通过串口将收到的字符串发到PC
Coordinator.c
#include "OSAL.h"//为了实现多事件和多任务切换,需要把事件和任务对应的应用,并起一个名字OSAL操作系统抽象层。 #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 "hal_uart.h" const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] = { GENERICAPP_CLUSTERID };//const 常量 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; };//上述数据姐构体可以用来描述一个eigbee设备节点,成为简单设备描述符 endPointDesc_t GenericApp_epDesc;//endPointDesc_t 是结构体,定义在AF.h byte GenericApp_TaskID; byte GenericApp_TransID; //unsigned char uartbuf[128];//串口缓冲区 //节点描述符 GenericApp_epDesc 任务优先级TaskID 数据发送序列号TransID void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );//消息处理函数 void GenericApp_SendTheMessage( void );//数据发送函数 //static void rxCB(uint8 port,uint8 event);//串口相关 void GenericApp_Init( byte task_id ) { halUARTCfg_t uartConfig;//定义串口配置结构体 GenericApp_TaskID = task_id;//初始化任务优先级 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;// afRegister( &GenericApp_epDesc );//调用函数为节点描述符注册,以使用OSAL提供的服务 /*以下是串口收发实验新增部分,对串口进行配置,如是否打开串口,波特率,是否使用流控等*/ uartConfig.configured = TRUE; uartConfig.baudRate = HAL_UART_BR_115200; uartConfig.flowControl = FALSE; uartConfig.callBackFunc = NULL;//在串口配置部分,回调函数不需要了 HalUARTOpen(0,&uartConfig);//最后使用HalUARTOpen对串口进行初始化 } // 上述代码是该任务初始化函数 //注释为空的部分较为固定,不用修改 UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events ) { //以下代码在基础串口收发实验时不用 ,将事件处理函数改为空函数 afIncomingMSGPacket_t *MSGpkt;//定义了一个指向消息接受结构体的指针MSGpkt if(events & SYS_EVENT_MSG) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(GenericApp_TaskID);//使用osal_msg_receive函数从消息队列上接受消息 //该消息包含了指向接收到数据包的指针 while(MSGpkt) { switch(MSGpkt->hdr.event) {case AF_INCOMING_MSG_CMD://如果是无线数据,用下面函数处理 GenericApp_MessageMSGCB( MSGpkt);//11111 break; default: break; } osal_msg_deallocate( (uint8 *)MSGpkt);//处理完消息需要释放内存空间,调用deallocate函数以释放 MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive (GenericApp_TaskID);//处理队列中下一个消息直到处理完 } return(events ^ SYS_EVENT_MSG); } return 0; } //上述代码是消息处理函数,大部分固定,唯一可以修改的是注释标记处 //需要熟悉该函数的格式 /*串口实验中新增*/ /*static void rxCB(uint8 port,uint8 event) { HalUARTRead(0,uartbuf,7);//调用函数,从串口读取数据并存放在uartbuf中 if(osal_memcmp(uartbuf,"ldztzrh",7))//判断接受到的数据,如果是,返回TURE { HalUARTWrite(0,uartbuf,8);//调用该函数,发送收到的数据 } }*/ //osal_memcmp()经常使用,是一个回调函数,在 uartConfig.callBackFunc = rxCB; 处 //将rxCB传递给了成员callBackFunc,是一个函数指针,也就是将函数的地址传给callBackFunc //这样就可以通过callBackFunc成员函数来调用rxCB()函数了。 //回调函数是在特定条件或事件发生时,由另一方调用的,用于响应 //以下代码在基础串口收发实验时不用 void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) { unsigned char buffer[10]; switch(pkt->clusterId) { case GENERICAPP_CLUSTERID: osal_memcpy(buffer,pkt->cmd.Data,10);//使用osal_memcpy函数将接收到的数据拷贝到buffer中 HalUARTWrite(0,buffer,10);//串口写函数 break; } }
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 "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; GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters; (cId_t *)GenericApp_ClusterList, // byte *pAppInClusterList; GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters; (cId_t *)GenericApp_ClusterList // byte *pAppInClusterList; };//描述一个设备节点,参考coordinator.c文件 endPointDesc_t GenericApp_epDesc; byte GenericApp_TaskID; byte GenericApp_TransID; devStates_t GenericApp_NwkState; /*定义四个变量 //节点描述符 GenericApp_epDesc 任务优先级TaskID 数据发送序列号TransID GenericApp_NwkState 保存节点状态*/ void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt ); void GenericApp_SendTheMessage( void );//发送函数 void GenericApp_Init( byte task_id ) { GenericApp_TaskID = task_id;//初始化任务优先级 GenericApp_NwkState = DEV_INIT;//状态初始化为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;// afRegister( &GenericApp_epDesc );//调用函数为节点描述符注册,以使用OSAL提供的服务 } // 上述代码是该任务初始化函数 //注释为空的部分较为固定,不用修改 UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events ) { afIncomingMSGPacket_t *MSGpkt;//定义了一个指向消息接受结构体的指针MSGpkt if(events & SYS_EVENT_MSG) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(GenericApp_TaskID);//使用osal_msg_receive函数从消息队列上接受消息 //该消息包含了指向接收到数据包的指针 while(MSGpkt) { switch(MSGpkt->hdr.event) { case ZDO_STATE_CHANGE: GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);//读取设备类型 if (GenericApp_NwkState == DEV_END_DEVICE)//如果是终端节点,类型码为DEV_END_DEVICE { osal_set_event(GenericApp_TaskID,SEND_DATA_EVENT);//当终端加入节点,用此函数设置事件 //此函数设置某一事件,事件发生后,执行事件处理函数 } break; default: break; } osal_msg_deallocate( (uint8 *)MSGpkt);//处理完消息需要释放内存空间,调用deallocate函数以释放 MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive (GenericApp_TaskID);//处理队列中下一个消息直到处理完 } return(events ^ SYS_EVENT_MSG); } if(events & SEND_DATA_EVENT) { GenericApp_SendTheMessage(); osal_start_timerEx(GenericApp_TaskID,SEND_DATA_EVENT,1000);//下一行解释三个参数 //(时间到达后,对其做出响应的任务,时间到达后,该事件发生,定时时间 ms) return (events ^ SEND_DATA_EVENT);//清除事件标志 } return 0; } /*在串口收发实验中,作用是调用无线发送函数,并且定时1s*/ /* 上述代码是消息处理函数,大部分固定 需要熟悉该函数的格式 */ void GenericApp_SendTheMessage(void) { unsigned char theMessageData[10] = "EndDevice";//用于存放要发送的数据 afAddrType_t my_DstAddr;//为满足AF_DataRequest第一个参数定义的变量 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,//命令号 osal_strlen("EndDevice")+1,//数据长度,发送时需要将结尾结束符一起发 theMessageData,//指向数据缓冲区的指针 &GenericApp_TransID, AF_DISCV_ROUTE, AF_DEFAULT_RADIUS); /*调用数据发送函数AF_DataRequest进行无线数据发送 */ /HalLedBlink(HAL_LED_2,0,50,500); } /*数据类型afAddrType和函数AF_DataRequest原型都在书上*/