⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nwk.i

📁 ATmega128L+CC2420的单片机源程序
💻 I
📖 第 1 页 / 共 3 页
字号:
 *******************************************************************************************************/
//-------------------------------------------------------------------------------------------------------
extern CC2420_RX_INFO rfRxInfo;
extern CC2420_TX_INFO rfTxInfo;
extern unsigned char pTxBuffer[(127 - ((2 + 1 + 2 + 2 + 2) + (2)))];
extern unsigned char pRxBuffer[(127 - ((2 + 1 + 2 + 2 + 2) + (2)))];
//-------------------------------------------------------------------------------------------------------




/***********************************************************************
* 创建网络 (仅对协调器节点有效 )
************************************************************************/
void nwk_CreatNetwork(void)
{  
    MAC_Init();
    nwk_Addr_Assign_Init();
}



/***********************************************************************
* 初始化地址分配表 (仅对协调器节点有效 )
************************************************************************/
void nwk_Addr_Assign_Init(void)
{
    unsigned char i;
    //addrTableList[0].ShortAddr = 43776;
        //addrTableList[0].Avail = 0x01;  // 地址允许分配
    for(i=0;i<20      ;i++)
    {
        addrTableList[i].ShortAddr = i+1;
        addrTableList[i].Avail = 0x01;  // 地址允许分配
    }
}



/***********************************************************************
* 检查地址分配表是否有未分配的地址 (仅对协调器节点有效 )
* 如果有,则返回地址分配表中第一个可用地址的下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_Addr_Assign_Check(void)
{
    unsigned char i;
    
    for(i=0;i<20      ;i++)
    {
        if(addrTableList[i].Avail == 0x01)  // 地址允许分配
        {
            return i;
        }
    }
    return 0xFF;
}
 


/***********************************************************************
* 检查地址分配表是否有指定地址存在 (仅对协调器节点有效 )
* 如果有,则返回地址分配表中此地址的下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_Addr_Assign_Check_Addr(unsigned int addr)
{
    unsigned char i;
    
    for(i=0;i<20      ;i++)
    {
        if(addrTableList[i].ShortAddr == addr)  // 地址允许分配
        {
            return i;
        }
    }
    return 0xFF;
}



/***********************************************************************
* 检查邻居表是否有空的 (仅对协调器节点有效 )
* 如果有,则返回地址分配表中第一个的下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_NeighborTable_Check(void)
{
    unsigned char i;
    
    for(i=0;i<20      ;i++)
    {
        if(neighbor[i].Avail == 0x00)
        {  
            return i;
        }
    }
    return 0xFF;
}



/***********************************************************************
* 检查IEEE地址是否在邻居表中 (仅对协调器节点有效 )
* ieeeAddr :要查询的地址的指针
* 如果找到则返回下标,没有则返回0xFF
************************************************************************/
unsigned char nwk_IEEEIsInNeighborTable_Check(unsigned char *ieeeAddr)
{
    unsigned char i;
    unsigned char *ieeeAddr_temp;
    for(i=0;i<20      ;i++)
    {
        ieeeAddr_temp = ieeeAddr;    
        if(
            (neighbor[i].IEEEAddr[0] == *ieeeAddr_temp++)&&
            (neighbor[i].IEEEAddr[1] == *ieeeAddr_temp++)&&
            (neighbor[i].IEEEAddr[2] == *ieeeAddr_temp++)&&
            (neighbor[i].IEEEAddr[3] == *ieeeAddr_temp++)&&
            (neighbor[i].IEEEAddr[4] == *ieeeAddr_temp++)&&
            (neighbor[i].IEEEAddr[5] == *ieeeAddr_temp++)&&
            (neighbor[i].IEEEAddr[6] == *ieeeAddr_temp++)&&
            (neighbor[i].IEEEAddr[7] == *ieeeAddr_temp)
        )return i;
    }
    return 0xFF;
}



/***********************************************************************
* 删除邻居表中指定的地址 (仅对协调器节点有效 )
* shortAddr :要删除的地址的指针
************************************************************************/
unsigned char nwk_DeleteNeighborTable(unsigned int shortAddr)
{
    unsigned char i,j,k=0;
    
    for(i=0;i<20      ;i++)
    {   
        if( neighbor[i].ShortAddr == shortAddr )
        {
            nwk_Send_neighbortable_to_PC(i,0x02);    //向PC机发送
            
            PORTD ^= (1<<7 )  ;
            
            neighbor[i].Avail = '';
            for(j=0;j<8;j++)
            {
                neighbor[i].IEEEAddr[j] = '';
            }             
            neighbor[i].ShortAddr = '';
            neighbor[i].DeviceType = '';
            neighbor[i].Relationship = ''; 
            
            k = nwk_Addr_Assign_Check_Addr(shortAddr);  //检查地址分配表中是否有此地址,如果有则把此地址设置为可分配
            if( k != 0xFF )
            {
                addrTableList[k].Avail = 0x01;
            }
            
            return i;      
        }
    }
    return 0xFF;
}



/***********************************************************************
* 允许其他节点加入网络 (仅对协调器节点有效 )
************************************************************************/
void nwk_PermitJoinIn(void)
{
    flag_PermitJoinIn = 0x01;
}



/***********************************************************************
* 加入网络 (仅对终端节点有效 )
************************************************************************/
void nwk_JoinInNetwork(void)
{ 
    unsigned char i;
     
    MAC_Init();
    
    nwk_FCF = 0x02;
    nwk_RequestOrAck = 0x01;
    nwk_CmdTypes = 0x01    ;
    

	rfTxInfo.destAddr = 0x1234;       // 发送的目的地址
    rfTxInfo.length = 0x05;                     // 要发送消息内容的长度
    rfTxInfo.ackRequest = 0;                // 不要求返回确认

    pTxBuffer[0] = nwk_FCF; 
    pTxBuffer[1] = nwk_RequestOrAck;
    pTxBuffer[2] = nwk_CmdTypes;

    pTxBuffer[3] = 0x11;
    pTxBuffer[4] = 0x03;


    CC2420_SendPacket(&rfTxInfo,0x02);
    
    
    // 等待一段时间看看有没有加入成功,有没有获得 16 bit 短地址
    delay_ms(1000);
    if(rfSettings.JoinNetworkSuccess)               // 加入成功 ,通知协调器加入成功
    {
        nwk_CmdTypes = 0x03    ;
        
    	rfTxInfo.destAddr = 0x1234;      // 发送的目的地址
        rfTxInfo.length = 0x011;                   // 要发送消息内容的长度
        rfTxInfo.ackRequest = 0;               // 不要求返回确认

        pTxBuffer[0] = nwk_FCF; 
        pTxBuffer[1] = nwk_RequestOrAck;
        pTxBuffer[2] = nwk_CmdTypes;
        
        for(i=0;i<8;i++)                           // 自己的IEEE地址
        {
            pTxBuffer[i+3] = rfSettings.myIEEE[i]; 
        }
        

        CC2420_SendPacket(&rfTxInfo,0x01);
        
        Sleep();//休眠模式:掉电模式
        
    }  
}



/***********************************************************************
* 加入网络请求的应答 (仅对协调器节点有效 )  
* 地址分配表中可分配的地址的下标,如果没有则其值为0xFF
************************************************************************/
void nwk_JoinInNetwork_ACK(unsigned char flage,unsigned char addrlistID,unsigned char neighbortable_tempID)
{ 
    unsigned char i; 
    unsigned char NeighborTableID;   
    nwk_FCF = 0x02;
    nwk_RequestOrAck = 0x02;
    nwk_CmdTypes = 0x01    ;
    
    for(i=0;i<8;i++)
    {
	    rfTxInfo.destIEEE[i] = rfSettings.pRxInfo->srcIEEE[i];  // 发送的目的地址
    }
    rfTxInfo.ackRequest = 0;                // 不要求返回确认

    pTxBuffer[0] = nwk_FCF; 
    pTxBuffer[1] = nwk_RequestOrAck;
    pTxBuffer[2] = nwk_CmdTypes;
    
    if(!flage)
    {
        if( addrlistID == 0xFF ) // 没有可分配地址
        {
            pTxBuffer[3] = 0x01;  // 没有可分配地址
            rfTxInfo.length = 0x04;     // 要发送消息内容的长度
        }
        else                    // 有可分配地址
        {
            pTxBuffer[3] = 0x02;     // 有可分配地址
            pTxBuffer[4] = addrTableList[addrlistID].ShortAddr & 0x00FF;
            pTxBuffer[5] = ( addrTableList[addrlistID].ShortAddr >> 8 );
            rfTxInfo.length = 0x06;             // 要发送消息内容的长度  
            
            addrTableList[addrlistID].Avail = 0x00;     // 地址分配表中的这个地址设置为已经被分配
            NeighborTableID = nwk_NeighborTable_Check();
            for(i=0;i<8;i++)
            {
                neighbor[NeighborTableID].IEEEAddr[i] = rfSettings.pRxInfo->srcIEEE[i];
            }   
        }
    }
    else
    {
        pTxBuffer[3] = 0x02;     // 有可分配地址
        pTxBuffer[4] = neighbor[neighbortable_tempID].ShortAddr & 0x00FF;
        pTxBuffer[5] = ( neighbor[neighbortable_tempID].ShortAddr >> 8 );
        rfTxInfo.length = 0x06;             // 要发送消息内容的长度
    }
    
    CC2420_SendPacket(&rfTxInfo,0x03);
}

 

/***********************************************************************
* 离开网络 (仅对终端节点有效 )
************************************************************************/
void nwk_LeaveNetwork(void)
{
    nwk_FCF = 0x02;
    nwk_RequestOrAck = 0x01;
    nwk_CmdTypes = 0x02    ;
    

	rfTxInfo.destAddr = 0x1234;   // 发送的目的地址
    rfTxInfo.length = 0x03;                 // 求取要发送消息内容的长度
    rfTxInfo.ackRequest = 0;            // 不要求返回确认
      
    pTxBuffer[0] = nwk_FCF; 
    pTxBuffer[1] = nwk_RequestOrAck;
    pTxBuffer[2] = nwk_CmdTypes;
        
    CC2420_SendPacket(&rfTxInfo,0x01); 
    
    // 等待一段时间看看有没有离开成功
    delay_ms(1000);
    if(!rfSettings.JoinNetworkSuccess) // 离开网络成功 ,通知协调器离开成功
    {
        nwk_CmdTypes = 0x04    ;
        
    	rfTxInfo.destAddr = 0x1234;       // 发送的目的地址
        rfTxInfo.length = 0x03;                     // 要发送消息内容的长度
        rfTxInfo.ackRequest = 0;                // 不要求返回确认

        pTxBuffer[0] = nwk_FCF; 
        pTxBuffer[1] = nwk_RequestOrAck;
        pTxBuffer[2] = nwk_CmdTypes;
        
        CC2420_SendPacket(&rfTxInfo,0x01);
        
        CC2420_SetShortAddress(0x0000); 
    }   
}



/***********************************************************************
* 离开网络的应答  (仅对协调器节点有效 )
************************************************************************/
void nwk_LeaveNetwork_ACK(void)
{
    nwk_FCF = 0x02;
    nwk_RequestOrAck = 0x02;
    nwk_CmdTypes = 0x02    ;
    
    rfTxInfo.destAddr = rfSettings.pRxInfo->srcAddr;  // 发送的目的地址
    rfTxInfo.length = 0x04;
    rfTxInfo.ackRequest = 0;                // 不要求返回确认

    pTxBuffer[0] = nwk_FCF; 
    pTxBuffer[1] = nwk_RequestOrAck;
    pTxBuffer[2] = nwk_CmdTypes;
    pTxBuffer[3] = 0x01;  //同意脱离网络
    
    CC2420_SendPacket(&rfTxInfo,0x01);
}


/***********************************************************************
* 网络层打包函数
************************************************************************/ 
void nwk_PackData(unsigned char *pPayload, unsigned char length)
{
    unsigned char i=0;
    
    nwk_FCF = 0x01;
    
    pTxBuffer[0] = nwk_FCF;
    for(i=0;i<length;i++) 
    {
        pTxBuffer[i+1] = *pPayload++;
    }
    rfTxInfo.length = length+1;         // 要发送消息内容的长度
    rfTxInfo.ackRequest = 0;        // 不要求返回确认
 
    CC2420_SendPacket(&rfTxInfo,0x01);   
}




/***********************************************************************
* 网络层解包函数
************************************************************************/ 
void nwk_UnPackData(unsigned char *pPayload, unsigned char length)
{
    unsigned char temp0,temp1,temp2,temp3;
    unsigned char addrlist_temp;
    unsigned char neighborID_temp;
    
    temp0 = *pPayload++; 

    switch (temp0)
    {
        case 0x01:
        {
            app_UnPackData(pPayload,length-1); // 调用应用层解包
            break;
        }            
        case 0x02:  // 网络层命令
        {
            temp1 = *pPayload++;
            switch (temp1)
            {
                case 0x01:  // 请求命令

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -