1、星型网络的程序实现一、方案概述星型网络以一个功能强大的主器件作为网络的中心,负责协调全网的工作,其他的主器件或从器件分布在其覆盖范围内。这种网络的控制和同步都比较简单,适用于设备数量比较少的场合。在无线传感器网中的节点是由软件层和硬件层共同配合来实现功能的。星型网络拓扑的最大优点是结构简单。这种简单带来的优点是很少有上层协议需要执行、较低的设备成本、较少的上层路由信息和管理简便。中心节点可以承担许多管理工作,如:发放证书和远距离网关管理等。但是这种简单是以灵活性的牺牲为代价的。因为需要把每个终端节点放在中心节点的通信范围之内,这必然会限制无线网络的覆盖范围。目前为止,星形拓扑是最常见的网络配置
2、结构,被大量应用在远程监测和控制中。由于 Zigbee 传感器星型网络的搭建简单,易于维护等优点,在实际应用中得到了广泛的应用。该网络由若干个 ZigBee 终端节点和一个中心节点构成一个星型网络,终端节点主要负责各个传感器模块的信息采集和传送。中心节点主要用于接收各个终端节点的上传数据,并对其进行压缩处理后通过扩展接口传送至服务器端。ZigBee 网络的建立是有序的。每个节点都有唯一的 MAC 地址,这是通过预编程设定的。ZigBee 有一套地址分配机制保证地址不会重复。网络一旦建立,拓扑关系和网络地址就会保存在各自节点的 Flash 中。网络建立后,各节点就可以通过各自的网络地址进行通讯了
3、。方案的总体框图如下所示:二、FFD(星型网络中心)的软件实现 星型网络中心是整个 ZigBee 无线传感网络的管理员,它负责网络的建立、地址的分配和成员的加入、节点设备数据的更新、数据转发表、设备关联表的维护并根据网络的状况自动更新。它能够主动扫描本身覆盖范围内的传感器节点,其它节点总是首先试图与星型网络中心进行连接。每个星型网中只有一个管理员即星型网络控制中心,它相当于现在有线局域网中的服务器,具有对本地网路管理的功能。网络中的全功能节点可作为路由器,协调器来使用,而半功能节点只能作为终端节点来使用。在星型网络中,所有的节点只能与星型网络控制中心进行通信,两者之间的通信是禁止。FFD 的程
4、序实现,分为主函数部分和响应终端节点部分:void main(void)WORD prio;WORD i;emDint(AD1PCFG=0xFFFF; /把模拟输入改成数字 I/OUnlockREG();AD1PCFGbits.PCFG11=1; RPINR0bits.INT1R=13;RPINR18bits.U1RXR=11;RPOR5bits.RP10R=3;LockREG();/硬件初始化SPIInit();RS485InitSetup();ADInitSetup();DeviceInitSetup();LEDInitSetup();RFInitSetup(); /驱动层初始化Flash
5、InitSetup();initUSART(); /串口模块初始化InitTicks();/中断初始化IFS1bits.INT1IF=0;IEC1bits.INT1IE=1;IPC5bits.INT1IP=7;/最高优先级为 7,依次递减 6 直至 1INTCON2bits.INT1EP=1;/1 为下降沿,0 为上升沿LEDBlinkRed();LEDBlinkYellow();/协议栈初始化emSysInit();PHYInitSetup();/物理层初始化MACInitSetup();/MAC 层初始化emEint(emSetHardTimer(0,TIME_CONTROL_NUM);e
6、mSetHardTimer(4,80000);emStartHardTimer(4);/ 操作系统任务CreateTask(SYSTask,0,0,READY);CreateTask(MACTask,9,9,READY);CreateTask(SendByUARTTask,12,12,READY);CreateTask(CircleTask,15,15,READY);/定义 FFD 的网络地址,MAC 地址。macPIB.macPANId.nVal=0x0101;macPIB.macShortAddr.nVal=0x1111;macStatus.bits.addrMode = MAC_SRC_
7、SHORT_ADDR;macStatus.bits.bEstablishPAN = 1;macStatus.bits.isAssociated = 1;RFSetTRxState(RF_TRX_RX);/射频模块处于接收状态StartTask();case MAC_BEACON_REQUEST:DeviceType=macPIB.DeviceInfo.bits.DeviceType;if(DeviceType=ZIGBEE_COORD) MACSendBeaconNotify();macCurrentRxFrame.bReady=0;break;BOOL MACSendBeaconNotify
8、(void)BYTE DeviceType;BYTE cSize=0;NODE_INFO macAddr;BYTE cPtrTx10;SUPERFRAME_SPEC SuperframeSpec;macAddr.AddrMode=0;MACPutHeader( /这里的帧头显示的是信标帧/封装数据,超帧描述,目的是得到 FFD 的类型SuperframeSpec.nVal=0;DeviceType=macPIB.DeviceInfo.bits.DeviceType;if(DeviceType=ZIGBEE_COORD) | (DeviceType=ZIGBEE_ROUTER)if(Device
9、Type=ZIGBEE_COORD)SuperframeSpec.bits.PANCoordinator=1;else SuperframeSpec.bits.PANCoordinator=0;if(SearchIdleNeighborRecord()SuperframeSpec.bits.AssociationPermit=1;elseSuperframeSpec.bits.AssociationPermit=0;/封装超帧描述cPtrTxcSize+=SuperframeSpec.cVal0;cPtrTxcSize+=SuperframeSpec.cVal1;/写入缓冲区MACPutTxB
10、uffer(cPtrTx,cSize);CLR_WDT();/发送return MACTransmitPacket();三 终端节点(RFD)的软件实现 终端节点是 ZigBee 网络结构中最简单的一种,它可以是一个 FFD 也可以是一个RFD。它不支持路由功能,只能与 1 个 FFD 节点通信。终端节点加入 ZigBee 网络之后就进入正常的工作状态,监听来自星型网络控制中心命令并做出应答,以及定时采集数据信息发送给星型网络控制中心并在客户端软件上显示相应的数据信息。RFD 的程序实现,主要分为发送入网请求部分、节点对于 FFD 的信标处理部分和离开网络部分:void MACJoinPAN(
11、void)WORD Index;NODE_INFO Record;ASSOC_REQUEST_CAP CapInfo;if(JoinNwkIndction = 1)/查找自己所属的 FFDIndex=MACSearchPrioPANRecord(if(Index!=InValid_Index)CapInfo.cVal=0;CapInfo.bits.EnableCoord=0; /RFDCapInfo.bits.DeviceType=MACGetDeviceType(); /供电方式永在 CapInfo.bits.PowerSource=1; /空闲处于接收状态CapInfo.bits.Rece
12、iveIdle=1;/没有使用安全模式CapInfo.bits.EnableSecur=0;/要求 FFD 分配地址 CapInfo.bits.AllocAddress=1; if(PANDescriptor.CoordAddrMode=0)Record.AddrMode=MAC_DST_SHORT_ADDR;Record.PANId.nVal=PANDescriptor.CoordPANId.nVal;Record.ShortAddr.nVal=PANDescriptor.CoordShortAddr.nVal;memcpy(BYTE*)MACSendAssociationReq(else
13、if(PANDescriptor.CoordAddrMode=1)Record.AddrMode=MAC_DST_LONG_ADDR;Record.PANId.nVal=PANDescriptor.CoordPANId.nVal;Record.PANId.nVal=PANDescriptor.CoordPANId.nVal;memcpy(BYTE*)memcpy(BYTE*)MACSendAssociationReq(/若还没有加入网络/if(JoinNwkTime = 0)elseif(!macStatus.bits.isAssociated)/首先要发送一个信标请求,发现 FFD 所在MA
14、CSendBeaconReq();/节点发送入网的请求具体实现函数BOOL MACSendAssociationReq(NODE_INFO *macAddr,ASSOC_REQUEST_CAP CapInfo)BYTE cSize=0;BYTE cPtrTx5;SHORT_ADDR PANId;/封装 MAC 帧头/临时存储源网络标识PANId.nVal=macPIB.macPANId.nVal;/源地址网络标示为广播macPIB.macPANId.nVal=0xFFFF;/目的地址模式根据信标帧来确定MACPutHeader(macAddr,MAC_FRAME_CMD); /发送入网请求命令
15、帧/恢复源网络标识macPIB.macPANId.nVal=PANId.nVal;/封装数据cPtrTxcSize+=MAC_ASSOC_REQUEST;cPtrTxcSize+=CapInfo.cVal;cPtrTxcSize+=macPIB.CDNum;MACPutTxBuffer(cPtrTx,cSize);/发送return MACTransmitPacket();/节点对于 FFD 的信标处理void MACProcessBeacon(void)BYTE cSize=0;PAN_DESCRIPTOR PANDesc;/判断 FFD 的地址模式,FFD 回复的超帧进入这个 if,因为
16、FFD 有源地址模式。if(macCurrentRxFrame.srcAddress.AddrMode = MAC_SRC_SHORT_ADDR)/短地址模式PANDesc.CoordAddrMode=0;/网络标识PANDesc.CoordPANId.nVal=macCurrentRxFrame.srcAddress.PANId.nVal;/短地址PANDesc.CoordShortAddr.nVal=macCurrentRxFrame.srcAddress.ShortAddr.nVal;else/长地址模式PANDesc.CoordAddrMode=1;/网络标识PANDesc.Coord
17、PANId.nVal=macCurrentRxFrame.srcAddress.PANId.nVal;/长地址memcpy(BYTE*)/记录超帧描述PANDesc.SuperframeSpec.cVal0=macCurrentRxFrame.pMsducSize+;PANDesc.SuperframeSpec.cVal1=macCurrentRxFrame.pMsducSize+;CLR_WDT();PANDesc.bits.allowJoin=PANDesc.SuperframeSpec.bits.AssociationPermit;/修改链路质量PANDesc.LinkQuality=P
18、HYGetLinkQuality(macCurrentRxFrame.rssi);MACRefreshPANRecord(/释放资源macCurrentRxFrame.bReady=0;CLR_WDT();case MAC_ASSOC_RESPONSE:DeviceType=macPIB.DeviceInfo.bits.DeviceType;/读出分配给自己的地址shortAddr.cVal0=macCurrentRxFrame.pMsduoffset+;shortAddr.cVal1=macCurrentRxFrame.pMsduoffset+;/读出加入网络的状态Status=macCur
19、rentRxFrame.pMsduoffset+;/说明加入网络成功,并且给分配了一个短地址if(Status=MAC_ASSOCIATION_PAN_SUCCESS)/记录分配的地址macPIB.macShortAddr.nVal=shortAddr.nVal;/存储短地址/PutMACAddr();/修改地址模式macStatus.bits.addrMode=MAC_SRC_SHORT_ADDR;/修改入网状态macStatus.bits.isAssociated=1;/保存父节点信息/PutCoordDescriptor();/节点离开网络BOOLMACSendDisassociatio
20、nNotify(LONG_ADDR*LongAddr,MAC_DISASSOCIATION_REASON Reason)BYTE cSize=0;BYTE cPtrTx5;BYTE addrMode;NODE_INFO macAddr;/封装 MAC 帧头/地址模式要用长地址macAddr.AddrMode=MAC_DST_LONG_ADDR;macAddr.PANId.nVal=0xFFFF;memcpy(BYTE *)/临时存储地址模式addrMode=macStatus.bits.addrMode;/源地址模式临时设为长地址macStatus.bits.addrMode=MAC_SRC_LONG_ADDR;MACPutHeader(/恢复源地址模式macStatus.bits.addrMode=addrMode;/封装数据cPtrTxcSize+=MAC_DISASSOC_NOTIFY; cPtrTxcSize+=Reason; MACPutTxBuffer(cPtrTx,cSize);CLR_WDT();/发送return MACTransmitPacket();