《無線傳感網(wǎng)技術(shù)》實(shí)訓(xùn)內(nèi)容課件 實(shí)訓(xùn)項(xiàng)目五:zigbee協(xié)議_第1頁
《無線傳感網(wǎng)技術(shù)》實(shí)訓(xùn)內(nèi)容課件 實(shí)訓(xùn)項(xiàng)目五:zigbee協(xié)議_第2頁
《無線傳感網(wǎng)技術(shù)》實(shí)訓(xùn)內(nèi)容課件 實(shí)訓(xùn)項(xiàng)目五:zigbee協(xié)議_第3頁
《無線傳感網(wǎng)技術(shù)》實(shí)訓(xùn)內(nèi)容課件 實(shí)訓(xùn)項(xiàng)目五:zigbee協(xié)議_第4頁
《無線傳感網(wǎng)技術(shù)》實(shí)訓(xùn)內(nèi)容課件 實(shí)訓(xùn)項(xiàng)目五:zigbee協(xié)議_第5頁
已閱讀5頁,還剩98頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

ZigBee無線網(wǎng)絡(luò)涉及電子、電路、通信、射頻等多學(xué)科的知識,這對于入門級學(xué)習(xí)來說,無形中增加了學(xué)習(xí)難度,很多初學(xué)者看zigBee協(xié)議、射頻電路......,學(xué)了半年甚至更長的時(shí)間,但是連基本點(diǎn)對點(diǎn)通信都無法實(shí)現(xiàn),別說根據(jù)對ZigBee協(xié)議的理解來實(shí)現(xiàn)正常的無線網(wǎng)絡(luò)部署工作了。本任務(wù)不是將重點(diǎn)放在復(fù)雜的ZigBee協(xié)議、射頻、天線等知識,而是直接進(jìn)行射頻、天線等知識,而是直接進(jìn)行射頻、天線等知識,而是直接進(jìn)行ZigBee無線網(wǎng)絡(luò)點(diǎn)對通信的學(xué)習(xí),基本思路是:從發(fā)送端一個(gè)數(shù)據(jù),接收到后校驗(yàn)的是否正確,并給出相應(yīng)的指示。很簡單的功能,但是這里涉及以下問題:數(shù)據(jù)在協(xié)議棧里面是如何流動(dòng)的;如何調(diào)用Z-Stack協(xié)議棧提供的發(fā)送函數(shù):如何使用Z-Stack協(xié)議棧進(jìn)行數(shù)據(jù)的接收;如何理解Z-Stack協(xié)議棧;Z-Stack協(xié)議棧是采用分層的思想,各都具有哪些功能;如何利用Z-Stack協(xié)議棧提供的函數(shù)來實(shí)現(xiàn)基本無線傳感器網(wǎng)絡(luò)應(yīng)用程序開發(fā):系統(tǒng)硬件對ZigBee協(xié)議都提供了哪些支持。既然Z-Stack協(xié)議棧已經(jīng)實(shí)現(xiàn)了ZigBee協(xié)議,那么用戶就可以使用協(xié)議棧提供的API進(jìn)行應(yīng)用程序的開發(fā),在開發(fā)過程中完全不必關(guān)心ZigBee協(xié)議的具體實(shí)現(xiàn)細(xì)節(jié),只需要關(guān)心一個(gè)核心的問題:應(yīng)用程序數(shù)據(jù)從哪里來到哪里去。下面舉個(gè)例子,當(dāng)用戶應(yīng)用程序需要進(jìn)行數(shù)據(jù)通信時(shí),需要按照如下步驟實(shí)現(xiàn):①調(diào)用協(xié)議棧提供的組網(wǎng)函數(shù)、加入網(wǎng)絡(luò)函數(shù),實(shí)現(xiàn)網(wǎng)絡(luò)的建立與節(jié)點(diǎn)的加入;②發(fā)送設(shè)備調(diào)用協(xié)議棧提供的無線數(shù)據(jù)發(fā)送函數(shù),實(shí)現(xiàn)數(shù)據(jù)的發(fā)送;③接收端調(diào)用協(xié)議棧提供的無線數(shù)據(jù)接收函數(shù),實(shí)現(xiàn)數(shù)據(jù)的正確接收。因此,使用協(xié)議棧進(jìn)行應(yīng)用程序開發(fā)時(shí),開發(fā)者不需要關(guān)心協(xié)議棧是具體怎么實(shí)現(xiàn)的(例如:每個(gè)函數(shù)是怎么實(shí)現(xiàn)的,每條函數(shù)代碼是什么意思等),只需要知道協(xié)議棧提供的函數(shù)實(shí)現(xiàn)什么樣的功能,會調(diào)用相應(yīng)的函數(shù)來實(shí)現(xiàn)自己的應(yīng)用需求即可。技巧提示:在TI推出的ZigBee2007協(xié)議棧(又稱作Z-Stack)中,提供的數(shù)據(jù)發(fā)送函數(shù)如下:用戶調(diào)用該函數(shù)即可實(shí)現(xiàn)數(shù)據(jù)的無線發(fā)送,當(dāng)然,在此函數(shù)中有8個(gè)參數(shù),用戶需要將每個(gè)參數(shù)的含義理解以后,才能達(dá)到熟練應(yīng)用該函數(shù)進(jìn)行無線數(shù)據(jù)通信的目的。AF_DataRequest0函數(shù)中最核心的兩個(gè)參數(shù):·uint16len-發(fā)送數(shù)據(jù)的長度;·uint8*buf-指向存放發(fā)送數(shù)據(jù)的緩沖區(qū)的指針。至于調(diào)用該函數(shù)后至于調(diào)用該函數(shù)后至于調(diào)用該函數(shù)后如何初始化硬件進(jìn)行數(shù)據(jù)發(fā)送等工作,用戶不需要關(guān)心,Z-Stack協(xié)議棧已經(jīng)將所需要的初始化工作了,這就類似于學(xué)習(xí)TCP/IP網(wǎng)絡(luò)編程時(shí),用絡(luò)編程時(shí),用戶只需要調(diào)用相應(yīng)的數(shù)據(jù)發(fā)送、接收函數(shù)即可,而不必關(guān)心具體的網(wǎng)卡驅(qū)動(dòng)(如DM9000、CS8900網(wǎng)卡是如何接收數(shù)據(jù)的)具體實(shí)現(xiàn)細(xì)節(jié)??梢灾苯訌腡I官網(wǎng)下載協(xié)議棧安裝文件或者直接拷貝最新的協(xié)議棧文件到C盤即可。協(xié)議棧文件如下圖所示:操作方法如下:在我們的資料中找到TexasInstrumentsTexasInstruments這個(gè)文件夾,然后拷貝C盤的根目錄。目錄詳情/ComponentsZ-StackStackStack協(xié)議棧所有的核心源碼和硬件驅(qū)動(dòng)在目錄,進(jìn)入該如下圖協(xié)/Components/halCC2530硬件驅(qū)動(dòng)層,包含LCD驅(qū)動(dòng)程序,KEY驅(qū)動(dòng)程序,LED驅(qū)動(dòng)程序,UART驅(qū)動(dòng)程序等。/Components/macCC2530Zigbee通信底層,由部分源碼和庫組成,TI在CC2530硬件基礎(chǔ)上封裝的通信層/Components/mtTI提供的debugger層,該層提供了一系列的調(diào)試接口,可以通過PC直接訪問Z-stack協(xié)議。/Components/osal操作系統(tǒng)抽象層,整個(gè)Z-Stack運(yùn)行在OSAL基礎(chǔ)上,OSAL相當(dāng)于一個(gè)操作系統(tǒng),管理每個(gè)任務(wù),關(guān)于OSAL的詳情見《OSAL編程指南》。/Components/stackZ-Stack協(xié)議棧源碼各層所在目錄,包括af層,nwk層,zcl層,zdo層等等。想要深入Z-Stack協(xié)議,對該目錄下的源碼的全面分析非常必要/Components/zmac在mac層之上又封裝了一層,叫做zmac,為上層的Z-Stack提供接口。/DocumentsZ-Stack相關(guān)的文檔目錄,包括Z-Stack協(xié)議棧的描述,OSAL層API函數(shù)介紹,SampleApp介紹等文檔。非常重要,在進(jìn)行zigbee開發(fā)前強(qiáng)烈建議仔細(xì)閱讀該目錄下的文檔。/ProjectsZ-Stack是zigbee協(xié)議的實(shí)現(xiàn)協(xié)議的實(shí)現(xiàn),但如何將此協(xié)議應(yīng)用具體的中,就需要一些列的實(shí)例,也是我們后的所有實(shí)例和示程序,也是我們后面開發(fā)z-stackstackstackstackstack應(yīng)用程序的重要目錄。/Projects/zstack/HomeAutomation家庭自動(dòng)化應(yīng)用示例程序,包含無線開關(guān)、無線燈控等程序/Projects\zstack\LibrariesZstack封裝好的庫函數(shù),這部分TI不提供源代碼,只是以庫的形式提供。/Projects/zstack/SamplesZ-Stack簡單的應(yīng)用程序示例,包括組通信,綁定通信等示例程序/Projects/zstack/SE智能能源示例程序,例如無線電表等。/Projects/zstack/Toolsz-stack示例程序中所用到的配置文件等。/Projects/zstack/UtilitiesZ-Stack實(shí)用程序,像串口透傳/Projects/zstack/ZMainMain函數(shù)和板級配置源文件目錄/Projects/zstack/ZNPZNP其實(shí)也是非常有用的程序,他把zigbee協(xié)議完全封裝在cc2530中,通過ZNP程序,可以通過uart,spi或其他接口,上層的mcu來控制cc2530。在圖中所示的文件布局中,左側(cè)有很多文件夾,如App、HAL、MAC等,這些文件夾對應(yīng)了Z-Stack協(xié)議棧中不同的層,使用Z-Stack協(xié)議棧進(jìn)行應(yīng)用程序的開發(fā),一般只需要修改App目錄下的文件即可。在ZigBee無線傳感器網(wǎng)絡(luò)中有三種設(shè)備類型:協(xié)調(diào)器、路由器和終端節(jié)點(diǎn),設(shè)備類型是由ZiglBee協(xié)議棧不同的編譯選項(xiàng)來選擇的。在IAR左邊的Workspace的下拉列表中選擇CoordinatorEB協(xié)調(diào)器程序?;蛘逺outerEB路由器程序、EndDeviceEB節(jié)點(diǎn)程序等配置。協(xié)調(diào)器主要負(fù)責(zé)網(wǎng)絡(luò)組建、維護(hù)、控制終端節(jié)點(diǎn)的加入等。路由器主要負(fù)責(zé)數(shù)據(jù)包的路由選擇,終端節(jié)點(diǎn)負(fù)責(zé)數(shù)據(jù)的采集,不具備路由功能。在本任務(wù)中,ZigBee節(jié)點(diǎn)1配置為一個(gè)協(xié)調(diào)器,負(fù)責(zé)ZigBee網(wǎng)絡(luò)的組建,ZigBee節(jié)點(diǎn)2配置為一個(gè)終端節(jié)點(diǎn)。上電后,節(jié)點(diǎn)1和節(jié)點(diǎn)2均可以通過Joystick的右方向鍵加入和退出該網(wǎng)絡(luò),通過Joystick的up方向鍵通過zigbee網(wǎng)絡(luò)發(fā)送一條閃爍led的命令到其他節(jié)點(diǎn),其他節(jié)點(diǎn)如果處在這個(gè)網(wǎng)絡(luò)中,會控制led閃爍。我們打開協(xié)議棧工程文件,選擇CoordinatorEB,然后打開SampleApp.c,在函數(shù)SampleApp_Init里有這樣的初始化代碼。220行:afRegister函數(shù),用來將上面的節(jié)點(diǎn)描述符進(jìn)行注冊,只有注冊以后,才可以使用OSAL提供的系統(tǒng)服務(wù)。上述代碼是消息處理函數(shù),該函數(shù)大部分代碼是固定的,讀者不需要修改,只需要熟悉這種格式即可,唯一需要讀者修改的是上面的反顯的函數(shù),可以修改函數(shù)的實(shí)現(xiàn)形式,但是其功能基本上都是完成對接收數(shù)據(jù)的處理。253行:SYS_EVENT_MSG,是否是系統(tǒng)消息判斷。Rf通信層上傳來的數(shù)據(jù)以及hal層的按鍵等時(shí)間,均會觸發(fā)該系統(tǒng)事件。255行:申請內(nèi)存,創(chuàng)建MSG結(jié)構(gòu)體指針,準(zhǔn)備接收系統(tǒng)消息。261行:KEY_CHANGE,按鍵按下,觸發(fā)的消息事件。262行:按鍵對應(yīng)的消息處理函數(shù),其實(shí)就是處理一下是哪個(gè)按鍵按下,然后執(zhí)行何種動(dòng)作。266行:AF_INCOMING_MSG_CMD,網(wǎng)絡(luò)上有發(fā)來數(shù)據(jù),準(zhǔn)備接收。267行:網(wǎng)絡(luò)數(shù)據(jù)處理函數(shù)。271行:ZDO_STATE_CHANGE,ZDO狀態(tài)發(fā)生變化,當(dāng)系統(tǒng)初始化后,程序會根據(jù)節(jié)點(diǎn)的配置情況,進(jìn)入?yún)f(xié)調(diào)器模式、路由器模式或者終端節(jié)點(diǎn)模式中的一個(gè)。278行:osal_start_timerEx,osal提供的定時(shí)器函數(shù),后面?zhèn)魅氲臅r(shí)間,將在設(shè)定的某個(gè)時(shí)間以后開始執(zhí)行。293行:當(dāng)處理完MSG消息后,需要對剛才申請的內(nèi)存進(jìn)行銷毀。否則會造成內(nèi)容泄露,最后內(nèi)存消耗完后死機(jī)。305行:SAMPLEAPP_SEND_PERIODIC_MSG_EVT,用戶自定義的消息事件,在z-stack程序里經(jīng)常需要用戶自定義各種事件,完成用戶的控制邏輯,比如我們需要在10ms以后點(diǎn)亮一個(gè)led,平時(shí)的做法,通常是延時(shí),或者開啟一個(gè)單片機(jī)的timer,當(dāng)10ms到后執(zhí)行點(diǎn)亮led的操作,但是早osal里,這個(gè)過程就變得非常簡單。我們只需要調(diào)用osal_start_timerEx函數(shù),傳入需要執(zhí)行的事件標(biāo)識,然后串口10ms時(shí)間參數(shù),然后我們就可以去做別的事情,當(dāng)時(shí)間到后,我們的任務(wù)函數(shù)會被自動(dòng)調(diào)用,也就是在if(events*SAMPLEAPP_SEND_PERIODIC_MSG_EVT)里開始操作就可以了,如果10ms之后還需要這個(gè)操作,則將osal_start_timerex在放到這個(gè)函數(shù)里執(zhí)行一次就可以了。391行,判斷clusterID,這個(gè)ID是在初始化的時(shí)候傳入Z-Stack中,代碼如下:396行:SAMPLEAPP_FLASH_CLUSTERID,閃爍事件的cluster。397行:保存網(wǎng)絡(luò)中發(fā)過來的閃爍事件的數(shù)據(jù)。也就是閃爍的時(shí)間,這個(gè)時(shí)間是在網(wǎng)絡(luò)里的其他節(jié)點(diǎn)通過zigbee網(wǎng)絡(luò)發(fā)送過來。將網(wǎng)絡(luò)中發(fā)送過來的數(shù)據(jù)保存到flashtime這個(gè)變量中。398行:調(diào)用led接口函數(shù),閃爍led。注意,這里的HAL_LED_4,在程序底層被映射到了HAL_LED_1,所以實(shí)驗(yàn)室閃爍的是D1綠色LED。在代碼的261行,是處理按鍵消息。按鍵的消息處理函數(shù)如下。341行:判斷是否是按鍵1,對應(yīng)的joystickup。如果是按鍵1按下,則執(zhí)行按鍵1動(dòng)作。347行:SampleApp_SendFlashMessage(SAMPLEAPP_FLASH_DERATION)向網(wǎng)絡(luò)中發(fā)送閃爍led的命令。445行:AF_DateRequest函數(shù)。這部分的代碼是本實(shí)驗(yàn)的關(guān)鍵部分,實(shí)現(xiàn)了數(shù)據(jù)發(fā)送。第一個(gè)參數(shù)是目標(biāo)地址,第二個(gè)參數(shù)是端點(diǎn)描述符,第三個(gè)參數(shù)是剛才看到的SAMPLEAPP_FLASH_CLUSTERID,第四個(gè)參數(shù)是需要發(fā)送的數(shù)據(jù)長度。第五個(gè)參數(shù)是需要發(fā)送的數(shù)據(jù)。后面的參數(shù)暫時(shí)略過。這里發(fā)送了三個(gè)字節(jié)長的數(shù)據(jù)。攜帶的是讓對方閃爍的時(shí)間參數(shù)。操作說明將CoordinatorEB程序下載到開發(fā)板中,將RouterEB或者EndDeviceEB下載到另外一個(gè)開發(fā)板中。記得設(shè)置option,燒寫的時(shí)候擦除flash。這里提醒一下,開發(fā)板可以使用仿真器供電或者USB供電,也可以外接電池進(jìn)行供電。程序燒寫好之后,打開協(xié)調(diào)器電源開關(guān)。幾秒后,會發(fā)現(xiàn)協(xié)調(diào)器的LED3閃爍幾次后常亮,這表明協(xié)調(diào)器已經(jīng)初始化了一個(gè)zigbee網(wǎng)絡(luò),其他節(jié)點(diǎn)可以加入。然后給終端節(jié)點(diǎn)上電。節(jié)點(diǎn)上電后后會持續(xù)搜索是否有網(wǎng)絡(luò)存在,如果存在,則點(diǎn)亮自己的LED3,然后加入該網(wǎng)絡(luò)。如果沒有,則持續(xù)搜索。因此協(xié)調(diào)器和終端節(jié)點(diǎn)沒有上電先后順序電先后順序。此時(shí),我們按下開發(fā)板(燒寫了協(xié)調(diào)器程序)的joystickup按鍵。會發(fā)現(xiàn)另外一個(gè)開發(fā)板(燒寫了終端節(jié)點(diǎn)程序)的LED1閃爍了四次。每次按下,都會觸發(fā)該事件,表明協(xié)調(diào)器像終端節(jié)點(diǎn)的數(shù)據(jù)發(fā)送已成功。然后,我們按下開發(fā)板(燒寫了終端節(jié)點(diǎn)程序)的Joystickup按鍵,會發(fā)現(xiàn)協(xié)調(diào)器開發(fā)板的LED1閃爍了4次。同樣也表明,終端節(jié)點(diǎn)像協(xié)調(diào)器的數(shù)據(jù)發(fā)送也已成功。這是值得慶祝的現(xiàn)象,因?yàn)槲覀兺ㄟ^zigbee協(xié)議完成了數(shù)據(jù)的收發(fā)。注:如果大家的終端開發(fā)板燒寫了EndDeviceEB這個(gè)程序后,發(fā)現(xiàn)無法接收數(shù)據(jù)時(shí)請注意,程序里對EndDeviceEB做了節(jié)電處理。數(shù)據(jù)傳輸原理分析協(xié)調(diào)器上電后,會按照編譯時(shí)給定的參數(shù),選擇合適的信道、合適的網(wǎng)絡(luò)號,建立zigbee網(wǎng)絡(luò),這部分內(nèi)容,讀者不需要寫代碼實(shí)驗(yàn),z-stack協(xié)議棧已經(jīng)實(shí)現(xiàn)了。終端節(jié)點(diǎn)上電后,會進(jìn)行硬件電路的初始化,然后搜索是否有zigbee無線網(wǎng)絡(luò),如果有zigbee無線網(wǎng)絡(luò)再自動(dòng)加入。(這是最簡單地情況,當(dāng)然可以控制節(jié)點(diǎn)加入網(wǎng)絡(luò)時(shí)需要符合編譯時(shí)確定的網(wǎng)絡(luò)號等),最后發(fā)送數(shù)據(jù)到協(xié)調(diào)器,最后使led閃爍。數(shù)據(jù)發(fā)送在Z-Stack協(xié)議棧中進(jìn)行數(shù)據(jù)發(fā)送可以調(diào)用AF_DataRequet.t函數(shù)實(shí)現(xiàn),該函教會調(diào)用協(xié)議棧里面與硬件相關(guān)的函數(shù)最終將數(shù)據(jù)通過天線發(fā)送出去,這里面涉及對射頻模塊的操作,例如:打開發(fā)射機(jī),調(diào)整發(fā)射機(jī)的發(fā)送功率等內(nèi)容,這些部分協(xié)議棧已經(jīng)實(shí)現(xiàn)了,用戶不需要自己寫代碼去實(shí)現(xiàn),只需要掌握AF_DataRequest函數(shù)的使用方法即可。下面簡要講解AF_DataRequest數(shù)據(jù)發(fā)送函數(shù)中各個(gè)參數(shù)的具體含義。①afAddrType_t*dstAddr,該參數(shù)包含了目的節(jié)點(diǎn)的網(wǎng)絡(luò)地址以及發(fā)送數(shù)據(jù)的格式,如廣播、單?;蚨嗖ァ?/p>

②endPointDesc_t*srcEP,在zigbee無線網(wǎng)絡(luò)中,通過網(wǎng)絡(luò)地址可以找到某個(gè)具體的節(jié)點(diǎn),如協(xié)調(diào)器的網(wǎng)絡(luò)地址是0x0000,但是鋸條某個(gè)節(jié)點(diǎn)上,還有不同的端口(endpoint),每個(gè)節(jié)點(diǎn)上最多支持240個(gè)端口。節(jié)點(diǎn)與端口的關(guān)系如圖4-21所示,每個(gè)節(jié)點(diǎn)上最多有240個(gè)端口,端口0是默認(rèn)的zdo(zigbeedeviceobject),端口1~240用戶可以自定義,不同節(jié)點(diǎn)上的端口之間可以進(jìn)行通信。如節(jié)點(diǎn)1的端口1可以給節(jié)點(diǎn)2的端口1發(fā)送控制命令來閃爍led,節(jié)點(diǎn)1的端口1也可以給節(jié)點(diǎn)2的端口2發(fā)送命令進(jìn)行數(shù)據(jù)采集操作。但是節(jié)點(diǎn)2上的端口1和端口2的網(wǎng)絡(luò)地址是相同的。所以僅僅通過網(wǎng)絡(luò)地址無法區(qū)分,所有在發(fā)送數(shù)據(jù)時(shí)不但要指定網(wǎng)絡(luò)地址,還有指定端口號。我們可以把端口理解為tcp/ip中的port。因此,通過上面的論述,可以得到如下的結(jié)論?!な褂镁W(wǎng)絡(luò)地址區(qū)分不同的節(jié)點(diǎn);·使用端口號來分區(qū)同一個(gè)節(jié)點(diǎn)上的不同需求。③uint16cID,這個(gè)參數(shù)描述的是命令號,在zigbee協(xié)議里的命令主要用來標(biāo)識不同的控制操作,不同的命令號代表了不同的的控制命令,如上面提到的FLASH的clusterid。④uint16len,發(fā)送數(shù)據(jù)的長度⑤uint8*buf,該參數(shù)紙箱發(fā)送數(shù)據(jù)緩沖區(qū)的指針,發(fā)送數(shù)據(jù)時(shí),之需要將所需要的發(fā)送的數(shù)據(jù)緩沖區(qū)的地址傳遞給該參數(shù)即可。⑥uint8*transID,該參數(shù)是一個(gè)紙箱發(fā)送序號的指針,每次發(fā)送數(shù)據(jù)時(shí),發(fā)送序號會自動(dòng)加1,(協(xié)議棧里面實(shí)現(xiàn)該功能。),在接收端可以通過發(fā)送序列號來判斷是否丟包,同時(shí)可以計(jì)算出丟包率。⑥uint8options,和uint8radius,這兩個(gè)參數(shù)取默認(rèn)值即可,options參數(shù)可以去AF_DISCV_ROUTE,radius參數(shù)可以取AF_DEFAULT_RADIUS。數(shù)據(jù)接收當(dāng)一個(gè)節(jié)點(diǎn)給其他節(jié)點(diǎn)發(fā)送數(shù)據(jù)后,其他節(jié)點(diǎn)會收到該收據(jù),但是協(xié)議棧里面是如何得到通過天線接受到的數(shù)據(jù)的呢?前文提到,在Z-Stack協(xié)議棧里添加一個(gè)小型的操作系統(tǒng),正式因?yàn)檫@個(gè)操作系統(tǒng),才使得對協(xié)議棧的開發(fā)變得容易,但是對于非計(jì)算機(jī)專業(yè)的初學(xué)者來說,如果操作系統(tǒng)的只是比較薄弱,則需要更多的實(shí)驗(yàn)才能很好的理解協(xié)議棧中的數(shù)據(jù)流向以及各種機(jī)制。當(dāng)協(xié)調(diào)器收到數(shù)據(jù)后,操作底層的協(xié)議棧會將該數(shù)據(jù)封裝成一個(gè)消息,然后通過這個(gè)操作系統(tǒng)osal的接口發(fā)送這個(gè)消息,也就是放到osal的消息隊(duì)列中。每個(gè)消息都有自己的消息ID,表示接收到新數(shù)據(jù)的消息的ID是AF_INCOMING_MSG_CMD,其中AF_INCOMING_MSG_CMD宏定義的值是0x1A,這個(gè)是協(xié)議棧代碼里定義好的,用戶不可修改(在Zcomdef.h中定義)。因此,任務(wù)函數(shù)中的代碼中有如下的代碼段首先使用osal_msg_receive函數(shù)從消息隊(duì)列中接觸一個(gè)消息,然后使用switch-case語句對消息類型進(jìn)行判斷(就是判斷消息ID),如果消息ID是AF_INCOMING_MSG_CMD則進(jìn)行相應(yīng)的數(shù)據(jù)接收工作。到此為止,讀者至少理清楚這條線索:當(dāng)一個(gè)節(jié)點(diǎn)通過z-stack提供的數(shù)據(jù)發(fā)送接口發(fā)送數(shù)據(jù)后,其他節(jié)點(diǎn)的協(xié)議棧收到數(shù)據(jù)后,只要從消息隊(duì)列中接收消息,取得自己需要的數(shù)據(jù)即可,其他工作,都由Z-Stack協(xié)議棧自動(dòng)完成了。建立自己的協(xié)議棧工程在ZigBee無線傳感器網(wǎng)絡(luò)中有三種設(shè)備類型:協(xié)調(diào)器、路由器和終端節(jié)點(diǎn),設(shè)備類型是由ZiglBee協(xié)議棧不同的編譯選項(xiàng)來選擇的。在本實(shí)驗(yàn)中,ZigBee節(jié)點(diǎn)1配置為協(xié)調(diào)器,負(fù)責(zé)建網(wǎng),ZigBee節(jié)點(diǎn)2配置為終端,上電后加入ZigBee節(jié)點(diǎn)1建立的網(wǎng)絡(luò),然后發(fā)送“LED”三個(gè)字符給節(jié)點(diǎn)1.打開\ZStack-CC2530-2.5.1a\Projects\zstack\Samples目錄,這里是我們建立工程的地方,在這個(gè)目錄下有3個(gè)文件,如下圖所示:首先復(fù)制GenericApp到本目錄下,如圖所示:將文件名改為TestA打開TestA\Source,如圖所示修改這三個(gè)文件的名稱,如圖所示:打開路徑TestA\CC2530DB,將里面的文件改為:用記事本打開這3個(gè)文件,替換其中的GenericApp為TestA,然后保存。打開目錄TestA\Source,替換該文件里的3個(gè)文件中的GenericApp為TestA,在IAR中打開工程,如下如所示:到這里,全新的工程就已經(jīng)建立好了。將TestA工程的TestA.h和TestA.c刪除,方法是點(diǎn)擊TestA.h,然后點(diǎn)擊右鍵,選擇Remove即可,刪除后如下圖所示單擊File,在彈出的下拉菜單中選擇New,然后選擇File,如圖所示,將該文件保存為Coordinator.h,然后用相同的方法建立Coordinator.c和Enddevice.c文件,保存哦路徑為Sample\TestA\Source。下面添加剛建立的文件到工程中來,方法是:右鍵點(diǎn)擊APP,然后點(diǎn)ADD,然后選擇AddFiles,選擇剛剛新建的3個(gè)文件,打開即可。協(xié)調(diào)器的編程下面開始編寫代碼。首先是OSAL_TestA.c文件編程。程序文件請參考OSAL_TestA.c。該文件是操作系統(tǒng)初始化需要的部分,在osalInitTasks()函數(shù)里。從上面看出,工程編譯首先必須定義osalInitTasks()函數(shù)。tasksArr()任務(wù)存放的位置,在操作系統(tǒng)中輪流用到,所以也必須初始化,這樣編譯就可以通過了,協(xié)議棧這樣就可以完成網(wǎng)絡(luò)的建立,但是我們還需要添加自己的任務(wù)。自己的任務(wù)添加到tasksArr()里面,但輪詢到該任務(wù)時(shí),必須分配一個(gè)任務(wù)ID,在osalInitTasks()添加。編譯完成上面的文件后,點(diǎn)擊保存,查看是否報(bào)錯(cuò)。最后然后我們開始編寫Coordinator.c,程序文件請參考資料的Coordinator.c文件。此外我們還要在Common.h中定義應(yīng)用層的一些初始化參數(shù)。Common.h程序文件如下:到此協(xié)調(diào)器的編程基本結(jié)束。,下面我你們回憶一下上述代碼所作的基本工作:1)刪除了協(xié)議棧中的GenericApp.h和GenericApp.c文件,然后添加了3個(gè)文件:Coordinator.cCoordinator.h,Enddevice.c。2)給出了Common.h的代碼和Coordinator.c代碼,其中Common.h定義了初始化的一些參數(shù),Coordinator.c文件中很多代碼的格式都是固定的,直接從協(xié)議棧復(fù)制過來,函數(shù)的具體作用可以參考《ZigBee2007協(xié)議棧API函數(shù)使用說明.pdf》,讀者大部分只需要看懂即可。下面需要改動(dòng)一下OSAL_GenericApp.c文件,因?yàn)槲覀冃枰砑幼约旱娜蝿?wù),所以在OSAL_TestA.c文件中添加任務(wù),需要在OSAL_TestA.c做以下修改。在constpTaskEventHandlerFntasksArr[]數(shù)組的最后面添加GenericApp_ProcessEvent,如下圖所示:以及在osalInitTasks(void)最后添加GenericApp_Init(taskID);如下圖所示:在Workspace西面的下拉列表框中選擇CoordinatorEB,然后右鍵單擊Enddevice.c文件,在彈出的下拉菜單中選擇Options,如下圖所示:在彈出的對話框中,選擇Excludefrombuild,此時(shí),Enddevice.c文件呈灰色顯示狀態(tài),此時(shí),可以打開Tools文件夾,可以看到f8wEndec.cfg和f8wRouter.cfg文件也是呈灰色狀態(tài),如下圖所示。文件呈灰色狀態(tài)說明該文件不參與編譯,ZigBee協(xié)議棧真是使用這種方式實(shí)現(xiàn)對源文件的控制。F8w2530.xcl、f8wConfig.cfg、f8wCoord.cfg三個(gè)文件包含可節(jié)點(diǎn)的配置信息,因此,如果想修改RF參數(shù),如信道等,設(shè)備類型(協(xié)調(diào)器、終端、路由器),網(wǎng)絡(luò)號等應(yīng)該在這3個(gè)文件里修改。程序編寫完成,文件也配置好了,就可以編譯和下載程序了,編譯結(jié)果如下:最后通過仿真器把程序下載到CC2530開發(fā)板中。終端的編程終端的編程和協(xié)調(diào)器編程類似。首先在Workspace西面的下拉列表框中選擇EnddviceEB,然后右鍵單擊Coordintor.c文件,在彈出的下拉菜單中選擇Options,如下圖所示:和剛才一樣,通過option控制一些文件不參與編譯。然后我們開始編寫Enddevice.c的程序。程序源文件請參考資料的源碼。數(shù)據(jù)發(fā)送代碼和上一節(jié)講到的第一個(gè)Z-stack協(xié)議棧實(shí)驗(yàn)原理一樣,這里就不重復(fù)了。編譯完之后通過仿真器把程序下載到終端模塊中。HAL層分析CC2530硬件驅(qū)動(dòng)層,包含所有硬件設(shè)備(例如LCD、KEY、LED、UART等)的驅(qū)動(dòng)函數(shù)及接口。HAL文件夾為硬件平臺的抽象層,包含common、include和target三個(gè)文件夾。common文件夾common文件夾下包含有hal_assert.c、hal_drivers.c兩個(gè)文件。其中hal_assert是聲明文件,用于調(diào)試,hal_drivers是驅(qū)動(dòng)文件。hal_assert.c在hal_assert.c文件中包含兩個(gè)重要的函數(shù):halAssertHandler()、halAssertHazardLights()。halAssertHandler()函數(shù)為硬件系統(tǒng)檢測函數(shù)。如果定義了ASSERT_RESET宏,系統(tǒng)將調(diào)用HAL_SYSTEM_RESET()復(fù)位,否則將調(diào)用halAssertHazardLights()執(zhí)行閃爍LED命令。voidhalAssertHandler(void){/*executecodethathandlesasserts*/#ifdefASSERT_RESETHAL_SYSTEM_RESET();系統(tǒng)復(fù)位#elif!definedASSERT_WHILE當(dāng)檢測到錯(cuò)誤時(shí),LED燈閃爍命令函數(shù)halAssertHazardLights();#elsewhile(1);#endif}halAssertHazardLights()函數(shù)控制LED閃爍,根據(jù)不同的硬件平臺定義的LED的個(gè)數(shù)來決定閃爍的LED的不同。比如CC2530與CC2430所使用的硬件平臺不同,決定了閃爍的LED的不同。如果硬件平臺定義的LED的個(gè)數(shù)是1#if(HAL_NUM_LEDS>=1)LED1閃爍HAL_TOGGLE_LED1();#if(HAL_NUM_LEDS>=2)HAL_TOGGLE_LED2();#if(HAL_NUM_LEDS>=3)HAL_TOGGLE_LED3();#if(HAL_NUM_LEDS>=4)HAL_TOGGLE_LED4();#endif#endif#endif#endifhal_drivers.chal_drivers.c文件中包含了與硬件相關(guān)的初始化和事件處理函數(shù)。該文件中有4個(gè)比較重要的函數(shù):硬件初始化函數(shù)Hal_Init()、硬件驅(qū)動(dòng)初始化函數(shù)HalDriverInit(void)、硬件事件處理函數(shù)Hal_ProcessEvent()和詢檢函數(shù)Hal_ProcessPoll()。Hal_Init()是硬件初始化函數(shù),其功能是通過“注冊任務(wù)ID號”以實(shí)現(xiàn)在OSAL層注冊,從而允許硬件驅(qū)動(dòng)的消息和事件由OSAL處理。voidHal_Init(uint8task_id){/*RegistertaskID*/注冊任務(wù)ID號Hal_TaskID=task_id;

#ifdefCC2591_COMPRESSION_WORKAROUNDosal_start_reload_timer(Hal_TaskID,PERIOD_RSSI_RESET_EVT,PERIOD_RSSI_RESET_TIMEOUT);#endif}HalDriverInit(void)是硬件驅(qū)動(dòng)初始化函數(shù),被main函數(shù)調(diào)用,用于初始化與硬件設(shè)備有關(guān)的驅(qū)動(dòng)。voidHalDriverInit(void){/*TIMER*/初始化定時(shí)器#if(definedHAL_TIMER)&&(HAL_TIMER==TRUE)#error"Thehaltimerdrivermoduleisremoved."#endif/*ADC*/定義了ADC,初始化ADC#if(definedHAL_ADC)&&(HAL_ADC==TRUE)HalAdcInit();#endif/*DMA*/#if(definedHAL_DMA)&&(HAL_DMA==TRUE)//MustbecalledbeforetheinitcalltoanymodulethatusesDMA.HalDmaInit();#endif/*AES*/#if(definedHAL_AES)&&(HAL_AES==TRUE)HalAesInit();#endif/*LCD*/#if(definedHAL_LCD)&&(HAL_LCD==TRUE)HalLcdInit();#endif/*LED*/#if(definedHAL_LED)&&(HAL_LED==TRUE)HalLedInit();#endif/*UART*/#if(definedHAL_UART)&&(HAL_UART==TRUE)HalUARTInit();#endif/*KEY*/#if(definedHAL_KEY)&&(HAL_KEY==TRUE)HalKeyInit();#endif/*SPI*/#if(definedHAL_SPI)&&(HAL_SPI==TRUE)HalSpiInit();#endif/*HID*/定義USB,初始化USB,只限于CC3531#if(definedHAL_HID)&&(HAL_HID==TRUE)usbHidInit();#endif}Hal_ProcessEvent()函數(shù)在APP層中的任務(wù)事件處理中調(diào)用,用于相應(yīng)的硬件事件作出處理,具體包括系統(tǒng)消息事件、按鍵處理事件和睡眠模式等。uint16Hal_ProcessEvent(uint8task_id,uint16events){uint8*msgPtr;

(void)task_id;//Intentionallyunreferencedparameter系統(tǒng)消息事件if(events&SYS_EVENT_MSG){msgPtr=osal_msg_receive(Hal_TaskID);while(msgPtr){/*Dosomethinghere-fornow,justdeallocatethemsgandmoveon*//*De-allocate*/osal_msg_deallocate(msgPtr);/*Next*/msgPtr=osal_msg_receive(Hal_TaskID);}returnevents^SYS_EVENT_MSG;}

if(events&HAL_LED_BLINK_EVENT)LED閃爍事件{#if(defined(BLINK_LEDS))&&(HAL_LED==TRUE)HalLedUpdate();#endif/*BLINK_LEDS&&HAL_LED*/returnevents^HAL_LED_BLINK_EVENT;}if(events&HAL_KEY_EVENT)按鍵處理事件{#if(definedHAL_KEY)&&(HAL_KEY==TRUE)/*Checkforkeys*/HalKeyPoll();/*ifinterruptdisabled,donextpolling*/if(!Hal_KeyIntEnable){osal_start_timerEx(Hal_TaskID,HAL_KEY_EVENT,100);}#endif//HAL_KEYreturnevents^HAL_KEY_EVENT;}#ifdefPOWER_SAVING睡眠模式if(events&HAL_SLEEP_TIMER_EVENT){halRestoreSleepLevel();returnevents^HAL_SLEEP_TIMER_EVENT;}#endif#ifdefCC2591_COMPRESSION_WORKAROUNDif(events&PERIOD_RSSI_RESET_EVT){macRxResetRssi();return(events^PERIOD_RSSI_RESET_EVT);}#endif

/*Nothinginterested,discardthemessage*/return0;}Hal_ProcessPoll()函數(shù)在main中被osal_system調(diào)用,要來對可能產(chǎn)生的硬件事件進(jìn)行詢檢。voidHal_ProcessPoll(){/*TimerPoll*/定時(shí)器詢檢#if(definedHAL_TIMER)&&(HAL_TIMER==TRUE)#error"Thehaltimerdrivermoduleisremoved."#endif/*UARTPoll*/#if(definedHAL_UART)&&(HAL_UART==TRUE)HalUARTPoll();#endif/*SPIPoll*/#if(definedHAL_SPI)&&(HAL_SPI==TRUE)HalSpiPoll();#endif/*HIDpoll*/USB詢檢#if(definedHAL_HID)&&(HAL_HID==TRUE)usbHidProcessEvents();#endif

#ifdefined(POWER_SAVING)定義睡眠模式/*AllowsleepbeforethenextOSALeventloop*/ALLOW_SLEEP_MODE();允許在下一個(gè)事件到來之前進(jìn)入休眠模式#endif}include文件夾include文件夾主要包含各個(gè)硬件模塊的頭文件,主要內(nèi)容是與硬件相關(guān)的常量定義以及函數(shù)聲明。target文件夾target文件夾目錄下包含了某個(gè)設(shè)備類型下的硬件驅(qū)動(dòng)文件、硬件開發(fā)平臺上的配置文件、MCU信息和數(shù)據(jù)類型。本例采用的硬件平臺CC2530,硬件設(shè)備類型是CC2530EB(EB是版本號,表示是評估版)。小知識(BB是電池版,DB是開發(fā)版)CC2530EB文件夾下包含三個(gè)子文件夾,分別是Config、Drivers、Include。Config文件夾Config文件夾中包含了hal_borad_cfg.h,在hal_borad_cfg.h中定義了硬件資源的配置,比如GPIO、DMA、ADC等。在hal_borad_cfg.h文件中可以定義開發(fā)板的硬件資源。以LED為例,CC2530EB版本中定義了兩個(gè)LED:LED1和LED2。*1-Green*/#defineLED1_BVBV(0)#defineLED1_SBITP2_0#defineLED1_DDRP2DIR#defineLED1_POLARITYACTIVE_HIGH如果定義了HAL_BOARD_CC2530EB_REV17,則可以定義LED2和LED3#ifdefined(HAL_BOARD_CC2530EB_REV17)/*2-Red*/#defineLED2_BVBV(1)#defineLED2_SBITP1_1#defineLED2_DDRP1DIR#defineLED2_POLARITYACTIVE_HIGH/*3-Yellow*/#defineLED3_BV

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論