1. 程式人生 > >Zigbee 兩串列埠除錯助手通過兩節點無線通訊

Zigbee 兩串列埠除錯助手通過兩節點無線通訊

Zigbee  兩串列埠除錯助手通過兩節點無線通訊

//Coordinator.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"  
  
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS]=  
{  
  GENERICAPP_CLUSTERID   
};  
  
//簡單裝置描述符(描述一個ZigBee裝置節點)  
const SimpleDescriptionFormat_t GenericApp_SimpleDesc=  
{  
  GENERICAPP_ENDPOINT,  
  GENERICAPP_PROFID,  
  GENERICAPP_DEVICEID,  
  GENERICAPP_DEVICE_VERSION,  
  GENERICAPP_FLAGS,  
  GENERICAPP_MAX_CLUSTERS,  
   
 (cId_t*)GenericApp_ClusterList, //?????  
  0,  
  (cId_t *)NULL  
};  
  
endPointDesc_t GenericApp_epDesc;//節點描述符  
byte GenericApp_TaskID;//任務優先順序  
byte GenericApp_TransID;//資料傳送序列號。  
  
  

  
  
  
void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pckt);//訊息處理函式  
void GenericApp_SendTheMessage(void);//資料傳送函式  
void GenericApp_SendTheMessage_two(void);

static void rxCB(uint8 port,uint8 envent);//???????????  
  
void GenericApp_Init(byte task_id)//任務初始化函式  
{  
  GenericApp_TaskID     =task_id;   //初始化任務優先順序(任務優先順序有協議棧的作業系統OSAL分配)  
  GenericApp_TransID    =0;         //傳送資料包的序號初始化為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);//afRegister()對節點的描述符進行註冊。註冊後,才能使用OSAL提供的系統服務。  
    
    
  halUARTCfg_t uartConfig;//該結構體變數是實現 串列埠的配置  
  //串列埠的初始化  
  uartConfig.configured   =TRUE;  
  uartConfig.baudRate     =HAL_UART_BR_115200;//波特率  
  uartConfig.flowControl  =FALSE;             //流控制  
  uartConfig.callBackFunc =rxCB;             //填的是回撥函式 ,數的指標(即函式的地址)作為引數傳遞給另一個函式,  
  //其實callBackFunc是一個函式指標,它的定義為halUARTCBack_t callBackFunc;  
  //而halUARTCBack_t的定義為 typed void (*halUARTCBack_t)(uint8 port,uint8 envent) 定義的是一個函式指標  
  HalUARTOpen(0,&uartConfig);                 //串列埠是否開啟  
}  
  
//下面這個是回撥函式,回電函式就是一個通過函式指標(函式地址)呼叫的函式,如果把函式的指標(即函式的地址)作為引數傳遞給另一  
//個函式,當通過該指正呼叫它鎖指向的函式時,稱為函式的回撥。  
  
//回撥函式不是有該函式的實現方直接呼叫的,而是在特定的事件或條件時,由另一方呼叫的額,用於對該事件或條件進行響應。  
//回撥函式機制提供了系統對非同步事件的處理能力。  

 unsigned char uartbuf[128];//串列埠接收發送資料緩衝單元  
static void rxCB(uint8 port,uint8 envent)  
{ 
 
  int rxlen=Hal_UART_RxBufLen(0); //接收緩衝區資料長度,位元組為單位
  if(rxlen)
  {
    HalUARTRead(0,uartbuf,rxlen);   //從串列埠讀取資料放在uartbuf緩衝區中 
  //  HalUARTWrite(0,uartbuf,rxlen); 
    uartbuf[rxlen]='\0';
    GenericApp_SendTheMessage_two() ;
   //  HalLedBlink(HAL_LED_2,0,50,500);    //LED2 閃爍  
  }
}  
  
  
//訊息處理函式      
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:          //接受到新資料的訊息的ID是AF_INCOMING_MSG_CMD,這個巨集是在協議棧中定義好的值為0x1A  
                                       //接受到的是無線資料包  
     GenericApp_MessageMSGCB(MSGpkt);//功能是完成對接受資料的處理  
      break;  
    default:  
      break;  
    }    
    osal_msg_deallocate((uint8 *)MSGpkt);//接收到的訊息處理完後,釋放訊息所佔的儲存空間      
     MSGpkt=(afIncomingMSGPacket_t*)osal_msg_receive(GenericApp_TaskID);  
    //處理完一個訊息後,再從訊息佇列裡接受訊息,然後對其進行相應處理,直到所有訊息處理完  
   }  
   return (events ^ SYS_EVENT_MSG);  
  }  
   return 0;  
}  
  
bool flag=true;
uint16 shorAddr=0;


void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pkt)  
{   
  unsigned char addr[2];
 switch(pkt->clusterId)  
 {  
 case GENERICAPP_CLUSTERID:  
   if(flag)
   {
     osal_memcpy(addr,pkt->cmd.Data,2);     
     osal_memcpy(&shorAddr,addr,2);
     flag=false;
   }
   else
   {
      
      HalUARTWrite( 0, pkt->cmd.Data, (pkt->cmd.DataLength) ) ; //接收的資料傳送的串列埠 
      HalLedBlink(HAL_LED_2,0,50,500);    //LED2 閃爍
   }
   break;  
 }  
} 

void GenericApp_SendTheMessage_two(void)  
{  
  afAddrType_t my_DstAddr;      
  my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;//資料傳送模式:可選 單播、廣播、多播方式  這裡選Addr16Bit表單播  
  my_DstAddr.endPoint=GENERICAPP_ENDPOINT;   //初始化埠函  
  my_DstAddr.addr.shortAddr=shorAddr;  //標誌目的地址節點的網路地址  這裡是協調器的地址    
  //下面是資料傳送                                                  長度  資料傳送緩衝區  
    AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,\
    osal_strlen(uartbuf)+1,uartbuf,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);  
    HalLedBlink(HAL_LED_1,0,50,500);    //LED2 閃爍  
}

//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  //傳送事件id  
  
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS]=  
{  
 GENERICAPP_CLUSTERID  
};  
  
//初始化埠描述符  
const SimpleDescriptionFormat_t GenericApp_SimpleDesc=  
{  
  GENERICAPP_ENDPOINT,  
  GENERICAPP_PROFID,  
  GENERICAPP_DEVICEID,  
  GENERICAPP_DEVICE_VERSION,  
  GENERICAPP_FLAGS,  
  0,  
  (cId_t*)NULL,  
  GENERICAPP_MAX_CLUSTERS,  
  (cId_t*)GenericApp_ClusterList    
};  
  
endPointDesc_t GenericApp_epDesc;//節點描述符  
byte GenericApp_TaskID;          //任務優先順序  
byte GenericApp_TransID;         //資料傳送序列號  
devStates_t GenericApp_NwkState;//儲存節點狀態  
  
void GenericApp_MessageMSGCB(afIncomingMSGPacket_t* pckt);//訊息處理函式的宣告  
void GenericApp_SendTheMessage(void); //資料傳送函式的宣告  
void GenericApp_SendTheMessage_two(void); //資料傳送函式的宣告  
static void rxCB(uint8 port,uint8 envent);//???????????  
void To_string(uint8 *dest,char *src,uint8 length);
//任務初始化函式  
void GenericApp_Init(byte task_id)  
{  
  GenericApp_TaskID     = task_id;//初始化任務優先順序  
  GenericApp_NwkState   =DEV_INIT; //初始化為DEV_INIT,表節點沒有連線到ZigBee網路  
  GenericApp_TransID    =0;        //傳送資料包的序列號初始化為0  
  //對節點描述符進行初始化  
  GenericApp_epDesc.endPoint=GENERICAPP_ENDPOINT;  
  GenericApp_epDesc.task_id =&GenericApp_TaskID;  
  GenericApp_epDesc.simpleDesc=(SimpleDescriptionFormat_t*)&GenericApp_SimpleDesc;  
  GenericApp_epDesc.latencyReq=noLatencyReqs;  
  //afRegister()函式將節點描述符進行註冊,註冊後才可以使用OSAL提供的系統服務  
  afRegister(&GenericApp_epDesc);  
  
   halUARTCfg_t uartConfig;//該結構體變數是實現 串列埠的配置  
  //串列埠的初始化  
  uartConfig.configured   =TRUE;  
  uartConfig.baudRate     =HAL_UART_BR_115200;//波特率  
  uartConfig.flowControl  =FALSE;             //流控制  
  uartConfig.callBackFunc =rxCB;             //填的是回撥函式 ,數的指標(即函式的地址)作為引數傳遞給另一個函式,  
  //其實callBackFunc是一個函式指標,它的定義為halUARTCBack_t callBackFunc;  
  //而halUARTCBack_t的定義為 typed void (*halUARTCBack_t)(uint8 port,uint8 envent) 定義的是一個函式指標 
   HalUARTOpen(0,&uartConfig);                 //串列埠是否開啟  
}  

//unsigned char theMessageData[128]="EndDevice";//存放傳送資料 
//回撥函式不是有該函式的實現方直接呼叫的,而是在特定的事件或條件時,由另一方呼叫的額,用於對該事件或條件進行響應。  
//回撥函式機制提供了系統對非同步事件的處理能力。  
  unsigned char uartbuf[128];//串列埠接收發送資料緩衝單元
static void rxCB(uint8 port,uint8 envent)  
{

  int rxlen=Hal_UART_RxBufLen(0); //接收緩衝區資料長度,位元組為單位
  if(rxlen)
  {
    HalUARTRead(0,uartbuf,rxlen);   //從串列埠讀取資料放在uartbuf緩衝區中 
   // HalUARTWrite(0,uartbuf,rxlen); 
    //傳送到天
   uartbuf[rxlen]='\0';
   GenericApp_SendTheMessage_two() ; 
 //  HalLedBlink(HAL_LED_2,0,50,500);    //LED2 閃爍  
  }
} 

  
//訊息處理函式  
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_envent()函式設定SEND_DATA_EVENT事件,當事件發生時,執行事件處理函式  
       // osal_set_event(GenericApp_TaskID,SEND_DATA_EVENT);//??????????????????????????  
        GenericApp_SendTheMessage(); //終端節點型別,執行無線資料傳送  
     }  
     break;
      
    case AF_INCOMING_MSG_CMD:          //接受到新資料的訊息的ID是AF_INCOMING_MSG_CMD,這個巨集是在協議棧中定義好的值為0x1A  
                                       //接受到的是無線資料包  
       GenericApp_MessageMSGCB(MSGpkt);//功能是完成對接受資料的處理  
      break;  
    default:  
      break;  
      }  
    osal_msg_deallocate((uint8*)MSGpkt);  
    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);  
   //定時器,三個引數:一參:表定時事件到底後,那個任務對其作出響應  
   //二參:時間ID,表時間達到後,事件發生,該事件的處理函式中實現資料的傳送。  
   //三參:定時的時間數量,單位毫秒。  
   osal_stop_timerEx(GenericApp_TaskID,SEND_DATA_EVENT);
   return (events^SEND_DATA_EVENT);//清除事件標誌  
  }  
  return 0;  
}  
   uint16 shorAddr;
   unsigned char addr[2];

void GenericApp_SendTheMessage(void)  
{  
  shorAddr=NLME_GetShortAddr(); 
  afAddrType_t my_DstAddr;      
  my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;//資料傳送模式:可選 單播、廣播、多播方式  這裡選Addr16Bit表單播  
  my_DstAddr.endPoint=GENERICAPP_ENDPOINT;   //初始化埠函  
  my_DstAddr.addr.shortAddr=0x0000;  //標誌目的地址節點的網路地址  這裡是協調器的地址    
  //下面是資料傳送                                                  長度  資料傳送緩衝區  
 
  AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,\
  2, (uint8*)&shorAddr,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS); 
} 

void GenericApp_MessageMSGCB(afIncomingMSGPacket_t *pkt)  
{  
 switch(pkt->clusterId)  
 {  
 case GENERICAPP_CLUSTERID:  
   
   HalUARTWrite( 0, pkt->cmd.Data, (pkt->cmd.DataLength) ) ; //接收的資料傳送的串列埠 
   HalLedBlink(HAL_LED_2,0,50,500);    //LED2 閃爍  
  // GenericApp_SendTheMessage_two() ;
   break;  
 }  
} 

void GenericApp_SendTheMessage_two(void)  
{  
  afAddrType_t my_DstAddr;      
  my_DstAddr.addrMode=(afAddrMode_t)Addr16Bit;//資料傳送模式:可選 單播、廣播、多播方式  這裡選Addr16Bit表單播  
  my_DstAddr.endPoint=GENERICAPP_ENDPOINT;   //初始化埠函  
  my_DstAddr.addr.shortAddr=0x0000;  //標誌目的地址節點的網路地址  這裡是協調器的地址    
  //下面是資料傳送                                                  長度  資料傳送緩衝區  
    AF_DataRequest(&my_DstAddr,&GenericApp_epDesc,GENERICAPP_CLUSTERID,\
    osal_strlen(uartbuf)+1,uartbuf,&GenericApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS);  
    HalLedBlink(HAL_LED_1,0,50,500);    //LED2 閃爍  
  // HalUARTWrite(0, addr,2); 
}