ZigBee无线通信网络软件毕业设计 - 图文 下载本文

// Successfully started a ZigBee network

if ( devState == DEV_COORD_STARTING ) {

devState = DEV_ZB_COORD; }

osal_pwrmgr_device( PWRMGR_ALWAYS_ON );

osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT ); }

…… }

⑧ ZDO事件轮询中处理ZDO状态改变事件

void ZDO_UpdateNwkStatus( devStates_t state )

{

// Endpoint/Interface descriptor list. epList_t *epDesc = epList;

byte bufLen = sizeof(osal_event_hdr_t); osal_event_hdr_t *msgPtr;

ZDAppNwkAddr.addr.shortAddr = NLME_GetShortAddr(); (void)NLME_GetExtAddr(); // Load the saveExtAddr pointer. while ( epDesc ) {

if ( epDesc->epDesc->endPoint != ZDO_EP ) {

msgPtr = (osal_event_hdr_t *)osal_msg_allocate( bufLen ); if ( msgPtr ) {

msgPtr->event = ZDO_STATE_CHANGE; // Command ID msgPtr->status = (byte)state;

osal_msg_send( *(epDesc->epDesc->task_id), (byte *)msgPtr ); } }

epDesc = epDesc->nextDesc; } }

(2)无线转串口数据传输

协调在网络启动后,就开始监听无线信号和串口信息。一旦有节点加入到网络当中,协调器将会将新加入节点的地址信息汇报给网关。当协调器监听到发送给自己无线信号时,将从无线信号包中解析出命令帧,在确认命令格式正确无误时,协调器将该命令帧通过串口发送给网关,其实现代码如下:

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )

{

20

#ifdef COORD uint8 i;

memcpy(RfRx.RxBuf,pkt->cmd.Data,32);

if((RfRx.RXDATA.Head == '&') && (RfRx.RXDATA.LastByte == '*')) {

memcpy(UartTxBuf.TxBuf,RfRx.RxBuf,32); for(i=0; i<8; i++) {

UartTxBuf.TXDATA.Laddr[i] = RfRx.RXDATA.Laddr[i]; }

for(i=0; i<2; i++) {

UartTxBuf.TXDATA.Saddr[i] = RfRx.RXDATA.Saddr[1-i]; }

UartTxBuf.TXDATA.CRC = CheckUartData(&UartTxBuf.TxBuf[1],29); HalUARTWrite ( HAL_UART_PORT_0, UartTxBuf.TxBuf, 32); } #endif …… }

(3)串口转无线数据传输

协调器不但要监听无线网络中的数据帧,还要与网关进行数据交互,本系统是通过串口实现与网关的通信的。在Z-Stack中需要使能MT监测任务才能实现对串口数据的收发,部分初始化代码如下所示:

void osalInitTasks( void ) {

??

#if defined( MT_TASK ) MT_TaskInit( taskID++ ); #endif ?? }

在MT_TaskInit函数中调用了MT_UartInit函数,该函数就是串口的初始化函数。具体初始化包括对串口的波特率,缓存区大小,流控制等进行了配置,特别决定了串口的处理方式为DMA方式,最后还指定了串口数据处理的回调函数。通过设置HAL_UART_DMA宏为1,再调用HalUARTOpen函数打开串口时,判断该配置宏,选择采用DMA方式打开串口,即调用HalUARTOpenDMA函数,初始化DMA,打开串口。

完成初始化工作后,然后在相应的层注册一个串口事件,即可将串口数据反馈到相应的层。本系统在应用层注册了串口事件,在系统消息中对串口消息进行

21

了处理,其处理代码如下:

void UartRxComCallBack(void) { uint16 DstAddr; if((UartRxBuf.RxBuf[0] == '&') && (UartRxBuf.RxBuf[31] == '*')) { memcpy(RfTx.TxBuf,UartRxBuf.RxBuf,32); DstAddr = RfTx.TXDATA.Saddr[0]; DstAddr <<= 8; DstAddr += RfTx.TXDATA.Saddr[1]; if(SendData(DstAddr, RfTx.TxBuf, 32) == 0)//发送数据失败 { memset(&RfTx.TxBuf[4],'x',26); memcpy(RfTx.TXDATA.Laddr,UartRxBuf.RXDATA.Laddr,8);//加入地址 RfTx.TXDATA.DataBuf[0] = 'E'; RfTx.TXDATA.DataBuf[1] = '1';//串口输出E1 memcpy(UartTxBuf.TxBuf,RfTx.TxBuf,32); UartTxBuf.TXDATA.CRC = CheckUartData(&UartTxBuf.TxBuf[1],29); HalUARTWrite(HAL_UART_PORT_0, UartTxBuf.TxBuf, 32);//串口输出 } else { P1_1 = !P1_1; } } memset(UartRxBuf.RxBuf,0,32); }

对串口消息的处理中,协调器首先对命令帧的格式进行了确认,然后通过memcpy(RfTx.TxBuf,UartRxBuf.RxBuf,32);从串口接收缓存区将数据拷贝到无线发送缓存区,从缓存区提取出目的地址后,通过无线发送函数SendData将数据发送出去。

4.1.2 终端节点模块软件设计

ZigBee节点软件包括加入到无线通信网络,采集光传感信息,控制LED台灯以及查询链路连接状态。其工作流程图如图18所示:

22

开始硬件初始化Zigbee协议栈初始化查找网络有网络?Y申请加入N加入成功?Y处理用户事件N

图18 节点软件设计流程图

(1)加入网络

终端设备的启动与协调器不同是从ZDO_StartDevice的调用开始的,该函数首先判断设备类型是终端设备,然后通过调用ZDO_StartDevice 函数启动设备,该函数调用了网络发现请求函数NLME_NetworkDiscoveryRequest来寻找一个可用网络,同样,也有其对应的确认函数ZDO_NetworkDiscoveryConfirmCB,在网络发现确认函数中,对网络信息进行校验,再发送一个网络发现确认消息给ZDO层,ZDO层得知网络已经发现后,会调用网络加入请求函数NLME_JoinRequest,加入到网络当中,网络加入确认则是在更新网络信息之后设置了ZDO_STATE_CHANGE_EVT,通过该事件,最后会发送消息个API层,通知器进行启动确认,从而完成整个启动过程。

① ZDO_StartDevice函数发现网络:

void ZDO_StartDevice( byte logicalType, devStartModes_t startMode, byte beaconOrder, byte superframeOrder )

{

……

#if !defined ( ZDO_COORDINATOR ) || defined( SOFT_START )

if ( logicalType == NODETYPE_ROUTER || logicalType == NODETYPE_DEVICE ) {

23