色yeye在线视频观看_亚洲人亚洲精品成人网站_一级毛片免费播放_91精品一区二区中文字幕_一区二区三区日本视频_成人性生交大免费看

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > Zigbee——串口無線透傳分析

Zigbee——串口無線透傳分析 時間:2017-10-25      來源:未知

透傳的基本概念:

透傳就是透明傳輸的簡稱。那么什么是透明傳輸呢?顧名思義,透明傳輸就是指在傳輸過程中,對外界完全透明,不需要關系傳輸過程以及傳輸協議,終目的是要把傳輸的內容原封不動的傳遞給被接收端,發送和接收的內容完全一致。這就相當于把信息直接扔給你想要傳輸的人,只需要扔(也就是傳輸)這一個步驟,不需要其他的內容安排。

串口無線透傳編程流程:

程序需要實現的功能:

1、 ZigBee 模塊接收到從 PC 機發來的消息,然后無線發送出去

2、 ZigBee 模塊接收到其他 ZigBee 模塊發來的消息,然后發送給 PC 機

發送和接收數據的流程:

發送數據:

填充并注冊端點描述符 配置發送模式及目的地址AF_DataRe quest()發送數據

接收數據:

填充并注冊端點描述符處理系統事件 SYS_EVENT_MSG 中的AF_INCOMING _MSG_CMD 消息獲得消息包中的無線數據

相關的API函數或結構體的介紹:

串口無線透傳我們需要掌握以下重點:

端點描述符

簡單描述符

如何發送數據

如何接收數據

我們重點分析四個函數:

任務的初始化函數

任務的事件處理函數

無線消息接收回調函數

無線消息發送函數

端口描述符的定義:

端點(Endpoint)是協議棧應用層入口,它通常為節點的一個通信部件或設備(如各種類型的傳感器、開關、 LED 燈等)也是用戶定義的應用對象駐留的地方。端點類似于在計算機 TCP/IP 網絡通信中,為方便計算機中不同的進程進行通信,在傳輸層設置的端口(Port)概念。端點和 IEEE64 位擴展地址、16 位網絡短地址一樣,是 ZigBee 無線通信的一個重要地址參數,能夠為多個應用對象提供邏輯子通道以進行通信。每個 ZigBee 設備支持多達 240 個端點,也就是說,每個設備多可以定義 240 個應用對象。端點 0 必須在ZigBee 設備中具有,它分配給 ZigBee 設備對象(ZD0)使用,端點 255 是端點廣播地址,端點 241~254 保留,為以后擴展使用。端點描述符用來描述一個端點,Z-Stack 中的 AF.h 中有關于端點描述符的定義如下:

typedef struct

{

  uint8 endPoint;     //端口號

  uint8 *task_id;     // 指向任務ID號  Pointer to location of the Application task ID.

  // 簡單設備描述符  可以通過go to…的方式查看結構體變量的類型

  SimpleDescriptionFormat_t *simpleDesc;  

  afNetworkLatencyReq_t latencyReq;   // 延時,采用默認值初始化即可

} endPointDesc_t;

端點描述符的初始化:

端點描述符需要在應用層 SampleApp.c 文件中的 SampleApp_Init()函數中進行端點填充,并向 AF 層注冊端點描述符。第一次對話實驗中填充端點描述符的過程如下,該部分代碼比較固定。

void SampleApp_Init( uint8 task_id )

{

  // Fill out the endpoint description.

  // 以下四行是對節點描述符進行初始化

  // 我們需要手動指定端口號,程序中 SAMPLEAPP_ENDPOINT 的宏值為20,

// 可以使用的端口號范圍:1~240,用戶可根據需要進行修改。

  SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT;

  //指定任務 ID,這里我們指向的是當前任務的 ID。

  SampleApp_epDesc.task_id = &SampleApp_TaskID;

// 指向簡單描述符。我們下邊會分析簡單描述符的定義。

  SampleApp_epDesc.simpleDesc

            = (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;

// 采用默認值 noLatencyReqs 即可

  SampleApp_epDesc.latencyReq = noLatencyReqs;

  // Register the endpoint description with the AF

  // 用 afRegister()函數向 AF 層注冊端點描述符。

  afRegister( &SampleApp_epDesc );

}

簡單設備描述符的定義:

typedef struct

{

  uint8          EndPoint;                // 端口號

  uint16         AppProfId;               // 應用規范ID

  uint16         AppDeviceId;             // 應用設備ID

  uint8          AppDevVer:4;             // 應用版本設備號

  uint8          Reserved:4;              // 保留  AF_V1_SUPPORT uses for AppFlags:4.

  uint8          AppNumInClusters;        // 輸入簇的個數

  cId_t         *pAppInClusterList;       // 輸入簇的列表

  uint8          AppNumOutClusters;       // 輸出簇的個數

  cId_t         *pAppOutClusterList;      // 輸出簇的列表

} SimpleDescriptionFormat_t;

簡單設備描述符的初始化:

宏定義在SampleApp.h文件中

#define SAMPLEAPP_ENDPOINT           20   // 端口號20

#define SAMPLEAPP_PROFID             0x0F08

#define SAMPLEAPP_DEVICEID           0x0001

#define SAMPLEAPP_DEVICE_VERSION     0

#define SAMPLEAPP_FLAGS              0

#define SAMPLEAPP_MAX_CLUSTERS       2

#define SAMPLEAPP_PERIODIC_CLUSTERID 1

#define SAMPLEAPP_FLASH_CLUSTERID     2

初始化在SampleApp.c文件中

const cId_t SampleApp_ClusterList[SAMPLEAPP_MAX_CLUSTERS] =

{

  SAMPLEAPP_PERIODIC_CLUSTERID,

  SAMPLEAPP_FLASH_CLUSTERID

};

const SimpleDescriptionFormat_t SampleApp_SimpleDesc =

{

  SAMPLEAPP_ENDPOINT,              //  int Endpoint;  端口號

  SAMPLEAPP_PROFID,                //  uint16 AppProfId[2];  應用規范ID

  SAMPLEAPP_DEVICEID,              //  uint16 AppDeviceId[2];  應用設備ID

  SAMPLEAPP_DEVICE_VERSION,        //  int   AppDevVer:4;    應用設備版本號

  SAMPLEAPP_FLAGS,                 //  int   AppFlags:4;     保留

  SAMPLEAPP_MAX_CLUSTERS,          //  uint8  AppNumInClusters;  輸入簇命令個數

  (cId_t *)SampleApp_ClusterList,  //  uint8 *pAppInClusterList; 輸入簇列表

  SAMPLEAPP_MAX_CLUSTERS,          //  uint8  AppNumInClusters;  輸出簇命令個數

  (cId_t *)SampleApp_ClusterList   //  uint8 *pAppOutClusterList;輸出簇列表 

};

發送數據函數詳解:

【1】 afStatus_t AF_DataRequest(

afAddrType_t *dstAddr, //包含目的節點的網絡地址以及發送數據的格式,如廣播、組播或單播。

endPointDesc_t *srcEP,//某一個節點上不同的端口 (endpoint) ,我們可以理解為 TCP/IP 中的端口。

uint16cID,//該參數主要是為了區分不同的命令,對應簡單描述符中的輸出群集

uint16 len,//該參數標識了發送數據的長度。

uint8 *buf,//該參數是指向發送緩沖區的指針。

uint8 *transID,//該參數是指向發送序號的指針。可以用來檢測丟包率,由OSAL維護。

uint8 options,//取默認值 AF_DISCV_ROUTE 即可。

uint8 radius//取默認值 AF_DEFAULT_RADIUS 即可。

    )

【2】對于發送數據函數AF_DataRequest函數的具體實現,

只需要理解zigbee協議棧是通過發送函數實現廣播、組播、單播的即可。

【3】這里重點關注AF_DataRequest函數的第一個參數,可以通過go to……的方式跳轉到第一個參數的變量類型:

第一個參數是一個結構體:如下

typedef struct

{

union

{

uint16      shortAddr;   //代表節點的網絡地址

ZLongAddr_t extAddr;

} addr;

afAddrMode_t addrMode;   //重點關注這個變量,他代表我的發送形式

uint8 endPoint;

uint16 panId;  // used for the INTER_PAN feature

} afAddrType_t;

afAddrMode_t變量是一個枚舉類型:

typedef enum

{

afAddrNotPresent = AddrNotPresent,

afAddr16Bit      = Addr16Bit,     //代表單播

afAddr64Bit      = Addr64Bit,     

afAddrGroup      = AddrGroup,     //代表組播

afAddrBroadcast  = AddrBroadcast  //代表廣播

} afAddrMode_t;

上述使用到的Addr16Bit,AddrGroup,,AddrBroadcast是一個常數,在zigbee協議棧中具有定義:如下

enum

{

AddrNotPresent = 0,

AddrGroup = 1,

Addr16Bit = 2,

Addr64Bit = 3,

AddrBroadcast = 15

};

接收數據函數詳解:

當設備接收到無線數據后,操作系統會將該數據封裝成一個消息然后放入消息隊列中,同時設置系統事件SYS_EVENT_MSG ,應用層的事件處理函數 SampleApp_ProcessEvent 會處理這個事件,他首先會將消息從消息隊列中取出,根據消息的 ID 判斷該消息是否就是接收到的數據,標識接收到新數據的消息 ID 是 AF_INCOMING_MSG_CMD,其中 AF_ INCOMING_MSG_CMD 的值是 0x1a,這是在 ZigBee 協議棧中定義好的,用戶不可更改。

具體的事件處理函數代碼如下所示,這部分代碼比較固定,我們只需要熟悉這種事件處理結構即可。

// 事件處理函數

uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )

{

  afIncomingMSGPacket_t *MSGpkt;

  (void)task_id;  // Intentionally unreferenced parameter

  if ( events & SYS_EVENT_MSG )

  {

    // 獲取消息

    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );

    while ( MSGpkt )

    {

      switch ( MSGpkt->hdr.event )

      {

        // Received when a messages is received (OTA) for this endpoint

        case AF_INCOMING_MSG_CMD://接收數據事件,調用函數AF_DataRequest()接收數據

          SampleApp_MessageMSGCB( MSGpkt );//調用回調函數對收到的數據進行處理

          break;

        default:

          break;

      }

      // Release the memory   事件處理完了,釋放消息占用的內存

      osal_msg_deallocate( (uint8 *)MSGpkt );

      // Next - if one is available 指針指向下一個放在緩沖區的待處理的事件,

      //返回while ( MSGpkt )重新處理事件,直到緩沖區沒有等待處理事件為止

      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );

    }

    // return unprocessed events   返回未處理的事件

    return (events ^ SYS_EVENT_MSG);

  }

  // Discard unknown events

  return 0;

}

SampleApp_MessageMSGCB( MSGpkt );函數使用說明:

// 接收到消息,消息處理回調函數

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )

{

  uint16 flashTime;

  switch ( pkt->clusterId )

  {

case SAMPLEAPP_PERIODIC_CLUSTERID:

HalUARTWrite (0, (pkt->cmd).Data, ((pkt->cmd).DataLength));

      break;

    case SAMPLEAPP_FLASH_CLUSTERID:

      flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );

      HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );

      break;

  }

}

思考兩個問題:

為什么要根據SAMPLEAPP_ PERIODIC_CLUSTERID 才能得到正確的數據呢?

在 ZigBee 網絡中進行通信時需要注意的,兩者如果想進行通信,需要具有相同的 Cluster ID,而且一個選擇“輸入” ,另一個選擇“輸出”(在簡單描述符中填充) 。

收到的數據在哪里?

在 pkt 指向的那個結構體里,我們去看下 afIncomingMSGPacket_t 的真面目了。

接收數據的存放位置:

typedef struct

{

  osal_event_hdr_t hdr;     /* OSAL Message header */

  uint16 groupId;           /* Message's group ID - 0 if not set */

  uint16 clusterId;         /* Message's cluster ID */

  afAddrType_t srcAddr;     /* Source Address, if endpoint is STUBAPS_INTER_PAN_EP,

                               it's an InterPAN message */

  uint16 macDestAddr;       /* MAC header destination short address */

  uint8 endPoint;           /* destination endpoint */

  uint8 wasBroadcast;       /* TRUE if network destination was a broadcast address */

  uint8 LinkQuality;        /* The link quality of the received data frame */

  uint8 correlation;        /* The raw correlation value of the received data frame */

  int8  rssi;               /* The received RF power in units dBm */

  uint8 SecurityUse;        /* deprecated */

  uint32 timestamp;         /* receipt timestamp from MAC */

  uint8 nwkSeqNum;          /* network header frame sequence number */

  afMSGCommandFormat_t cmd; /* Application Data */

} afIncomingMSGPacket_t;

afMSGCommandFormat_t結構體的聲明:

typedef struct

{

  uint8   TransSeqNumber;   //用于存儲發送序列號;

  uint16  DataLength;              //用于存儲接收到的數據長度;

  uint8  *Data;            //數據接收后放在一個緩沖區,該參數就是指向緩沖區的指針;

} afMSGCommandFormat_t;

上一篇:什么是USB

下一篇:條件變量演示

熱點文章推薦
華清學員就業榜單
高薪學員經驗分享
熱點新聞推薦
前臺專線:010-82525158 企業培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5京公海網安備11010802025203號

回到頂部

主站蜘蛛池模板: 国产欧美日韩A片免费软件 四虎影视免费 | 人妻少妇精品视频专区 | 色情大片AAAAAA视频 | 午夜免费啪视频在线体验区 | 亚洲AV日韩AV一区二区三曲 | 国产美女裸体无遮挡免费视频 | 巨胸喷奶水视频WWW免费网站 | 全部免费的毛片无遮挡 | 亚洲av综合av一区 | 国产欧美日韩精品在线观看 | 无码AV波多野结衣久久 | 嫩草影院永久入口 | 麻豆影视在线免费观看 | 最新国产一级片 | 午夜神器成在线人成在线人 | 23部禽女乱小说内裤畸情视频 | 无码欧美激情性做爰免费 | 亚洲欧洲日产国码久在线 | 三上悠亚日韩精品二区 | 一本无码中文字幕在线观 | 色综合久久综合欧美综合网 | 黑人和黑人一级毛片 | 亚洲高清专区日韩精品 | 丰满少妇被猛烈进AV毛片 | 亚洲精品国产自在现线最新 | 亚洲丁香婷婷综合久久 | 狠狠躁天天躁无码中文字幕 | 综合亚洲另类欧美久久成人精品 | 久久久久精品无码专区 | 18无码粉嫩小泬无套在线观看 | 日本喷奶水中文字幕视频 | 亚洲色成人一区二区三区小说 | 欧美videosdesexo肥婆 | 人妻少妇看a片偷人精品视频 | 五月婷久久综合狠狠爱97 | 中文字幕中文字幕在线中心一区 | 精品国自产在线观看 | 白丝女仆被主人调教喷水蜜臀 | 桃色AV久久无码线观看 | 人妻av中文字幕无码专区 | 国产精品av久久久久久小说 |