日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[zigbee][z-Stack]协议栈简介及工作流程

發(fā)布時(shí)間:2024/8/1 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [zigbee][z-Stack]协议栈简介及工作流程 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 什么是zigbee協(xié)議棧?
    • 如何使用zigbee協(xié)議棧?
    • z-Stack工作流程

什么是zigbee協(xié)議棧?

協(xié)議棧是協(xié)議的具體實(shí)現(xiàn)形式,通俗點(diǎn)來(lái)理解就是協(xié)議棧是協(xié)議和用戶之間的一個(gè)缺口,開發(fā)人員通過(guò)使用協(xié)議棧來(lái)使用這個(gè)協(xié)議的,進(jìn)而實(shí)現(xiàn)無(wú)線數(shù)據(jù)收發(fā)。

ZigBee的協(xié)議分為兩部分,IEEE 802.15.4定義了PHY(物理層)和MAC(介質(zhì)訪問(wèn)層)技術(shù)規(guī)范;ZigBee聯(lián)盟定義了NWK(網(wǎng)絡(luò)層) APS(應(yīng)用程序支持子層) APL(應(yīng)用層)技術(shù)規(guī)范。

ZigBee協(xié)議棧就是將各個(gè)層定義的協(xié)議都集合在一起,以函數(shù)的形式實(shí)現(xiàn),并給用戶提供API(應(yīng)用層),用戶可以直接調(diào)用。
無(wú)線網(wǎng)絡(luò)協(xié)議層👇

如何使用zigbee協(xié)議棧?

協(xié)議棧是協(xié)議的實(shí)現(xiàn),可以理解為代碼,函數(shù)庫(kù),供上層應(yīng)用調(diào)用,協(xié)議棧底下的層與應(yīng)用是相互獨(dú)立的。商業(yè)的協(xié)議棧就是給你寫好了底層的代碼,符合協(xié)議標(biāo)準(zhǔn),提過(guò)給你一個(gè)功能模塊給你調(diào)用。

我們需要關(guān)心的是我們的應(yīng)用邏輯,數(shù)據(jù)從哪里到哪里,怎么存儲(chǔ),處理;還有系統(tǒng)里的設(shè)備之間的聽信順序什么的,當(dāng)你的應(yīng)用需要數(shù)據(jù)通信時(shí),調(diào)用組網(wǎng)函數(shù)給你組建你想要的網(wǎng)絡(luò);當(dāng)你想從一個(gè)設(shè)備發(fā)數(shù)據(jù)到另一個(gè)設(shè)備時(shí),調(diào)用無(wú)線數(shù)據(jù)發(fā)送函數(shù);當(dāng)然,接收端就調(diào)用接收函數(shù);當(dāng)你的設(shè)備沒事干的時(shí)候你就調(diào)用睡眠函數(shù);要干活的時(shí)候就調(diào)用喚醒函數(shù)。

所以當(dāng)你做具體應(yīng)用時(shí),不需要關(guān)心協(xié)議棧是怎么寫的,里面的每條代碼是什么意思。除非你要做協(xié)議研究。每個(gè)廠商的協(xié)議棧有區(qū)別,也就是函數(shù)名稱和參數(shù)可能有區(qū)別,這個(gè)要看具體的例子、說(shuō)明文檔。

舉個(gè)例子,用戶實(shí)現(xiàn)一個(gè)簡(jiǎn)單的無(wú)線數(shù)據(jù)通信時(shí)的一般步驟:

1、組網(wǎng):調(diào)用協(xié)議棧的組網(wǎng)函數(shù)、加入網(wǎng)絡(luò)函數(shù),實(shí)現(xiàn)網(wǎng)絡(luò)的建立與節(jié)點(diǎn)的加入。2、發(fā)送:發(fā)送節(jié)點(diǎn)調(diào)用協(xié)議棧的無(wú)線數(shù)據(jù)發(fā)送函數(shù),實(shí)現(xiàn)無(wú)線數(shù)據(jù)發(fā)送。3、接收:接收節(jié)點(diǎn)調(diào)用協(xié)議棧的無(wú)線數(shù)據(jù)接收函數(shù),實(shí)現(xiàn)無(wú)線數(shù)據(jù)接收。

是不是看上去很簡(jiǎn)單啊,其實(shí)協(xié)議棧很多都封裝好了,下面我們大概看看無(wú)線發(fā)送函數(shù):

afStatus_t AF_DataRequest(afAddrType_t *dstAddr,endPointDesc_t *srcEP,uint16 cID,uint16 len, //發(fā)送數(shù)據(jù)的長(zhǎng)度uint8 *buf, //指向存放發(fā)送數(shù)據(jù)的緩沖區(qū)的指針uint8 *transID,uint8 options,uint8 radiuis)

用戶調(diào)用該函數(shù)即可實(shí)現(xiàn)數(shù)據(jù)的無(wú)線數(shù)據(jù)的發(fā)送,此函數(shù)中有8個(gè)參數(shù),用戶需要將每個(gè)參數(shù)的含義理解以后,才能熟練使用該函數(shù)進(jìn)行無(wú)線數(shù)據(jù)通信的目的。現(xiàn)在只講其中最重要的兩個(gè)參數(shù),其它參數(shù)不需要死記硬背,以后用多了自然就記住了。

至于調(diào)用該函數(shù)后,如何初始化硬件進(jìn)行數(shù)據(jù)發(fā)送等工作,用戶不需要關(guān)心, ZigBee協(xié)議棧己經(jīng)將所需要的工作做好了,我們只需要調(diào)用相應(yīng)的API函數(shù)即可,而不必關(guān)心具體實(shí)現(xiàn)細(xì)節(jié)。

z-Stack工作流程


下載z-Stack 提取碼:qta9

打開工程:

ZStack2.5.1a\Projects\zstack\Samples\SampleApp\CC2530DB\SampleApp.eww

建議大家復(fù)制工程到非中文目錄,因?yàn)橛行╅_發(fā)環(huán)境對(duì)中文路徑的支持不友好;還有就是不要把文件放的太深層目錄下,目錄太長(zhǎng),打開工程是IAR會(huì)關(guān)閉;(如果使用 IAR 打開工程停止響應(yīng)或關(guān)閉,說(shuō)明你路徑太長(zhǎng), IAR 不識(shí)別,把路徑改短或移上幾層目錄即可解決)

App:應(yīng)用層目錄,這是用戶創(chuàng)建各種不同工程的區(qū)域,在這個(gè)目錄中包含了應(yīng)用層的內(nèi)容和這個(gè)項(xiàng)目的主要內(nèi)容。

HAL:硬件層目錄,包含有與硬件相關(guān)的配置和驅(qū)動(dòng)及操作函數(shù)。MAC:MAC層目錄,包含了MAC層的參數(shù)配置文件及其MAC的LIB庫(kù)的函數(shù)接口文件。MT:實(shí)現(xiàn)通過(guò)串口可控制各層,并與各層進(jìn)行直接交互NWK:網(wǎng)絡(luò)層目錄,包含網(wǎng)絡(luò)層配置參數(shù)文件網(wǎng)絡(luò)層庫(kù)的函數(shù)接口文件及APS層庫(kù)的函數(shù)接口。OSAL:協(xié)議棧的操作系統(tǒng)。Profile:Application framework應(yīng)用框架層目錄,包含AF層處理函數(shù)文件。應(yīng)用框架層是應(yīng)用程序APS層的無(wú)線數(shù)據(jù)接口。Security:安全層目錄,包含安全層處理函數(shù),比如加密函數(shù)等Services:地址處理函數(shù)目錄,包括地址模式的定義及地址處理函數(shù)。Tools:工程配置目錄,包括空間劃分及Z-Stack相關(guān)配置信息。ZDO:ZDO目錄ZMac:MAC層目錄,包括MAC層參數(shù)配置及MAC層LIB庫(kù)函數(shù)回調(diào)處理函數(shù)。ZMain:主函數(shù)目錄,包括入口函數(shù)及硬件配置文件。Output:輸出文件目錄,由IAR IDE自動(dòng)生成

看到工程中有這么多的文件夾和文件,先不要害怕,帶著疑問(wèn)做實(shí)驗(yàn)就行,做的多了就明白了。

用戶自己添加的應(yīng)用任務(wù)程序在 Zstack 中的調(diào)用過(guò)程:

main()---> osal_init_system()---> osalInitTasks()---> SampleApp_Init()

打開ZMain.c找到main函數(shù)

int main( void ) {osal_int_disable( INTS_ALL ); //關(guān)閉所有中斷HAL_BOARD_INIT(); //初始化系統(tǒng)時(shí)鐘zmain_vdd_check(); //檢查芯片電壓是否正常InitBoard( OB_COLD ); //初始化 I/O , LED 、 Timer 等HalDriverInit(); //初始化芯片各硬件模塊osal_nv_init( NULL ); //初始化 Flash 存儲(chǔ)器ZMacInit(); //初始化 MAC 層zmain_ext_addr(); //確定 IEEE 64 位地址zgInit(); //初始化非易失變量#ifndef NONWK// Since the AF isn't a task, call it's initialization routineafInit();#endifosal_init_system(); //初始化操作系統(tǒng)osal_int_enable( INTS_ALL ); //使能全部中斷InitBoard( OB_READY ); //最終板載初始化zmain_dev_info(); //顯示設(shè)備信息#ifdef LCD_SUPPORTEDzmain_lcd_init(); //初始化 LCD#endif#ifdef WDT_IN_PM1/* If WDT is used, this is a good place to enable it. */WatchDogEnable( WDTIMX );#endifosal_start_system();// No Return from here 執(zhí)行操作系統(tǒng),進(jìn)去后不會(huì)返回return 0; // Shouldn't get here. } // main()

看了上面的代碼后,可能感覺很多函數(shù)不認(rèn)識(shí)。沒關(guān)系剛開始大概了解流程即可, main 函數(shù)先執(zhí)行初始化工作,包括硬件、網(wǎng)絡(luò)層、任務(wù)等的初始化。然后執(zhí)行 osal_start_system(); 操作系統(tǒng)。進(jìn)去后可不會(huì)回來(lái)了。

在這里,我們重點(diǎn)了解 2 個(gè)函數(shù):

初始化操作系統(tǒng) osal_init_system();運(yùn)行操作系統(tǒng) osal_start_system();

先來(lái)看osal_init_system();系統(tǒng)初始化函數(shù),進(jìn)入函數(shù)。如果用IAR看代碼可在函數(shù)名上單擊右鍵——go to definition of…,便可以進(jìn)入函數(shù)。發(fā)現(xiàn)里面有6個(gè)初始化函數(shù),這里我們只關(guān)心 osalInitTasks();任務(wù)初始化函數(shù),繼續(xù)由該函數(shù)進(jìn)入。

void osalInitTasks( void ) {uint8 taskID = 0;// 分配內(nèi)存,返回指向緩沖區(qū)的指針tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);// 設(shè)置所分配的內(nèi)存空間單元值為 0osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));// 任務(wù)優(yōu)先級(jí)由高向低依次排列,高優(yōu)先級(jí)對(duì)應(yīng) taskID 的值反而小macTaskInit( taskID++ ); //macTaskInit(0) ,用戶不需考慮nwk_init( taskID++ ); //nwk_init(1),用戶不需考慮Hal_Init( taskID++ ); //Hal_Init(2) ,用戶需考慮#if defined( MT_TASK ) //如果定義 MT_TASK 則調(diào)用 MT_TaskInit()MT_TaskInit( taskID++ );#endifAPS_Init( taskID++ ); //APS_Init(3) ,用戶不需考慮#if defined ( ZIGBEE_FRAGMENTATION )APSF_Init( taskID++ );#endifZDApp_Init( taskID++ ); //ZDApp_Init(4) ,用戶需考慮#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )ZDNwkMgr_Init( taskID++ );#endif//用戶創(chuàng)建的任務(wù)SampleApp_Init( taskID ); // SampleApp_Init _Init(5),用戶需考慮。重要! }

函數(shù)對(duì) taskID 進(jìn)行初始化,每初始化一個(gè), taskID++。大家看到了注釋后面有些寫著用戶需要考慮,有些則寫著用戶不需考慮。沒錯(cuò),需要考慮的用戶可以根據(jù)自己的硬件平臺(tái)或者其他設(shè)置,而寫著不需考慮的也是不能修改的。TI 公司協(xié)議棧已完成。SampleApp_Init()是我們 應(yīng) 用 協(xié) 議 棧 例 程 的 必 要 函 數(shù) , 用 戶 通 常 在 這 里 初 始 化 自 己 的 東 西 。至 此 ,osal_init_system();大概了解完畢。

接下來(lái)看第二個(gè)函數(shù) osal_start_system();運(yùn)行操作系統(tǒng)。同樣用go to definition 的方法進(jìn)入該函數(shù)。

void osal_start_system( void ) {#if !defined ( ZBIT ) && !defined ( UBIT )for(;;) // Forever Loop#endif{uint8 idx = 0;osalTimeUpdate(); //掃描哪個(gè)事件被觸發(fā)了,然后置相應(yīng)的標(biāo)志位Hal_ProcessPoll(); //輪詢 TIMER 與 UARTdo {if (tasksEvents[idx]) // Task is highest priority that is ready.{break; //得到待處理的最高優(yōu)先級(jí)任務(wù)索引號(hào) idx}} while (++idx < tasksCnt);if (idx < tasksCnt){uint16 events;halIntState_t intState;HAL_ENTER_CRITICAL_SECTION(intState);// 進(jìn)入臨界區(qū),保護(hù)events = tasksEvents[idx]; //提取需要處理的任務(wù)中的事件tasksEvents[idx] = 0; //清除本次任務(wù)的事件HAL_EXIT_CRITICAL_SECTION(intState); // 退出臨界區(qū)events = (tasksArr[idx])( idx, events );//通過(guò)指針調(diào)用任務(wù)處理函數(shù),關(guān)鍵HAL_ENTER_CRITICAL_SECTION(intState); //進(jìn)入臨界區(qū)tasksEvents[idx] |= events; // 保存未處理的事件 Add back unprocessed eventsto the current task.HAL_EXIT_CRITICAL_SECTION(intState); // 退出臨界區(qū)}#if defined( POWER_SAVING )else // Complete pass through all task events with no activity?{osal_pwrmgr_powerconserve(); // Put the processor/system into sleep}#endif} }

看一下 events = tasksEvents[idx]; 進(jìn)入 tasksEvents[idx]數(shù)組定義,發(fā)現(xiàn)恰好是osalInitTasks()函數(shù)里面分配空間初始化過(guò)的 tasksEvents。而且 taskID 一一對(duì)應(yīng)。這就是初始化與調(diào)用的關(guān)系。taskID 把任務(wù)聯(lián)系起來(lái)了。

SampleApp_Init()用戶應(yīng)用任務(wù)初始化函數(shù)

void SampleApp_Init( uint8 task_id ) {SampleApp_TaskID = task_id;//osal 分配的任務(wù) ID 隨著用戶添加任務(wù)的增多而改變SampleApp_NwkState = DEV_INIT; //設(shè)備狀態(tài)設(shè)定為 ZDO 層中定義的初始化狀態(tài)/*初始化應(yīng)用設(shè)備的網(wǎng)絡(luò)類型,設(shè)備類型的改變都要產(chǎn)生一個(gè)事件—ZDO_STATE_CHANGE,從字面理解為 ZDO 狀態(tài)發(fā)生了改變。所以在設(shè)備初始化的時(shí)候一定要把它初始化為什么狀態(tài)都沒有。那么它就要去檢測(cè)整個(gè)環(huán)境,看是否能重新建立或者加入存在的網(wǎng)絡(luò)。但是有一種情況例外,就是當(dāng) NV_RESTORE 被設(shè)置的候( NV_RESTORE 是把信息保存在非易失存儲(chǔ)器中),那么當(dāng)設(shè)備斷電或者某種意外重啟時(shí),由于網(wǎng)絡(luò)狀態(tài)存儲(chǔ)在非易失存儲(chǔ)器中,那么此時(shí)就只需要恢復(fù)其網(wǎng)絡(luò)狀態(tài),而不需要重新建立或者加入網(wǎng)絡(luò)了.這里需要設(shè)置 NV_RESTORE 宏定義。*/SampleApp_TransID = 0; //消息發(fā)送 ID(多消息時(shí)有順序之分)#if defined ( BUILD_ALL_DEVICES )if ( readCoordinatorJumper() )zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;elsezgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;#endif // BUILD_ALL_DEVICES//該段的意思是,如果設(shè)置了 HOLD_AUTO_START 宏定義,將會(huì)在啟動(dòng)芯片的時(shí)候會(huì)暫停啟動(dòng)流程,只有外部觸發(fā)以后才會(huì)啟動(dòng)芯片。其實(shí)就是需要一個(gè)按鈕觸發(fā)它的啟動(dòng)流程。#if defined ( HOLD_AUTO_START )ZDOInitDevice(0);#endif//設(shè)置發(fā)送數(shù)據(jù)的方式和目的地址尋址模式//發(fā)送模式:廣播發(fā)送SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast; //廣播SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; //指定端點(diǎn)號(hào)SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;//指定目的網(wǎng)絡(luò)地址為廣播地址//發(fā)送模式:組播發(fā)送 Setup for the flash command's destination address - Group 1SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; //組尋址SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; //指定端點(diǎn)號(hào)SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP; //組號(hào) 0x0001//定義本設(shè)備用來(lái)通信的 APS 層端點(diǎn)描述符SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT;SampleApp_epDesc.task_id = &SampleApp_TaskID; //SampleApp 描述符的任務(wù) IDSampleApp_epDesc.simpleDesc //SampleApp 簡(jiǎn)單描述符= (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;SampleApp_epDesc.latencyReq = noLatencyReqs; //延時(shí)策略//向 AF 層登記描述符, 登記 endpoint description 到 AF,要對(duì)該應(yīng)用進(jìn)行初始化并在 AF/*進(jìn)行登記,告訴應(yīng)用層有這么一個(gè) EP 已經(jīng)開通可以使用,那么下層要是有關(guān)于該應(yīng)用的信息或者應(yīng)用要對(duì)下層做哪些操作,就自動(dòng)得到下層的配合*/afRegister( &SampleApp_epDesc );// 登記所有的按鍵事件RegisterForKeys( SampleApp_TaskID );// By default, all devices start out in Group 1SampleApp_Group.ID = 0x0001; //組號(hào)osal_memcpy( SampleApp_Group.name, "Group 1", 7 ); //設(shè)定組名aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group ); //把該組登記添加到 APS 中#if defined ( LCD_SUPPORTED )HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); //如果支持 LCD,顯示提示信息#endif }

SampleApp_ProcessEvent() 用戶應(yīng)用任務(wù)的事件處理函數(shù)

uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) {afIncomingMSGPacket_t *MSGpkt;(void)task_id; // Intentionally unreferenced parameterif ( events & SYS_EVENT_MSG ) //接收系統(tǒng)消息再進(jìn)行判斷{//接收屬于本應(yīng)用任務(wù)SampleApp的消息,以SampleApp_TaskID標(biāo)記MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );while ( MSGpkt ){switch ( MSGpkt->hdr.event ){// Received when a key is pressedcase KEY_CHANGE://按鍵事件SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t*)MSGpkt)->keys );break;// Received when a messages is received (OTA) for this endpointcase AF_INCOMING_MSG_CMD: //接收數(shù)據(jù)事件,調(diào)用函數(shù) AF_DataRequest()接收數(shù)據(jù)SampleApp_MessageMSGCB( MSGpkt ); //調(diào)用回調(diào)函數(shù)對(duì)收到的數(shù)據(jù)進(jìn)行處理break;// Received whenever the device changes state in the networkcase ZDO_STATE_CHANGE: //只要網(wǎng)絡(luò)狀態(tài)發(fā)生改變,就通過(guò)ZDO_STATE_CHANGE事件通知所有的任務(wù)。同時(shí)完成對(duì)協(xié)調(diào)器,路由器,終端的設(shè)置SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);//if ( (SampleApp_NwkState == DEV_ZB_COORD) //實(shí)驗(yàn)中協(xié)調(diào)器只接收數(shù)據(jù)所以取消發(fā)送事件if ( (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState ==DEV_END_DEVICE) ){//這個(gè)定時(shí)器只是為發(fā)送周期信息開啟的,設(shè)備啟動(dòng)初始化后從這里開始觸發(fā)第一個(gè)周期信息的發(fā)送,然后周而復(fù)始下去。osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );}else{// Device is no longer in the network}break;default:break;}// Release the memory //事件處理完了,釋放消息占用的內(nèi)存osal_msg_deallocate( (uint8 *)MSGpkt );//指針指向下一個(gè)放在緩沖區(qū)的待處理的事件,返回 while ( MSGpkt )重新處理事件,直到緩沖區(qū)沒有等待處理事件為止MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );}// return unprocessed events //返回未處理的事件return (events ^ SYS_EVENT_MSG);}// Send a message out - This event is generated by a timer// (setup in SampleApp_Init()).if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ){/*處理周期性事件,利用 SampleApp_SendPeriodicMessage()處理完當(dāng)前的周期性事件,然后啟動(dòng)定時(shí)器開啟下一個(gè)周期性事情,這樣一種循環(huán)下去,也即是上面說(shuō)的周期性事件了,可以做為傳感器定時(shí)采集、上傳任務(wù)*/SampleApp_SendPeriodicMessage();// Setup to send message again in normal period (+ a little jitter)osal_start_timerEx(SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,(SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );// return unprocessed events 返回未處理的事件return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);}// Discard unknown eventsreturn 0; }

分析接收數(shù)據(jù)函數(shù) SampleApp_MessageMSGCB

//接收數(shù)據(jù),參數(shù)為接收到的數(shù)據(jù) void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) {uint16 flashTime;byte buf[3];switch ( pkt->clusterId ) //判斷簇 ID{case SAMPLEAPP_PERIODIC_CLUSTERID: //收到廣播數(shù)據(jù)osal_memset(buf, 0 , 3);osal_memcpy(buf, pkt->cmd.Data, 2); //復(fù)制數(shù)據(jù)到緩沖區(qū)中if(buf[0]=='D' && buf[1]=='1') //判斷收到的數(shù)據(jù)是否為“ D1”{HalLedBlink(HAL_LED_1, 0, 50, 500); //如果是則 Led1 間隔 500ms 閃爍#if defined(ZDO_COORDINATOR) //協(xié)調(diào)器收到"D1"后,返回"D1"給終端,讓終端 Led1 也閃爍SampleApp_SendPeriodicMessage();#endif}else{HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);}break;case SAMPLEAPP_FLASH_CLUSTERID: //收到組播數(shù)據(jù)flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );break;} }

分析發(fā)送周期信息 SampleApp_SendPeriodicMessage()

void SampleApp_SendPeriodicMessage( void ) {byte SendData[3]="D1";// 調(diào)用 AF_DataRequest 將數(shù)據(jù)無(wú)線廣播出去if( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,SAMPLEAPP_PERIODIC_CLUSTERID,2,SendData,&SampleApp_TransID,AF_DISCV_ROUTE,AF_DEFAULT_RADIUS ) == afStatus_SUCCESS ){}else{HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);// Error occurred in request to send.} }

AF_DataRequest 發(fā)送函數(shù)

AF_DataRequest( &SampleApp_Periodic_DstAddr, //發(fā)送目的地址+端點(diǎn)地址和傳送模式 &SampleApp_epDesc, //源(答復(fù)或確認(rèn))終端的描述(比如操作系統(tǒng)中任務(wù) ID 等)源 EP SAMPLEAPP_PERIODIC_CLUSTERID, //被 Profile 指定的有效的集群號(hào) 2, // 發(fā)送數(shù)據(jù)長(zhǎng)度 SendData,// 發(fā)送數(shù)據(jù)緩沖區(qū) &SampleApp_TransID, // 任務(wù) ID 號(hào) AF_DISCV_ROUTE, // 有效位掩碼的發(fā)送選項(xiàng) AF_DEFAULT_RADIUS ) //傳送跳數(shù),通常設(shè)置為 AF_DEFAULT_RADIUS

內(nèi)容很多但非常重要,最好盡力理解后再去做,會(huì)容易很多。

end.

總結(jié)

以上是生活随笔為你收集整理的[zigbee][z-Stack]协议栈简介及工作流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。