CC2530自動安全聯網

King_Alex發表於2015-01-26

CC2530自動聯網的苦惱

不知道部落格園裡面有沒有人研究CC2530,也就是zigbee技術,其實我在做東西的時候很糾結一個問題,那就是我如何將裝置連上後,如何通過協調者傳送命令給終端呢?有什麼方法可以快捷的解決這個事情呢?zigbee確實是讓我們能夠直接形成一個網路了,但是我們要的是能夠在協調者裡面直接找到相應的終端,然後直接相連不就行了嗎,這樣又快又好!但是在這個過程中我們經常碰到是,我們根本找不到目標終端!

  • zigbee的協調者是會給終端隨機分配一個16位的短地址
  • CC2530雖然有IEEE的長地址,但是這個長地址在獲取的過程中相當複雜
  • CC2530也沒有非常好的demo來解決

我的思考與想法

既然我們無法容易的得到長地址,而且長地址的資料量也是有點大的,光使用協議,每次都輸相應的長地址,這不是找死是什麼,閒自己的資料還不夠多嗎?於是我思考了一段時間,哈哈哈,為什麼我們不能自己建立對映表來對應相應的短地址,就像一張表格一樣。或者說像資料庫的模式學習,一個是標題欄,一個是值,這個值是短地址,但是標題欄永遠不會變不就可以了嗎?

CC2530自動安全聯網

動手實現一下

那麼從何開始呢?我們不能亂碰啊!首先你得知道咋麼建立網路連線吧!,等等,有人說:我沒有安裝檔案,你說的z-stack2007那個玩意在哪呢?好吧,我把它放出來!TI的官網上早就沒有這個了,因為它是version2.5a的 現在的是TI的 z-stack home 是version2.6a版的,筆者比較懶,沒想用2.6a的,原因嘛~~~因為不高興再使用新的工具去調了!

z-satck-version 2.5

開發工具及序號產生器 IAR 8.10版

分析一下自帶的zigbee的聯網

在sampleapp.c中我們來看看zigbee是如何聯網的!

afAddrType_t SampleApp_Periodic_DstAddr;
afAddrType_t SampleApp_Flash_DstAddr;

afAddrType_t 沒錯就是這個東西,不明白,沒關係,我們使用go to defintion 去看看它是如何定義的!

typedef enum
{
  afAddrNotPresent = AddrNotPresent, //按照繫結表進行繫結傳輸
  afAddr16Bit      = Addr16Bit,// 指定目標網路地址進行單薄傳輸 16位
  afAddr64Bit      = Addr64Bit,
  afAddrGroup      = AddrGroup,// 組播傳輸 
  afAddrBroadcast  = AddrBroadcast//廣播傳輸 
} afAddrMode_t;

typedef struct
{
  union
  {
    uint16      shortAddr;//隨機分配的短地址
    ZLongAddr_t extAddr;
  } addr;
  afAddrMode_t addrMode;//afAddrMode_t是一個列舉型別 模式引數
  uint8 endPoint;  //指定的端點號 端點241—254保留端點 範圍 1-240
  uint16 panId;  // 加入的panid 就是在哪個網段上
} afAddrType_t;

看到我上面的註釋了吧? 哈哈,那麼我們就可以模仿它來寫我們的網路協議
回到sampleapp.c我們新增自己的對點網路。

afAddrType_t SampleApp_Periodic_DstAddr;
afAddrType_t SampleApp_Flash_DstAddr;
/**自己定義的點對點的傳輸**/

  afAddrType_t SampleApp_Point_to_Point_DstAddr;

/**************/

ok了,那麼我們上面不是說了要用對映的形式 對不對?

uint16 Routing_Table[DEV_COUNT][1]={0} 定義路由表單那是必須的 你有多少個zigbee你就得用多少的DEV_COUNT

這個呢就直接放在我們點對點的傳輸定義的下面就可以了!

  // Setup for the periodic message's destination address
  // Broadcast to everyone
  SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;
  SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
  SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;

  // Setup for the flash command's destination address - Group 1
  SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
  SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
  SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;

往下翻,你看到了嗎?沒錯,這個就是配置我們網路模式的函式了,可以與上面的afAddrType_t定義的內容一一對應哦!
好了 我們也可以通過自己的方法寫自己的配置模式!

  // Setup for the flash command's destination address - Group 1
  SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;
  SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
  SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
/***設定點對點的地址方案****/
  SampleApp_Point_to_Point_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//點對點模式
  SampleApp_Point_to_Point_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;
  SampleApp_Point_to_Point_DstAddr.addr.shortAddr = 0xffff;//資料從發給全部裝置
/********************************/

找到這個函式uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )沒錯這個函式其實是傳送處理函式。

傳送端處理

uint8 buffer[4];//存放加入網路的資料
            buffer[0] = 'm';
            buffer[1] = DEV_NUM;// 裝置號 你需要自己定義         
            buffer[2] = 1;
            buffer[3] = 'g';
            SampleApp_Point_to_Point_DstAddr.addr.shortAddr = 0x0000;
            if ( AF_DataRequest( &SampleApp_Point_to_Point_DstAddr,
                       &SampleApp_epDesc,
                       SAMPLEAPP_ADDNET_CLUSTERID,
                       4,
                       buffer,
                       &SampleApp_TransID,
                       AF_DISCV_ROUTE | AF_ACK_REQUEST,
                       AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
                   {
                      #ifdef DEBUG_STAGE
                               HalUARTWrite(0,"Init EndPoint\n\r",sizeof("Init EndPoint\n\r"));
                             //HalLedSet(LED1,LED_ON);
                      #endif 
                   }
                else
                  {
                  // Error occurred in request to send.
                   }
            /*****原函式被註釋
            // Start sending the periodic message in a regular interval.
            osal_start_timerEx( SampleApp_TaskID,
                              SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
                              SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
            */

接收端處理

找到這個函式void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )這個是接受端的處理函式

      uint8 *str = NULL;
      uint8 buffer[4];//用於處理應答
      uint16 shortaddr;//用來存放短地址
      str = pkt->cmd.Data;
      switch ( pkt->clusterId )
{ 
   case SAMPLEAPP_ADDNET_CLUSTERID://入網處理
     
          if(pkt->cmd.Data[0]=='m' && pkt->cmd.Data[3]=='g' && pkt->srcAddr.addr.shortAddr != 0)
          {
            HalLedSet(LED1,LED_ON);//協調者led1亮 表示找到了網路
            shortaddr = pkt->srcAddr.addr.shortAddr;//把收到的終端的地址儲存
            Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]] = shortaddr;  //對應的房間裝置的路由表建立                    
           
                     HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]/4096],1);
                     HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%4096/256],1);
                     HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%256/16],1);
                     HalUARTWrite(0,&asc_16[Routing_Table[pkt->cmd.Data[1]][pkt->cmd.Data[2]]%16],1);
        
             buffer[0] = 'r';//進行回覆          
             buffer[1] = 0;
             buffer[2] = 0;
             buffer[3] = 'a';
             SampleApp_Point_to_Point_DstAddr.addr.shortAddr = shortaddr;//並把應答資訊傳送給終端 入網成功
             if ( AF_DataRequest( &SampleApp_Point_to_Point_DstAddr, &SampleApp_epDesc,
                           SAMPLEAPP_ADDNET_CLUSTERID,
                           4,
                           buffer,
                           &SampleApp_TransID,
                           AF_DISCV_ROUTE | AF_ACK_REQUEST,
                           AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
            {
             //  HalUARTWrite(0,"get searchmsg\n\r",sizeof("get searchmsg\n\r"));      
             //  HalUARTWrite(0,"bind one end",12);
               HalLedSet(LED1,LED_OFF);//協調者led1燈滅 表示曾找到網路
            }
            else
            {
              // Error occurred in request to send.
            }
         }

然後我們對接受到的資料資訊進行分析,有頭帶m尾g的我們就入網,且迴應協調者r00a 我收到了的意思

SAMPLEAPP_ADDNET_CLUSTERID這個又是從哪冒出來的呢? 嘿嘿就在sampleapp.c的標頭檔案裡面新增自己的輪迴任務ID

申明

如果您轉了我的文章呢,非常之感謝,但請您表明一下出處就可以了,一個連結的事情嘛~~再次感謝各位對我的支援!

相關文章