ZIGBEE簡(jiǎn)介,協(xié)議棧的使用
協(xié)議棧的使用
1.?為了讓ZigBee的開發(fā)更加簡(jiǎn)單高效,TI公司推出了基于CC2530芯片的協(xié)議棧-Z-Stack。協(xié)議棧實(shí)質(zhì)上就是能實(shí)現(xiàn)各個(gè)功能的示例框架代碼,我們要實(shí)現(xiàn)自己想要的功能,只需要在協(xié)議棧的基礎(chǔ)上修改或添加即可。
2.?Z-Stack的發(fā)展 由0.0.1 -2.5.1a?
Mesh:之前版本的升級(jí)?HA:智能家居?SE:智能能源
他們的區(qū)別是應(yīng)用部分不同
工程打開路徑Texas InstrumentsZStack-CC2530-2.3.0-1.4.0ProjectszstackSamplesGenericAppCC2530DBGenericApp.eww,既可以打開工程文件。
選擇不同的選項(xiàng)卡能夠生成不同的模塊程序
CoordinatorEB??協(xié)調(diào)器
RouterEB?路由器
EndDeviceEB?終端
注:有Pro的版本比沒(méi)有Pro的版本功能強(qiáng)大一點(diǎn),所以我們一般使用額是有Pro的版本。
寫在前面的話:Zigbee無(wú)線傳感網(wǎng)絡(luò)電子、電路、通信、視頻、網(wǎng)絡(luò)等多學(xué)科的知識(shí),對(duì)于剛?cè)腴T想要學(xué)習(xí)的人來(lái)說(shuō),一般難度是很大的,很多人一開始就想著看懂zigbee協(xié)議、射頻電路或者網(wǎng)絡(luò)相關(guān)的知識(shí),學(xué)了很長(zhǎng)時(shí)間連一個(gè)最簡(jiǎn)單點(diǎn)對(duì)點(diǎn)的zigbee協(xié)議網(wǎng)絡(luò)通信都搭建不起來(lái),更別說(shuō)進(jìn)行實(shí)現(xiàn)無(wú)線網(wǎng)絡(luò)的部署和開發(fā)了,我個(gè)人覺(jué)得入門學(xué)習(xí)zigbee,不應(yīng)該重點(diǎn)學(xué)習(xí)復(fù)雜的zigbee協(xié)議、射頻、天線、網(wǎng)絡(luò)等知識(shí),而是直接動(dòng)手搭建一個(gè)zigbee無(wú)線網(wǎng)絡(luò)通信系統(tǒng)(基本思路就是從發(fā)送端發(fā)送一個(gè)數(shù)據(jù),接收端接到數(shù)據(jù)后校驗(yàn)數(shù)據(jù)是否正確,并給給出相應(yīng)的指示),然后根據(jù)實(shí)際的效果來(lái)進(jìn)行相應(yīng)知識(shí)的學(xué)習(xí)。在上訴的功能中,我們只需關(guān)心以下問(wèn)題就可以實(shí)現(xiàn):1.數(shù)據(jù)在協(xié)議棧里面是如何流動(dòng)的;2.如何調(diào)用zigbee協(xié)議棧提供的發(fā)送函數(shù)和進(jìn)行數(shù)據(jù)的收發(fā);3.zigbee協(xié)議棧采用的分層思想,各層中都具有那些基本的功能;4.如何利用zigbee協(xié)議棧提供的函數(shù)來(lái)實(shí)現(xiàn)基本的無(wú)線傳感器網(wǎng)絡(luò)應(yīng)用程序開發(fā);
CC2530簡(jiǎn)歷:
? ? CC2530單片機(jī)是一款完全兼容8051內(nèi)核,同時(shí)也是支持IEEE 802.15.4協(xié)議的無(wú)線射頻單片機(jī),一般用于學(xué)習(xí)zigbee協(xié)議棧的一款不錯(cuò)的開發(fā)板,CC2530的Flash容量可以選擇,有32kb、64kb、128kb、256
kb,常用的有256kb。
協(xié)議和協(xié)議棧:
協(xié)議定義的是一系列的通信標(biāo)準(zhǔn)、通信雙方需要共同按照這一標(biāo)準(zhǔn)進(jìn)行正常的數(shù)據(jù)隨收發(fā);協(xié)議棧是協(xié)議的具體實(shí)現(xiàn)形式,通俗的理解協(xié)議棧就是用代碼實(shí)現(xiàn)的函數(shù)庫(kù),以便開發(fā)人員使用。
?
??
ZIGBEE簡(jiǎn)介
? ?ZigBee協(xié)議棧建立在IEEE802.154的PHY層和MAC子層規(guī)范之上。它實(shí)現(xiàn)了網(wǎng)絡(luò)層(networklayer,NWK)和應(yīng)用層(applicationlayer,APL)。在應(yīng)用層內(nèi)提供了應(yīng)用支持子層(applicationsupportsub—layer,APS)和ZigBee設(shè)備對(duì)象(ZigBeeDeviceObject,ZDO)。應(yīng)用框架中則加入了用戶自定義的應(yīng)用對(duì)象
? ?ZigBee的體系結(jié)構(gòu)由稱為層的各模塊組成。每一層為其上層提供特定的服務(wù):即由數(shù)據(jù)服務(wù)實(shí)體提供數(shù)據(jù)傳輸服務(wù);管理實(shí)體提供所有的其他管理服務(wù)。每個(gè)服務(wù)實(shí)體通過(guò)相應(yīng)的服務(wù)接入點(diǎn)(SAP)為其上層提供一個(gè)接口,每個(gè)服務(wù)接入點(diǎn)通過(guò)服務(wù)原語(yǔ)來(lái)完成所對(duì)應(yīng)的功能。
? ?ZigBee協(xié)議棧的核心部分在網(wǎng)絡(luò)層。網(wǎng)絡(luò)層主要實(shí)現(xiàn)節(jié)點(diǎn)加入或離開網(wǎng)絡(luò)、接收或拋棄其他節(jié)點(diǎn)、路由查找及傳送數(shù)據(jù)等功能。
? ?應(yīng)用層(APL)ZigBee應(yīng)用層框架包括應(yīng)用支持層(APS)、ZigBee設(shè)備對(duì)象(ZDO)和制造商所
? ?應(yīng)用支持層的功能包括:維持綁定表、在綁定的設(shè)備之間傳送消息。ZigBee設(shè)備對(duì)象的功能包括:定義設(shè)備在網(wǎng)絡(luò)中的角色(如ZigBee協(xié)調(diào)器和終端設(shè)備),發(fā)起和響應(yīng)綁定請(qǐng)求,在網(wǎng)絡(luò)設(shè)備之間建立安全機(jī)制。ZigBee設(shè)備對(duì)象還負(fù)責(zé)發(fā)現(xiàn)網(wǎng)絡(luò)中的設(shè)備,并且決定向他們提供何種應(yīng)用服務(wù)。ZigBee應(yīng)用層除了提供一些必要函數(shù)以及為網(wǎng)絡(luò)層提供合適的服務(wù)接口外,一個(gè)重要的功能是應(yīng)用者可在這層定義自己的應(yīng)用對(duì)象,開發(fā)人員一般進(jìn)行開發(fā)也只是在應(yīng)用層的基礎(chǔ)上面進(jìn)行開發(fā),因?yàn)槲覀儾荒苋?dòng)zigbee協(xié)議棧里面的內(nèi)容。
?
?
?
設(shè)備類型
? ?在ZigBee網(wǎng)絡(luò)中存在三種邏輯設(shè)備類型:Coordinator(協(xié)調(diào)器),Router(路由器)和End-Device(終端設(shè)備)。ZigBee網(wǎng)絡(luò)由一個(gè)Coordinator以及多個(gè)Router和多個(gè)End_Device組成.協(xié)調(diào)器負(fù)責(zé)啟動(dòng)整個(gè)網(wǎng)絡(luò)。它也是網(wǎng)絡(luò)的第一個(gè)設(shè)備。協(xié)調(diào)器選擇一個(gè)信道和一個(gè)網(wǎng)絡(luò)ID(也稱之為PANID,即PersonalAreaNetworkID(個(gè)域網(wǎng)ID)),隨后啟動(dòng)整個(gè)網(wǎng)絡(luò)。協(xié)調(diào)器也可以用來(lái)協(xié)助建立網(wǎng)絡(luò)中安全層和應(yīng)用層的綁定(bindings)。協(xié)調(diào)器的角色主要涉及網(wǎng)絡(luò)的啟動(dòng)和配臵。一旦這些都完成后,協(xié)調(diào)器的工作就像一個(gè)路由器(或者消失goaway)。由于ZigBee網(wǎng)絡(luò)本身的分布特性,因此接下來(lái)整個(gè)網(wǎng)絡(luò)的操作就不在依賴協(xié)調(diào)器是否存在,因?yàn)閆igBee是蜂窩式分布式網(wǎng)絡(luò)。
? ?路由器的功能主要是:允許其他設(shè)備加入網(wǎng)絡(luò),多跳路由和協(xié)助它自己的由電池供電的終端設(shè)備的通訊。 通常,路由器希望是一直處于活動(dòng)狀態(tài),因此它必須使用主電源供電。但是當(dāng)使用樹狀網(wǎng) 絡(luò)拓?fù)浣Y(jié)構(gòu)時(shí),允許路由間隔一定的周期操作一次,這樣就可以使用電池給其供電。
??終端設(shè)備沒(méi)有特定的維持網(wǎng)絡(luò)結(jié)構(gòu)的責(zé)任,它可以睡眠或者喚醒,因此它可以可以是一個(gè)電池供電設(shè)備。通常,終端設(shè)備對(duì)存儲(chǔ)空間(特別是 RAM 的需要)比較小。一般終端設(shè)備采集相關(guān)的傳感器節(jié)點(diǎn)信息,控制相應(yīng)的控制部分。
注意:一個(gè)ZigBee網(wǎng)絡(luò)由一個(gè)協(xié)調(diào)器節(jié)點(diǎn)、多個(gè)路由器和多個(gè)終端設(shè)備節(jié)點(diǎn)組成。設(shè)備類型不以任何方式限制應(yīng)用程序的類型,可以運(yùn)行在特定的裝置,這就說(shuō)明了一個(gè)zigbee的開發(fā)模塊,你給它燒寫什么設(shè)備類型的代碼它就是什么的設(shè)備類型了。
?
拓?fù)浣Y(jié)構(gòu)
? ?ZigBee網(wǎng)絡(luò)支持星狀、樹狀和網(wǎng)狀三種網(wǎng)絡(luò)拓?fù)浣Y(jié)構(gòu),它們的介紹(優(yōu)缺點(diǎn))分別為
? ?星狀網(wǎng)絡(luò)(star)由一個(gè)PAN協(xié)調(diào)器和多個(gè)終端設(shè)備組成,只存在PAN協(xié)調(diào)器與終端的通訊,終端設(shè)備間的通訊都需通過(guò)PAN協(xié)調(diào)器的轉(zhuǎn)發(fā)。
? ?樹狀網(wǎng)絡(luò)(tree)由一個(gè)協(xié)調(diào)器和一個(gè)或多個(gè)星狀結(jié)構(gòu)連接而成,設(shè)備除了能與自己的父節(jié)點(diǎn)或子節(jié)點(diǎn)進(jìn)行點(diǎn)對(duì)點(diǎn)直接通訊外,其他只能通過(guò)樹狀路由完成消息傳輸。
? ?網(wǎng)狀網(wǎng)絡(luò)(mesh)是樹狀網(wǎng)絡(luò)基礎(chǔ)上實(shí)現(xiàn)的,與樹狀網(wǎng)絡(luò)不同的是,它允許網(wǎng)絡(luò)中所有具有路由功能的節(jié)點(diǎn)直接互連,由路由器中的路由表實(shí)現(xiàn)消息的網(wǎng)狀路由。該拓?fù)涞膬?yōu)點(diǎn)是減少了消息延時(shí),增強(qiáng)了可靠性,缺點(diǎn)是需要更多的存儲(chǔ)空間開銷
關(guān)于網(wǎng)絡(luò)結(jié)構(gòu)的定義同樣在nwk_globals.h中定義。默認(rèn)的是是選擇網(wǎng)狀結(jié)構(gòu)
信標(biāo)與非信標(biāo)模式
? ?ZigBee網(wǎng)絡(luò)的工作模式可以分為信標(biāo)(Beacon)和非信標(biāo)(Non-beacon)兩種模式。信標(biāo)模式實(shí)現(xiàn)了網(wǎng)絡(luò)中所有設(shè)備的同步工作和同步休眠,以達(dá)到最大限度的功耗節(jié)省,而非信標(biāo)模式則只允許終端設(shè)備進(jìn)行周期性休眠,協(xié)調(diào)器和所有路由器設(shè)備必須長(zhǎng)期處于工作狀態(tài)
? ?信標(biāo)模式下,協(xié)調(diào)器負(fù)責(zé)以一定的間隔時(shí)間(一般在15ms-4mins之間)向網(wǎng)絡(luò)廣播信標(biāo)幀,兩個(gè)信標(biāo)幀發(fā)送間隔之間有16個(gè)相同的時(shí)槽,這些時(shí)槽分為網(wǎng)絡(luò)休眠區(qū)和網(wǎng)絡(luò)活動(dòng)區(qū)兩個(gè)部分,消息只能在網(wǎng)絡(luò)活動(dòng)區(qū)的各時(shí)槽內(nèi)發(fā)送。
? ?非信標(biāo)模式下,ZigBee標(biāo)準(zhǔn)采用父節(jié)點(diǎn)為終端設(shè)備子節(jié)點(diǎn)緩存數(shù)據(jù),終端設(shè)備主動(dòng)向其父節(jié)點(diǎn)提取數(shù)據(jù)的機(jī)制,實(shí)現(xiàn)終端設(shè)備的周期性(周期可設(shè)臵)休眠。網(wǎng)絡(luò)中所有父節(jié)點(diǎn)需為自己的終端設(shè)備子節(jié)點(diǎn)緩存數(shù)據(jù)幀,所有終端設(shè)備子節(jié)點(diǎn)的大多數(shù)時(shí)間都處于休眠模式,周期性的醒來(lái)與父節(jié)點(diǎn)握手以確認(rèn)自己仍處于網(wǎng)絡(luò)中,其從休眠模式轉(zhuǎn)入數(shù)據(jù)傳輸模式一般只需要15ms。所有節(jié)點(diǎn)競(jìng)爭(zhēng)同一信道,使用CSMA/CA的信道接入技術(shù),(就是節(jié)點(diǎn)在發(fā)送數(shù)據(jù)之前先監(jiān)聽信道,如果信道空閑則可以發(fā)送數(shù)據(jù),否則就要進(jìn)行隨機(jī)的退避,即延遲一段隨機(jī)時(shí)間,然后再進(jìn)行監(jiān)聽,)信標(biāo)與非信標(biāo)是信標(biāo)接入模式。TI的Zstack協(xié)議棧采用的就是非信標(biāo)模式。(網(wǎng)上是這么說(shuō)的我也不知道在哪里定義的,稍后我去翻一翻源代碼看一下)信道接入方式采用免沖突載波檢測(cè)多址接入(CSMA-CA)機(jī)制;(這個(gè)不多說(shuō)自己去查一下)
地址(16與64位地址)網(wǎng)絡(luò)地址
? ?ZigBee設(shè)備有兩種類型的地址。一種是64位IEEE地址,即MAC地址,另一種是16位網(wǎng)絡(luò)地址。
? ?64位地址使全球唯一的地址,設(shè)備將在它的生命周期中一直擁有它。它通常由制造商或者被安裝時(shí)設(shè)臵。這些地址由IEEE來(lái)維護(hù)和分配。
? ?16位網(wǎng)絡(luò)地址是當(dāng)設(shè)備加入網(wǎng)絡(luò)后分配的。它在加入的網(wǎng)絡(luò)中是唯一的,用來(lái)在網(wǎng)絡(luò)中鑒別設(shè)備和發(fā)送數(shù)據(jù)。其中,協(xié)調(diào)器的網(wǎng)絡(luò)地址為0x0000,是固定的,所有的zigbee協(xié)調(diào)器中的網(wǎng)絡(luò)地址是唯一的.(所以16位地址是可變的),這也決定了一個(gè)zigbee網(wǎng)絡(luò)中最多只能有65535個(gè)節(jié)點(diǎn)組成。
在ZigBee無(wú)線網(wǎng)絡(luò)里,每一個(gè)zigbee模塊(模塊可以由終端、路由器、協(xié)調(diào)器組成)都有一個(gè)在該網(wǎng)絡(luò)中唯一的2個(gè)字節(jié)的地址,這個(gè)地址叫做網(wǎng)絡(luò)地址(網(wǎng)絡(luò)短地址)
PANID(個(gè)域網(wǎng)ID):這個(gè)是2個(gè)字節(jié)的編碼,用來(lái)區(qū)別不同的ZigBee無(wú)線局域網(wǎng),我們稱為個(gè)域網(wǎng)ID。
信道
ZigBee無(wú)線通信需要高頻的載波來(lái)提供發(fā)射效率,ZigBee模塊之間要正常的通信,接收模塊和發(fā)射模塊的頻率要一致。ZigBee有27個(gè)載波可以進(jìn)行通信,載波又叫信道。這些載波的頻率落在某個(gè)頻率區(qū)段,我們把這些區(qū)段叫做頻段
2.4G頻段??16個(gè)信道?
915頻段?896頻段?11個(gè)信道
但是TI的所有支持ZigBee底層協(xié)議的芯片只有在2.4G頻段的16個(gè)信道里進(jìn)行通信,即11-26號(hào)信道(0-10信道在896、915頻段),11號(hào)信道是2405M,以后沒(méi)增加一個(gè)信道,頻率增加5M,26號(hào)信道2485M。
/* Default channel is Channel 11 - 0x0B */
// Channels are defined in the following:
// ? ? ? ? 0 ? ? ?: 868 MHz ? ? 0x00000001
// ? ? ? ? 1 - 10 : 915 MHz ? ? 0x000007FE
// ? ? ? ?11 - 26 : 2.4 GHz ? ? 0x07FFF800
//
//-DMAX_CHANNELS_868MHZ ? ? 0x00000001
//-DMAX_CHANNELS_915MHZ ? ? 0x000007FE
//-DMAX_CHANNELS_24GHZ ? ? ?0x07FFF800
在ZigBee無(wú)線局域網(wǎng)里面,節(jié)點(diǎn)(無(wú)線模塊)按照網(wǎng)絡(luò)里面的功能來(lái)劃分,可以分為協(xié)調(diào)器,路由器,終端,他們的硬件可以一模一樣。之所以在網(wǎng)絡(luò)里面表現(xiàn)不同的功能,是因?yàn)樗麄兿螺d了不同功能版本的程序,在同一個(gè)網(wǎng)絡(luò)里擔(dān)當(dāng)不同的角色功能。
?
下載了路由器和終端代碼的節(jié)點(diǎn),上電后第一件事情是去尋找網(wǎng)絡(luò)(是根據(jù)屬于同一個(gè)個(gè)域網(wǎng)ID和信道來(lái)進(jìn)行劃分),請(qǐng)求加入,;而網(wǎng)絡(luò)不會(huì)平白無(wú)故去產(chǎn)生,是由下載了協(xié)調(diào)器代碼的節(jié)點(diǎn)創(chuàng)建的,下載協(xié)調(diào)器代碼的節(jié)點(diǎn)上電后第一件事情是去創(chuàng)建網(wǎng)絡(luò)。
?
任何一個(gè)網(wǎng)絡(luò),第一個(gè)節(jié)點(diǎn)一定是該網(wǎng)絡(luò)的協(xié)調(diào)器,有且只有一個(gè)。協(xié)調(diào)器網(wǎng)絡(luò)組建后,網(wǎng)絡(luò)里面的協(xié)調(diào)器的網(wǎng)絡(luò)地址已經(jīng)固定為0x0000,當(dāng)設(shè)備加入成功后,會(huì)產(chǎn)生一個(gè)ZDO_STATE_CHANGE_EVT事件,這個(gè)事件就是設(shè)備加入網(wǎng)絡(luò)成功后,并在網(wǎng)絡(luò)中的身份確定后產(chǎn)生的一個(gè)事件,我們可以在這里處理,一些初始化,比如可以發(fā)送終端的短地址,IEEE地址等,這里協(xié)調(diào)器接收到以后,可以提取出終端的短地址,其實(shí)在終端給協(xié)調(diào)器發(fā)送的每個(gè)數(shù)據(jù)包中,都含有其自身的短地址,如結(jié)構(gòu)體當(dāng)中的afAddrType_t srcAddr;協(xié)調(diào)器在接收到短地址后,就可以知道自己下面管轄的終端節(jié)點(diǎn),或者路由節(jié)點(diǎn)有哪些了。
注意:模塊如果想要通信,必須位于同一個(gè)信道,同一個(gè)個(gè)域網(wǎng),在Tools文件夾中的f8wConfig.cfg文件可以修改信道和個(gè)域網(wǎng)
應(yīng)用層是一個(gè)任務(wù),它有一個(gè)系統(tǒng)分配給它的數(shù)值唯一的編號(hào)叫做任務(wù)ID,查看ZMain.c?中的osal_init_syste()中的osalInitTasks();發(fā)現(xiàn)應(yīng)用層的任務(wù)ID是最大的那個(gè)(8);
任務(wù)可以處理事件,處理事件的這些代碼都在一個(gè)函數(shù)里,這個(gè)函數(shù)就叫做任務(wù)處理函數(shù),我們查看osal_start_system()中使用的tasksArr[]?知道應(yīng)用層對(duì)應(yīng)的任務(wù)處理函數(shù)是GenericApp_ProcessEvent();
?
應(yīng)用層任務(wù)還有一個(gè)2個(gè)字節(jié)的變量 任務(wù)事件變量tasksEvents
?
當(dāng)發(fā)現(xiàn)有一個(gè)任務(wù)事件變量的值不為0就意味著這個(gè)任務(wù)層有事件要去處理,如果這個(gè)任務(wù)事件變量得到值為0就是沒(méi)有事件要去處理,如果有事件要去處理,那么會(huì)調(diào)用相對(duì)應(yīng)的任務(wù)事件處理函數(shù)就行處理。
?
tasksEvents[]= {任務(wù)事件變量a,任務(wù)事件變量b,……}
tasksArr[] = {任務(wù)事件處理函數(shù)A,任務(wù)事件處理函數(shù)B,……};
?
osal_init_system();?在這個(gè)函數(shù)里發(fā)現(xiàn)系統(tǒng)給所有任務(wù)分配任務(wù)ID,表示當(dāng)前系統(tǒng)又taskCnt個(gè)任務(wù);
?
osal_start_system();所有協(xié)議棧在穩(wěn)定工作時(shí),他的行為是不斷的去讀所有的任務(wù)的任務(wù)事件變量,如果發(fā)現(xiàn)所有的任務(wù)事件變量的值都為0,說(shuō)明沒(méi)有事件要去處理,直到發(fā)現(xiàn)某個(gè)任務(wù)事件變量的值不為0,就會(huì)通知這個(gè)不為0的任務(wù)ID去處理這個(gè)事件。
?
?
在GenericAPP.c?中的319行跳轉(zhuǎn)到GENERICAPP_SEND_MSG_EVT的定義處,定義我自己的事件,比如#define GENERICAPP_MY_EVT 0x0002(后面的數(shù)字不能隨便定義,每一個(gè)bit位上只有有一個(gè)為1),然后在網(wǎng)絡(luò)狀態(tài)改變的那里利用osal_start_timerEx將自定義的事件和應(yīng)用層任務(wù)ID掛鉤,然后在任務(wù)事件處理代碼那里用調(diào)用osal_start_timerEx,那么可以實(shí)現(xiàn)燈的閃爍
?
?
?尋址發(fā)數(shù)據(jù)
ZigBee向網(wǎng)絡(luò)中的設(shè)備發(fā)送數(shù)據(jù),應(yīng)用程序通常使用AF_DataRequest()函數(shù)。
AF_DataRequest(afAddrType_t*dstAddr,//全ZB目的地址,包含NWK地址與ENDPoint
endPointDesc_t*srcEP,//端點(diǎn)描述符
uint16cID,//簇ID
uint16len,//要發(fā)送數(shù)據(jù)的長(zhǎng)度
uint8*buf,//要發(fā)送的數(shù)據(jù)(地址)
uint8*transID,//傳輸序列號(hào)
uint8options,//發(fā)送選項(xiàng)的有效標(biāo)志位
uint8radius);//一般設(shè)置為AF_DEFAULT_RADIUS
?
我們主要看一下第一個(gè)參數(shù)。NWK地址(這里指的是16位的地址)ENDPoint(這是那個(gè)20)
typedefstruct
{
union
{
uint16shortAddr;
ZLongAddr_textAddr;
}addr;
afAddrMode_taddrMode;
byteendPoint;
uint16panId;//usedfortheINTER_PANfeature
}afAddrType_t;
其中包括16或64為地址,網(wǎng)絡(luò)地址。
地址模式參數(shù)
typedefenum
{
afAddrNotPresent=AddrNotPresent,
afAddr16Bit=Addr16Bit,
afAddr64Bit=Addr64Bit,
afAddrGroup=AddrGroup,
afAddrBroadcast=AddrBroadcast
}afAddrMode_t;
它主要用來(lái)表征是單點(diǎn)傳送(unicast),多點(diǎn)傳送(multicast)還是廣播傳送
? ?單點(diǎn)傳送(Unicast)Uicast是標(biāo)準(zhǔn)尋址模式,它將數(shù)據(jù)包發(fā)送給一個(gè)已經(jīng)知道網(wǎng)絡(luò)地址的網(wǎng)絡(luò)設(shè)備。將afAddrMode設(shè)臵為Addr16Bit并且在數(shù)據(jù)包中攜帶目標(biāo)設(shè)備地址。
? ?間接傳送(Indirect)當(dāng)應(yīng)用程序不知道數(shù)據(jù)包的目標(biāo)設(shè)備在哪里的時(shí)候使用的模式。將模式設(shè)臵為AddrNotPresent并且目標(biāo)地址沒(méi)有指定。取代它的是從發(fā)送設(shè)備的棧的綁定表中查找目標(biāo)設(shè)備。這種特點(diǎn)稱之為源綁定。(這種方式一般用于綁定的情況下)當(dāng)數(shù)據(jù)向下發(fā)送到達(dá)棧中,從綁定表中查找并且使用該目標(biāo)地址。這樣,數(shù)據(jù)包將被處理成為一個(gè)標(biāo)準(zhǔn)的單點(diǎn)傳送數(shù)據(jù)包。如果在綁定表中找到多個(gè)設(shè)備,則向每個(gè)設(shè)備都發(fā)送一個(gè)數(shù)據(jù)包的拷貝。上一個(gè)版本的ZigBee(ZigBee2004),有一個(gè)選項(xiàng)可以講綁定表保存在協(xié)調(diào)器(Coordinator)當(dāng)中。發(fā)送設(shè)備將數(shù)據(jù)包發(fā)送給協(xié)調(diào)器,協(xié)調(diào)器查找它棧中的綁定表,然后將數(shù)據(jù)發(fā)送給最終的目標(biāo)設(shè)備。這個(gè)附加的特性叫做協(xié)調(diào)器綁定(CoordinatorBinding)。
? ?廣播傳送(broadcast)當(dāng)應(yīng)用程序需要將數(shù)據(jù)包發(fā)送給網(wǎng)絡(luò)的每一個(gè)設(shè)備時(shí),使用這種模式。地址模式設(shè)臵為AddrBroadcast。目標(biāo)地址可以設(shè)臵為下面廣播地址的一種:
NWK_BROADCAST_SHORTADDR_DEVALL(0xFFFF)——數(shù)據(jù)包將被傳送到網(wǎng)絡(luò)上的所有設(shè)備,包括睡眠中的設(shè)備。對(duì)于睡眠中的設(shè)備,數(shù)據(jù)包將被保留在其父親節(jié)點(diǎn)直到查詢到它,或者消息超時(shí)(NWK_INDIRECT_MSG_TIMEOUT在f8wConifg.cfg中)。
NWK_BROADCAST_SHORTADDR_DEVRXON(0xFFFD)——數(shù)據(jù)包將被傳送到網(wǎng)絡(luò)上的所有在空閑時(shí)打開接收的設(shè)備(RXONWHENIDLE),也就是說(shuō),除了睡眠中的所有設(shè)備。
NWK_BROADCAST_SHORTADDR_DEVZCZR(0xFFFC)——數(shù)據(jù)包發(fā)送給所有的路由器,包括協(xié)調(diào)器。
組尋址(GroupAddressing)當(dāng)應(yīng)用程序需要將數(shù)據(jù)包發(fā)送給網(wǎng)絡(luò)上的一組設(shè)備時(shí),使用該模式。地址模式設(shè)臵為afAddrGroup并且addr.shortAddr設(shè)臵為組ID。
aps_Group_tgroup;
group.ID=0x0001;
group.name[0]=0;//Thiscouldbeahumanreadablestring,比如說(shuō)“Group1”
aps_AddGroup(SAMPLEAPP_ENDPOINT,&group);
其中的aps_Group_t中只包含ID與name兩個(gè)參數(shù)
?
獲取重要地址
NLME_GetShortAddr()——返回本設(shè)備的16位網(wǎng)絡(luò)地址
NLME_GetExtAddr()——返回本設(shè)備的64位擴(kuò)展地址
NLME_GetCoordShortAddr()——返回本設(shè)備的父親設(shè)備的16位網(wǎng)絡(luò)地址NLME_GetCoordExtAddr()——返回本設(shè)備的父親設(shè)備的64位擴(kuò)展地址
NLME_IsAddressBroadcast()此函數(shù)根據(jù)設(shè)備能力來(lái)評(píng)估提供的地址是否是一個(gè)有效的廣播地址。
NLME_SetBroadCastFilter()此函數(shù)根據(jù)設(shè)備能力設(shè)置掩碼,用于處理有效的廣播地址
?
單播
單播的特點(diǎn)是:在ZigBee網(wǎng)絡(luò)中,模塊之間要進(jìn)行通信,發(fā)射模塊要明確知道接收模塊的網(wǎng)絡(luò)地址,以這個(gè)發(fā)送數(shù)據(jù)給指定接收模塊。
?
單播要確定的信息:
1)目標(biāo)地址:也就是網(wǎng)絡(luò)短地址,協(xié)調(diào)器的網(wǎng)絡(luò)地址是0x0000.
2)目標(biāo)端點(diǎn)與簇
端點(diǎn):通常要發(fā)送到的數(shù)據(jù)要明確該數(shù)據(jù)是給接收模塊的哪個(gè)任務(wù)層的,而這個(gè)是通過(guò)端點(diǎn)來(lái)指定的;(引用端口的主要原因是TI實(shí)現(xiàn)的zigbee協(xié)議棧中加入了一個(gè)小的操作系統(tǒng),這樣每個(gè)節(jié)點(diǎn)的所有端口共用一個(gè)發(fā)射/接收天線,不同的節(jié)點(diǎn)上的不同端口之間進(jìn)行通信僅僅通過(guò)網(wǎng)絡(luò)地址是無(wú)法區(qū)分,因此在發(fā)送數(shù)據(jù)的時(shí)候不但要指定網(wǎng)絡(luò)地址還有指定端口號(hào))
簇:在接收模塊中,每個(gè)任務(wù)層可以對(duì)應(yīng)不同的數(shù)據(jù)類型采取不同的處理方式,這里數(shù)據(jù)類型就是簇
3)要發(fā)送的數(shù)據(jù)與大小
發(fā)送函數(shù)和接收函數(shù)
發(fā)送
afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
? ? ? ? ? ? ? ? ? ? ? ? ? ?uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
? ? ? ? ? ? ? ? ? ? ? ? ? ?uint8 options, uint8 radius )
{
AF_DataRequest
( &GenericApp_DstAddr,???接收方發(fā)送方的地址,發(fā)送數(shù)據(jù)的格式(廣播、單播和多播)
&GenericApp_epDesc,??發(fā)送方的地址,端點(diǎn)描述符,指定發(fā)送數(shù)據(jù)的端口? ? ? ? ? ? ? ? ? ??
GENERICAPP_CLUSTERID,?發(fā)送數(shù)據(jù)使用的命令,主要用于接收數(shù)據(jù)的時(shí)候區(qū)分不同的命令? ? ? ? ? ? ??
(byte)osal_strlen( theMessageData ) + 1,?數(shù)據(jù)大小
?(byte *)&theMessageData,?數(shù)據(jù)的地址
???&GenericApp_TransID,//指向發(fā)送數(shù)據(jù)的序號(hào)
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS )?發(fā)送的路徑,一般采取默認(rèn)
?AF_DataRequest( &GenericApp_DstAddr,?
? ? ? ? ? ? ? ? ? ? ? ?&GenericApp_epDesc,
? ? ? ? ? ? ? ? ? ? ? ?GENERICAPP_MY_CLUSTERID, //指定事件
? ? ? ? ? ? ? ? ? ? ? ?(byte)osal_strlen( str ) + 1,
? ? ? ? ? ? ? ? ? ? ? ? str,//(byte *)&theMessageData,
? ? ? ? ? ? ? ? ? ? ? ?&GenericApp_TransID,
? ? ? ? ? ? ? ? ? ? ? ?AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
接收
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
? switch ( pkt->clusterId )
? {
? ? ? P1_1 = ~P1_1;
? ? case GENERICAPP_CLUSTERID:
? ? ? // "the" message
#if defined( LCD_SUPPORTED )
? ? ? HalLcdWriteScreen( (char*)pkt->cmd.Data, "rcvd" );
#elif defined( WIN32 )
? ? ? WPRINTSTR( pkt->cmd.Data );
#endif
??break;
? case GENERICAPP_MY_CLUSTERID:
/*
把自己收到的存放在(char*)pkt->cmd.Data;的數(shù)據(jù)取出來(lái)然后
通過(guò)串口發(fā)送給PC機(jī)
*/
char *s=(char*)pkt->cmd.Data;
UartTX_Send_String(s ,strlen(s));
? ? ? break;
? }
}
擴(kuò)展閱讀:zigbee協(xié)議棧數(shù)據(jù)包格式
?在構(gòu)成數(shù)據(jù)包時(shí)MAC幀是作為物理層幀的物理層凈荷存在的。
網(wǎng)絡(luò)層(NWK)幀主要包含兩部分:
NWK頭(NHR,NWK Header) NWK凈荷(NWK Payload),NWK頭主要包含一些網(wǎng)絡(luò)級(jí)的地址信息和控制信息。
??
?