第一篇:Zigbee心得體會
心得體會
本次實訓之前,我就上網搜索了Zigbee的概念和相關信息。通過這次為期五周的無線通信技術綜合訓練,我對Zigbee無線通信技術,以及單片機CC2530開發板的硬件結構和功能有了初步的了解和認識。
實訓的第一周,我們學習利用IAR Embedded Wordbench軟件,建立工程,編寫、調試和下載程序,通過CC2530開發板的現象來分析程序的功能。親眼目睹了軟件驅動硬件工作之后,我開始對這次實訓產生了濃厚興趣。在熟悉了軟件和硬件的基本操作后,我們開始編寫和調試相對復雜的程序。這個編寫和調試的過程對我來說是個很大的挑戰,因為我的C51基礎很薄弱,所以很多看似簡單的程序,我都要去查資料或者請教老師同學。最后一周的綜合實驗,是小組合作共同完成的。我體會到了Zigbee技術的功能強大,也體會到了團隊合作的快樂和價值。
現實和理想總是有差距的,或多或少都會出現一些問題。對于通信方面的實訓來說更是如此。在這次實訓過程中,我遇到了各種問題:某句程序不理解,程序調試不成功,節點指示燈不閃爍,液晶屏顯示亂碼,實驗現象和預期要求不符等。通過查閱相關資料、小組成員探討和請教老師等途徑,這些問題得到了及時有效的解決。解決問題的過程不是一帆風順的,是要付出汗水和努力的,但這個過程很值得。
通過這次實訓,我認識和了解了熱門的Zigbee技術,提高了C51的程序編寫和調試能力。更重要的是,這次實訓提高了我們通信專業所必需的實踐能力和職場所需的團隊合作能力,培養了我們認真嚴謹的科學態度。這些東西將讓我們終身受益!
第二篇:zigbee學習自我總結!!!!!
1.Zigbee網絡節點類型
Zigbee網絡有三類節點類型:即協調器Coordinator、路由器Router和終端設備EndDevice,其中協調器和路由器均為全功能設備,而終端設備選用精簡功能設備。
2.Zigbee協議棧各層主要功能模塊
3.Zigbee網絡節點地址
Zigbee網絡協議的每一個節點皆有兩個地址:64位的IEEE MAC地址及16位網絡地址.EUI-64(64-bit extended unique identifier)
1)64-bit地址,又稱為MAC地址或IEEE地址。
每個ZigBee節點都應該有全球唯一的64位IEEE地址。這個地址需要向IEEE組織申請才能使用。通信時,將待發送的數據包的目的地址設為此64位IEEE地址,從而實現數據包的正確投遞。
2)16-bit地址,即網絡地址,或稱為短地址。當一個ZigBee網絡形成后,ZigBee網絡內的每個節點,都會分配到一個16位的網絡地址。通信時,將待發送的數據包的目的地址設為此16位網絡地址。
4.Zigbee協議術語
配置文件(profile):Zigbee協議的配置文件是對邏輯組件及其相關接口的描述,是面向某個應用類別的公約、準則.通常沒有程序代碼與配置文件相關聯.
屬性(attribute):設備之間通信的每一種數據像開關的狀態或溫度計值等皆可稱為屬性.每個屬性可得到唯一的ID值.
簇(cluster):多個屬性的匯集形成了簇,每個簇也擁有一個唯一的ID。雖然個體之間傳輸的通常是屬性信息,但所謂的邏輯組件的接口指的卻是簇一級的操作,而非屬性一級.
終端(endpoint):每個支持一個或多個簇的代碼功能塊稱為終端。不同的設備通過它們的終端及所支持的簇來進行通信。
PAN IDs:PAN IDs是用來在邏輯上分離在同一領域內的多個節點組。這樣不同組之間節點通信就不會干擾,且可以在同一通道channel上(zigbee2007不行,因為它通信時可以改變頻率的)Pan id是16位,范圍是0x0000~03fff。當建立或加入網絡時沒有指定PAN ID的話,就會根據default PAN ID確定。它是個常量。
Extended PAN ID:zigbee 增加了一個8字節的擴展PAN ID,便于提供服務和PAN ID沖突檢測。5.Zigbee協議結構
●物理層(PHY)物理層定義了物理無線信道和MAC子層之間的接口,提供物理層數據服務和 物理層管理服務。物理層內容: 1)ZigBee的激活;2)當前信道的能量檢測;3)接收鏈路服務質量信息;4)ZigBee信道接入方式;5)信道頻率選擇;6)數據傳輸和接收?!窠橘|接入控制子層(MAC)MAC層負責處理所有的物理無線信道訪問,并產生網絡信號、同步信號;支持PAN連接和分離,提供兩個對等MAC實體之間可靠的鏈路。
MAC層功能:
1)網絡協調器產生信標; 2)與信標同步;
3)支持PAN(個域網)鏈路的建立和斷開; 4)為設備的安全性提供支持;
5)信道接入方式采用免沖突載波檢測多址接入(CSMA-CA)機制; 6)處理和維護保護時隙(GTS)機制;
7)在兩個對等的M AC實體之間提供一個可靠的通信鏈路。●網絡層(NWK)
ZigBee協議棧的核心部分在網絡層。網絡層主要實現節點加入或離開網絡、接收或拋棄其他節點、路由查找及傳送數據等功能。網絡層功能: 1)網絡發現;2)網絡形成;3)允許設備連接;4)路由器初始化;5)設備同網絡 連接;6)直接將設備同網絡連接;7)斷開網絡連接;8)重新復位設備;9)接收機 同步;10)信息庫維護?!駪脤樱ˋPL)
ZigBee應用層框架包括應用支持層(APS)、ZigBee設備對象(ZDO)和制造商所定義的應用對象。應用支持層的功能包括:維持綁定表、在綁定的設備之間傳送消息。
ZigBee設備對象的功能包括:定義設備在網絡中的角色(如ZigBee協調器和終端設備),發起和響應綁定請求,在網絡設備之間建立安全機制。ZigBee 設備對象還負責發現網絡中的設備,并且決定向他們提供何種應用服務。ZigBee應用層除了提供一些必要函數以及為網絡層提供合適的服務接口外,一個重要的功能是應用者可在這層定義自己的應用對象。●應用程序框架(AF)
運行在ZigBee協議棧上的應用程序實際上就是廠商自定義的應用對象,并且遵循規范(profile)運行在端點1---240上。在ZigBee應用中,提供2種標準服務類型:鍵值對(KVP)或報文(MSG)?!馴igbee設備對象(ZDO)
遠程設備通過ZDO請求描述符信息,接收到這些請求時,ZDO會調用配置對象獲取相應描述符值。另外,ZDO提供綁定服務。
6.Z-Stack軟件構架
Z-Stack由main()函數開始執行,main()函數共做了2件事:一是系統初始化,另外一件是開始執行輪轉查詢式操作系統,如下圖所示:
7.Z-Stack 系統運行流程圖
8.Z-Stack在項目中的目錄結構
(1)App:應用層目錄,這個目錄下的文件就是創建一個新項目時自己要添加的文件,(2)HAL:硬件層目錄,Common目錄下的文件是公用文件,基本上與硬件無關,其中hal_assert.c是斷言文件,用于調用,hal_drivers.c是驅動文件,抽象出與硬件無關的驅動函數,包含有與硬件相關的配置和驅動及操作函數。Include目錄下主要包含各個硬件模塊的頭文件,而Target目錄下的文件是跟硬件平臺相關的,可能看到有兩個平臺,分別是Cc2430DB平臺和一個CC2430EB平臺。后面的DB和EB表示的是TI公司開發板的型號,其實還有一種類型是BB的,BB: Battery Board DB: Development Board EB: Evaluation Board 分別對應TI公司開發的三種板型,其功能按上順序依次變強??梢詤⒖础癦-Stack User's Guide for CC2430”的圖片,可以獲得更直觀的認識。
(3)MAC:MAC層目錄,High Level和Low Level兩個目錄表示MAC層分為了高層和底層兩層,Include目錄下則包含了MAC層的參數配置文件及基MAC的LIB庫函數接口文件,這里的MAC層的協議是不開源的,以庫的形式給出
(4)MT:監制調試層目錄,該目錄下的文件主要用于調試目的,即實現通過串口調試各層,與各層進行直接交互。
(5)NWK:網絡層目錄,含有網絡層配置參數文件及網絡層庫的函數接口文件,及APS層庫的函數接口
(6)OSAL:協議棧的操作系統抽象層目錄
(7)Profile:AF層目錄,Application Farmework 應用框架,包含AF層處理函數接口文件。
(8)Security:安全層目錄,包含安全層處理函數接口文件
(9)Services:ZigBee和802.15.4設備地址處理函數目錄,包括地址模式的定義及地址處理函數
(10)Tools:工作配置目錄,包括空間劃分及Z-Stack相關配置信息
(11)ZDO:指ZigBee設備對象,可認為是一種公共的功能集,文件用戶用自定義的對象調用APS子層的服務和NWK層的服務
(12)ZMAC:其中Zmac.c是Z-StackMAC導出層接口文件,zmac_cb.c是ZMAC需要調用的網絡層函數
(13)Zmain:Zmain.c主要包含了整個項目的入口函數main(),在OnBoard.c包含硬件開始平臺類外設進行控制的接口函數
(14)Output:輸出文件目錄,這個是EW8051 IDE自動生成的
9.Z-stack 中實現自己的任務
在Zstack(TI的Zigbee協議棧)中,對于每個用戶自己新建立的任務通常需要兩個相關的處理函數,包括: ①用于初始化的函數
如:SampleApp_Init(),這個函數是在osalInitTasks()這個osal(Zstack中自帶的小操作系統)中去調用的,其目的就是把一些用戶自己寫的任務中的一些變量,網絡模式,網絡終端類型等進行初始化;②用于引起該任務狀態變化的事件發生后所需要執行的事件處理函數
如:SampleApp_ProcessEvent(),這個函數是首先const pTaskEventHandlerFn tasksArr[ ]中進行設置(綁定),然后在osalInitTasks()中如果發生事件進行調用綁定的事件處理函數。
1)用戶自己設計的任務代碼在Zstack中的調用過程
main()執行(在Zmain目錄中ZMain.c)-?osal_init_system()(在OSAL目錄中的OSAL.c 中)-?調用osalInitTasks()(在APP目錄中的OSAL_SerialApp.c)-?調用SerialApp_Init(),(在APP目錄中的SerialApp.c中)。
在osalInitTasks()中實現了多個任務初始化的設置,其中macTaskInit(taskID++)到ZDApp_Init(taskID++)的幾行代碼表示對于幾個系統運行初始化任務的調用,而用戶自己實現的SampleApp_Init()在最后,這里taskID隨著任務的增加也隨之遞增.所以用戶自己實現的任務的初始化操作應該在osalInitTasks()中增加。(在APP目錄中的OSAL_SerialApp.c中增加)。2)任務處理調用的重要數據結構
在Zstack里,對于同一個任務可能有多種事件發生,那么需要執行不同的事件處理,為了方便,對于每個任務的事件處理函數都統一在一個事件處理函數中實現,然后根據任務的ID號(task_id)和該任務的具體事件(events)調用某個任務的事件處理函數,進入了該任務的事件處理函數之后,再根據 events 再來判別是該任務的哪一種事件發生,進而執行相應的事件處理。
pTaskEventHandlerFn 是一個指向函數(事件處理函數)的指針,這里實現的每一個數組元素各對應于一個任務的事件處理函數,比如SampleApp_ProcessEvent對于用戶自行實現的事件處理函數 uint16 SampleApp_ProcessEvent(uint8 task_id,uint16 events),所以這里如果我們實現了一個任務,還需要把實現的該任務的事件處理函數在這里添加。
注意,tasksEvents(在APP目錄中的OSAL_SerialApp.c的osalInitTasks(void)函數中)和tasksArr[](在APP中的OSAL_SerialApp.c中)里的順序是一一對應的,tasksArr[]中的第i個事件處理函數對應于tasksEvents中的第i個任務的事件。
3)對于不同事件發生后的任務處理函數的調用
osal_start_system()很重要,決定了當某個任務的事件發生后調用對應的事件處理函數(在Zmain目錄中ZMain.c)。
10.Z-stack 添加一個新的任務
在osalInitTasks()和tasksArr[]添加相應的項就可以了。osalInitTasks()為初始化系統的任務,tasksArr[ ]為任務處理事件矩陣。在 osalInitTasks()和 tasksArr[]添加相應的項就可以。
1)修改 osalInitTasks()void osalInitTasks(void){ ……
OuhsApp_Init(taskID++);PhotoApp_Init(taskID);} 2)修改 tasksArr[] const pTaskEventHandlerFn tasksArr[] = { ……
OuhsApp_ProcessEvent PhotoApp_ProcessEvent };3)添加_Init()和_ProcessEvent()void PhotoApp_Init(uint8 task_id){ PhotoApp_TaskID=task_id;PhotoInit();RegisterForPhoto(PhotoApp_TaskID);} uint16 PhotoApp_ProcessEvent(uint8 task_id uint16 events){ afIncomingMSGPacket_t *MSGpkt;if(events &SYS_EVENT_MSG){ MSGpkt =(afIncomingMSGPacket_t *)osal_msg_receive(PhotoApp_TaskID);while(MSGpkt){ switch(MSGpkt->hdr.event){ case PHOTO_CHANGE: HalLedblink(HAL_LED_1 3 30 300);//P0IE=1;break;} // Release the memory osal_msg_deallocate((uint8 *)MSGpkt);// Next0 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 */
afMSGCommandFormat_t cmd;/* Application Data */ } afIncomingMSGPacket_t;typedef struct {uint8 event;
uint8 status;} osal_event_hdr_t;typedef struct {
byte
TransSeqNumber;
uint16 DataLength;
// Number of bytes in TransData
byte *Data;} afMSGCommandFormat_t;
第三篇:Zigbee讀書日記(七)
原文鏈接:
Zigbee讀書日記
(七)--基于Contiki的開源Zigbee-freakz研究(前言)
此系列筆記已經很長時間沒更新了,主要是在忙著2530開發板的事情,項目規劃、例程、文檔甚至元件采購,實在有太多事情要忙了。還好,不是一個人在戰斗~~這兩天因為有些工作要等手樣出來才能繼續,所以就空出一點時間,想把開源Zigbee的項目先啟動起來。
本來是沒時間寫這個貼的,但是想把自己最近做的事情跟大家做個交代,同時也希望能尋找些有共同愛好的朋友能一起來做這個事情。廢話不說了,先說說我的想法,我想論壇會按照開源操作系統+開源Zigbee,然后擴展到TCP/IP這個方向去走。之前選擇的平臺是msstatePAN,但是最近一段時間的了解,雖然msstatePAN可以直接支持CC2430,用起來相對會容易些。但畢竟這個協議還很初級,很多功能沒有完成。程序寫得也不是太規范,而且作者最近幾年都沒有更新了。而freakz這個協議,用的是開源的contiki操作系統,其擴展性會好很多,因為在contiki基礎上,已經有很多不錯的應用了,甚至是開源的IPV6。而且針對Zigbee來說,其協議雖然離產品化還有距離,但是要完整很多,唯一的缺點就是硬件還不支持TI系列。
我們能不能自己去做這部分工作呢?我相信有TI詳細的技術資料支持跟幾個開源的MAC層代碼,應該是可以的。這就是我接下來一段時間準備要做的事情,希望能在2530開發板的手樣出來(大概到下個周末)前,能做出個大概,如果有網友有興趣,非常渴望您的加入!
第四篇:zigbee入網退網機制分析
Zstack入網退網代碼分析
網絡初始化和路由:
網絡初始化:
協調器(Coordinator)首先在某個頻段發起一個網絡,網絡頻段的定義放在DEFAULT_CHANLIST配置文件里。如果ZDAPP_CONFIG_PANID定義的PAN ID是0xFFFF(代表所有的PAN ID),則協調器根據它的IEEE地址隨機確定一個PAN ID。否則,根據ZDAPP_CONFIG_PANID的定義建立PAN ID。當節點為Router或者End Device時,設備將會試圖加入DEFAULT_ CHANLIST所指定的工作頻段。如果ZDAPP_CONFIG_PANID沒有設為0xFFFF,則Router或者End Device會加入ZDAPP_CONFIG_PANID所定義的PAN ID。設備上電之后會自動的形成或加入網絡,如果想設備上電之后不馬上加入網絡或者在加入網絡之前先處理其他事件,可以通過定義HOLD_AUTO_START來實現。通過調用ZDOInitDevice(int startdelay)來手動定義多久時間(startdelay)之后開始加入網絡。
設備如果成功的加入網絡,會將網絡信息存儲在非易失性存儲器(NV Flash)里,掉電后仍然保存,這樣當再次上電后,設備會自動讀取網絡信息,這樣設備對網絡就有一定的記憶功能。
如果需要使用NV Flash的設置,可以通過定義NV_RESTORE宏和關閉SW_BYPASS_NV來使用。
有關網絡參數的設置大多保存在協議棧Tools文件夾的f8wConfig.cfg里。路由:
Z-Stack采用無線自組網按需平面距離矢量路由協議AODV,建立一個Hoc網絡,支持移動節點,鏈接失敗和數據丟失,能夠自組織和自修復。當一個Router接受到一個信息包之后,NMK層將會進行以下的工作:首先確認目的地,如果目的地就是這個Router的鄰居,信息包將會直接傳輸給目的設備;否則,Router將會確認和目的地址相應的路由表條目,如果對于目的地址能找到有效的路由表條目,信息包將會被傳遞到該條目中所存儲的下一個hop地址;如果找不到有效的路由表條目,路由探測功能將會被啟動,信息包將會被緩存直到發現一個新的路由信息。
ZigBee End Device不會執行任何路由函數,它只是簡單的將信息傳送給前面的可以執行路由功能的父設備。因此,如果End Device想發送信息給另外一個End Device,在發送信息之間將會啟動路由探測功能,找到相應的父路由節點。初始化流程圖:
ZStack代碼中的設備初始化流程圖如下:
其中根據宏的設置可以達到擴展panID的效果,并且所有設備類型都集中處理。
退網: 協調器和路由器上層使用ZDP_MgmtLeaveReq()進行設備退網申請,會通過ZDO的Mgmt消息處理函數ZDO_ProcessMgmtLeaveReq()來調用NLME_LeaveReq()函數,實現退網申請,主要用來申請給其他設備退網。
當前設備直接使用NLME_LeaveReq()來進行退網申請,并且注意LeaveReq的addr必須為NULL!當前設備申請后,會在網絡層發送一個LeaveInd給協調器(路由器),協調器根據LeaveInd執行結果返回LeaveRsp。
因此協調器可以通過ZDO_RegisterZDOCB的函數來注冊LeaveInd后處理,比如刪除自制表項等等。
尋址:
為了在網絡中發送數據到一個設備,應用層一般用AF_DataRequest()函數。typedef enum { afAddrNotPresent = AddrNotPresent, afAddr16Bit = Addr16Bit, afAddr64Bit = Addr64Bit, afAddrGroup = AddrGroup, afAddrBroadcast = AddrBroadcast } afAddrMode_t;
地址模式參數是需要的,因為在ZB中,數據包能被點傳輸、多點傳輸或者廣播傳輸。點傳輸被發送到單個設備,多點傳輸一定發送到一組設備,廣播傳輸一般被發送到網絡中的所有設備。如下是更詳細的說明。
點到傳輸(Unicast):這是標準地址模式,被用于發送一個數據包到網絡中單個已知地址的設備。這個addrMode參數被設置為Addr16Bit或者Addr64Bit,目的網絡地址在數據包中一同被發送。其中一個是64位IEEE地址(也可以叫MAC地址或擴展地址),一個是16位網絡地址(也可以叫邏輯地址或短地址)。64位地址是全球唯一的,作為設備(產品)的終生地址被分配。它通常被開發商或安裝的時候被指定。該地址由IEEE分配指定。16位地址在設備加入網絡的時候被分配,由這個網絡自動分配。該地址只能用與本網絡中,標志不同的設備間傳遞信息。
間接尋址:數據包中的最終目的地址不識別的時候使用。該模式被AddrNotPresent設置,而且目的地址沒有被指定。代替目的地址的是:一個存儲在發送設備協議棧的“綁定表格”,該表格中有被綁定設備的地址。這個特性被調用是源于綁定。當被發送的信息包下載到協議棧時,從這個綁定表格中尋找使用的目的地址。然后該信息包被有規則的處理為點對點數據包。如果有多個(大于1)目的地址在綁定表格中被發現,那么該數據包將被拷貝成對應的份數分別發送給他們。
廣播傳輸:該模式在應用層想發送一個數據包到所有網絡中的所有設備時被使用。該地址模式被AddrBroadcast被設置,目的地址被設置為下列值之一: NWK_BROADCAST_SHORTADDR_DEVALL(0xFFFF)-信息將被發送到網絡中的所有設備(包括休眠的設備)。對于休眠的設備,這個信息將被保持在它的父節點,直到該休眠設備獲得該信息或者該信息時間溢出(在f8wConfig.cfg 中的NWK_INDIRECT_MSG_TIMEOUT選項)。
NWK_BROADCAST_SHORTADDR_DEVRXON(0xFFFD)–該信息將被發送到網絡中有接收器并處于IDLE(RXONWHENIDLE)狀態下的所有設備。也就是說,除了休眠模式設備的所有設備。NWK_BROADCAST_SHORTADDR_DEVZCZR(0xFFFC)–該信息被發送到所有路由器(包括協調器)。
組地址:該模式用于應用層想發送一個數據包到一個設備組的時候。該地址模式被afAddrGroup設置這個組標志符。用該特性之前,在網絡中,組不得不被定義[看ZStack API文檔中的] aps_AddGroup()注意:組能與間接尋址一起結合使用。該目的地址在綁定表格中發現,可以作為點對點或一個組地址。也要注意廣播地址可以當作是組被提前設置,一個簡單的組尋址的特例。例子代碼對于一個設備添加它自己到一個組標志符1: aps_Group_t group;// Assign yourself to group 1 group.ID = 0x0001;group.name[0] = 0;// This could be a human readable string aps_AddGroup(SAMPLEAPP_ENDPOINT, &group);
一個應用可以能想知道它自身和父節點的地址,用下面的函數可以得到設備的地址(被定義在ZStack API文檔中):
NLME_GetShortAddr()– 返回該設備的 16 位網絡地址 NLME_GetExtAddr()–返回該設備的64 位擴展地址.用下面的函數可以得到該設備的父節點的地址(被定義在ZStack API文檔中)。注意該函數在協調器中不被涉及到,但是被設備父節點代替(MAC協調器): NLME_GetCoordShortAddr()– returns this device’s parent’s 16 bit short address.NLME_GetCoordExtAddr()– returns this device’s parent’s 64 bit extended address.
第五篇:Zigbee基礎實驗(6)—簡單通信編程
Zigbee基礎實驗(6)—簡單通信編程
2011-07-25 20:06:19|分類: |字號 訂閱
實驗中兩節點分別充當開關和電燈,通過在開關節點上的操作來控制電燈節點。
源代碼: #include
#include “basic_rf.h”
#define RF_CHANNEL25// 信道選擇。
// 定義各個參數的值
#define PAN_ID0x2007//網絡ID
#define SWITCH_ADDR0x2520//開關節點的地址
#define LIGHT_ADDR0xBEEF//電燈節點的地址
#define APP_PAYLOAD_LENGTH1//負載字節的長度,信息的長度。#define LIGHT_TOGGLE_CMD0//被傳送的開關命令。
//節點狀態。0為空閑
#define IDLE0
#define SEND_CMD1
// 定義該節點所承擔的任務(開關或電燈)
#define NONE0
#define SWITCH1
#define LIGHT2
#define APP_MODES2
static uint8 pTxData[APP_PAYLOAD_LENGTH];//發送數組
static uint8 pRxData[APP_PAYLOAD_LENGTH];//接收數組
static basicRfCfg_t basicRfConfig;
// 模式選擇菜單 static menuItem_t pMenuItems[] = {
“Switch”,SWITCH,“Light”,LIGHT
};static menu_t pMenu = {
pMenuItems,N_ITEMS(pMenuItems)
};
static void appLight();//實現電燈功能
static void appSwitch();//實現遠程開關功能
static uint8 appSelectMode(void);//功能選擇
static void appLight()//實現電燈功能 {
halLcdWriteLine(HAL_LCD_LINE_1, “Light”);
halLcdWriteLine(HAL_LCD_LINE_2, “Ready”);
// 初始化射頻模塊
basicRfConfig.myAddr = LIGHT_ADDR;//網絡地址
if(basicRfInit(&basicRfConfig)==FAILED){
HAL_ASSERT(FALSE);//初始化錯誤處理
}
basicRfReceiveOn();//打開接收功能。
//死循環
while(TRUE){
while(!basicRfPacketIsReady());
if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)>0){//如果接收到數據
if(pRxData[0] == LIGHT_TOGGLE_CMD){
halLedToggle(1);//開關改變狀態
}
}
}
}
static void appSwitch()//實現遠程開關 {
halLcdWriteLine(HAL_LCD_LINE_1, “Switch”);//屏幕輸出
halLcdWriteLine(HAL_LCD_LINE_2, “Joystick Push”);
halLcdWriteLine(HAL_LCD_LINE_3, “Send Command”);
pTxData[0] = LIGHT_TOGGLE_CMD;//需要發送的數據
// 初始化
basicRfConfig.myAddr = SWITCH_ADDR;
if(basicRfInit(&basicRfConfig)==FAILED){
HAL_ASSERT(FALSE);//出錯處理
}
basicRfReceiveOff();//關閉接收機
// 死循環
while(TRUE){
if(halJoystickPushed()){//當按鍵按下時觸發
basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH);//發送命令
}
}
}void main(void)
{
uint8 appMode = NONE;//模式變量
// 設置網絡ID和信道
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.ackRequest = TRUE;
//初始化其他設備
halBoardInit();
halJoystickInit();
// 初始化射頻模塊
if(halRfInit()==FAILED){
HAL_ASSERT(FALSE);
}
halLedSet(1);//LED1燈亮,提示節點已上電
utilPrintLogo(“Light Switch”);
// 等待用戶按下S1進入菜單
while(halButtonPushed()!=HAL_BUTTON_1);
halMcuWaitMs(350);//延時
halLcdClear();//清屏
// 設置該節點是開關還是電燈
appMode = appSelectMode();
halLcdClear();
// 模塊開始工作
if(appMode == SWITCH){
appSwitch();
}
else if(appMode == LIGHT){
appLight();
}
//如果沒有定義該節點的功能,則LED燈不斷閃爍
HAL_ASSERT(FALSE);
}
static uint8 appSelectMode(void)//模式選擇 {
halLcdWriteLine(1, “Device Mode: ”);
return utilMenuSelect(&pMenu);//通過調用頭文件實現功能選擇
}
實驗總結:
這個實驗雖然功能非常簡單,只是通過按下開關節點的按鍵來控制電燈節點LED的亮或滅,但是通過這個實驗可以了解節點間通信的基本思路。
原代碼中有許多可有可無的冗余代碼,上面的代碼經過代碼中很多都是調用頭文件,在這里就不在一一羅列,只在代碼注釋中注明該調用的功能。這些調用都是一些非常簡單的操作,寫入頭文件調用是為了增加代碼可讀性。
baseRF通信基本流程
1.初始化網絡地址,打開接收機或關閉接收機。
2.初始化basicRfConfig,確定網絡ID、信道、是否需要應答、是否采用加密機制等。
3.初始化周邊設備,如時鐘、各個I/O口等。
4.事件的處理,如發送報文或接受報文后的數據處理等。