「ZigBee模塊」組網實驗-無線點燈


ZigBee入門小實驗——無線點燈

 

 

寫在前面:無線點燈實驗不涉及協議棧,只是對Basic RF的應用,但是其中關於數據收發的思想和協議棧類似,可以借鑒。這個代碼和實驗過程都是參考某教程的,然后有加上自己的理解......歡迎糾錯(*^__^*) 

 

 

一、設備

兩個ZigBee模塊

一個方口USB線(這個只是供電用,要看自己模塊用什么接口,不一定是方口的,用電池也行)

一個編譯器

 

二、幾個名詞解釋

CCM -Counter with CBC-MAC(mode of operation) 就知道和加密有關,具體不明白...有人能解釋下嗎?

HAL -Hardware Abstraction Layer (硬件抽象層)

PAN -Personal Area Network (個人局域網)

RF -Radio Frequency (射頻)

RSSI -Received Signal Strength Indicator (接收信號強度指示)

 

 

三、關於Basic RF

 

  1. 在介紹Basic RF之前先看一下該實驗例程的大體結構,圖見下方

 

  ①Hardware layer 硬件層

 

  實現數據傳輸的基礎

 

 

 

  ②Hardware Abstraction layer 硬件抽象層

 

  提供接口以訪問TIMERGPIOUARTADC等,這些接口都通過函數實現。

 

 

 

  ③Basic RF

 

  為雙向無線通信提供一種簡單的協議

 

 

 

  ④Application layer 用戶應用層

 

  它相當於一個接口,方便用戶使用Basic RF層和HAL,就是說在Application層就可以使用封裝好的Basic RFHAL函數

 

 

  2. Basic RF layer 簡介

  Basic RF TI公司提供,包含IEEE 802.15.4標准的數據包收發功能但不使用協議棧,僅讓兩個結點進行簡單通信。

  Basic RF layer 為雙向無線通信提供了一個簡單的協議,通過這個協議能夠進行數據的發送和接收

 

 

四、Basic RF 工作過程分析

 

     Basic RF的工作過程分為三個部分:啟動、發射、接收

 

啟動:

 

  1. 確保外圍器件沒有問題

  2. 定義一個新的結構體類型,變量名為basicRfCfg_t,打開basic_rf.h可以找到該結構體。

 

typedef struct {
    uint16 myAddr;             //16位的短地址,就是結點的地址
    uint16 panId;              //結點的PAN ID
    uint8 channel;             //PF通道(必須在11-26之間)
    uint8 ackRequest;          //目標確認就置true
    #ifdef SECURITY_CCM        //是否加密,預定義里取消了加密
    uint8* securityKey;
    uint8* securityNonce;
    #endif
} basicRfCfg_t;

 

  3. 調用basicRfInit()函數進行協議的初始化,在basic_rf.h中可以找到函數聲明

  Unit8 basicRfInit(basicRfCfg_t* pRfConfig);

  函數功能:對basicRfCfg_t進行初始化,設置模塊的傳輸通道,短地址,PAN ID

 

 

發送:

 

  1. 創建一個buffer,把payload放入其中。Payload最大為103個字節

 

  2. 調用basicRfSendPacket()函數發送,並查看其返回值

 

  在basic_rf.h中可以找到函數聲明

 

  uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length);

 

  destAddr  目的短地址

 

  pPayload 指向發送緩沖區的指針

 

  length 發送數據長度

 

  函數功能:給目的短地址發送指定長度的數據,發送成功返回SUCCESS,失敗返回FAILED

 

 

接收:

 

  1. 上層通過basicRfPacketIsReady()函數來檢查是否收到一個新數據包,在basic_rf.h中可以找到函數聲明

 

  uint8 basicRfPacketIsReady(void);

 

  函數功能:檢查模塊是否已經可以接收下一個數據,如果准備好返回TRUE

 

  2. 調用basicRfReceive()函數,把收到的數據復制到buffer中,在basic_rf.h中可以找到該函數聲明

 

  uint8 basicRfReceive(uint8* pRxData, uint8 len, int16* pRssi);

 

  函數功能:接收來自Basic RF層的數據包,並為所接收的數據和RSSI值配緩沖區

 

 

 

  據說只要能看懂啟動、發送、接收就基本上能使用這個無線模塊了......加油~

 

 

五、Light_switch.c 代碼詳解

 

這個代碼其實是對上面那些函數的應用

 

主要分為三個部分:主函數,按鍵函數,點燈函數

 

 

 

先看主函數吧

 1 void main(void)
 2 {
 3     //不設置模塊的模式,代碼本意是通過這個來選擇這個模塊是按鍵還是點燈模塊
 4     //但是因為代碼被改過了,其實這個已經沒有用啦 
 5     uint8 appMode = NONE;               
 6 
 7     // Config basicRF
 8     //這里的basicRfConfig就是之前提到的basicRFCfg_t,只是重新定義了下
 9     //以下是給各成員賦值
10     basicRfConfig.panId = PAN_ID;       //設置panId的值 PAN_ID是自己定義的一個16位地址,程序開頭可以改
11     basicRfConfig.channel = RF_CHANNEL; //通道值,RF_CHANNEL也是自己定義的,開頭可以修改
12     basicRfConfig.ackRequest = TRUE;    //目標確認為TRUE 這個應該不用改吧...
13 #ifdef SECURITY_CCM                     //加密的東西,暫時忽略
14     basicRfConfig.securityKey = key;    //|
15 #endif                                  //|
16 
17     // Initalise board peripherals     
18     //初始化外圍設備
19     halBoardInit();                     //這個我暫時不知道是什么,以后補上,求解答
20     halJoystickInit();                  //游戲搖桿,據說國外用比較多...我確定這個程序不需要這個...
21 
22     // Initalise hal_rf
23     //硬件抽象層的RF進行初始化
24     if(halRfInit()==FAILED) {
25       HAL_ASSERT(FALSE);
26     }
27 
28     // Indicate that device is powered
29     //把兩個燈都打開,表示下通電啦
30     halLedSet(2);      //關閉LED2
31     halLedSet(1);      //打開LED1
32     
33     /************Select one and shield to another***********by boo*/
34     //這個端口怎么改? hal_board.h里面的
35     //HAL_BOARD_IO_BTN_1_PORT 和 HAL_BOARD_IO_BTN_1_PIN 改按鍵端口
36     //HAL_BOARD_IO_LED_1_PORT 和 HAL_BOARD_IO_LED_1_PIN 改燈的端口
37     //問我怎么找出來的?一直go 頭 definition吧~ 笑...
38     appSwitch();          //節點為按鍵S1      P0_0 
39     //appLight();         //節點為指示燈LED1   P1_0
40     
41     // Role is undefined. This code should not be reached
42     HAL_ASSERT(FALSE);
43 }

主函數其實就三步

①啟動(初始化)Basic RF

②初始化其余外圍設備(按鍵、燈之類的)

③選擇是按鍵還是燈的函數(手動選擇啦,就是把另一行函數注釋掉!)

 

然后看下按鍵函數:

 1 static void appSwitch()
 2 {
 3     halLcdWriteLine(HAL_LCD_LINE_1, "    W e B e e      ");//液晶
 4     halLcdWriteLine(HAL_LCD_LINE_2, "  ZigBee CC2530  ");  //屏顯
 5     halLcdWriteLine(HAL_LCD_LINE_4, "     SWITCH    ");    //示的
 6                                                            //內容
 7 #ifdef ASSY_EXP4618_CC2420                                 //
 8     halLcdClearLine(1);                                    //忽略
 9     halLcdWriteSymbol(HAL_LCD_SYMBOL_TX, 1);               //
10 #endif                                                     //!
11 
12 
13     // Initialize BasicRF
14     //初始化Basic RF 為什么又初始化??
15     //其實就是剛才main函數里部分沒初始化的繼續初始化下
16     //因為點燈和按鍵的部分要求不一樣,應該是這樣的...
17     basicRfConfig.myAddr = SWITCH_ADDR;        //確實,點燈和按鍵設置的地址怎么能一樣?!
18     if(basicRfInit(&basicRfConfig)==FAILED) {
19       HAL_ASSERT(FALSE);
20     }
21     
22     //把要發送的數據寫到buffer里面去,這里buffer就1位
23     //LIGHT_TOGGLE_CMD是自己在上面定義的,0
24     pTxData[0] = LIGHT_TOGGLE_CMD;             
25 
26     // Keep Receiver off when not needed to save power
27     //把模塊的接收部分關掉,可以省點電!
28     basicRfReceiveOff();
29 
30     // Main loop
31     //以上都算是設初值吧,這里進去就出不來啦,死循環!
32     while (TRUE) {
33         //if( halJoystickPushed() )**********************by boo
34       if(halButtonPushed()==HAL_BUTTON_1)//**************by boo檢查按鍵S1是否按下!
35         {
36             //按下就發送數據(發給誰, 發的數據, 數據長度)
37             //這個應該很重要吧!
38             basicRfSendPacket(LIGHT_ADDR, pTxData, APP_PAYLOAD_LENGTH); 
39 
40             // Put MCU to sleep. It will wake up on joystick interrupt
41             //搖桿,忽略!!!
42             halIntOff();
43             halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global            
44             // interrupt enable
45             halIntOn();
46 
47         }
48     }
49 }

按鍵也是三步......

①初始化Basic RF的地址部分

②初始化條件觸發后要發送的數據,就是把要發送的數據先准備好,等要發送了就直接發出去就可以了,不需要重復賦值啦

③循環檢查按鍵是否按下,按下就發數據出去

 

最后還剩點燈啦,這個和按鍵差不多的呢

 1 static void appLight()
 2 {
 3 
 4     halLcdWriteLine(HAL_LCD_LINE_1, "    W e B e e      "); //顯示屏,忽略
 5     halLcdWriteLine(HAL_LCD_LINE_2, "  ZigBee CC2530  ");   //|
 6     halLcdWriteLine(HAL_LCD_LINE_4, "     LIGHT     ");     //|
 7                                                             //|
 8 #ifdef ASSY_EXP4618_CC2420                                  //|
 9     halLcdClearLine(1);                                     //|
10     halLcdWriteSymbol(HAL_LCD_SYMBOL_RX, 1);                //|
11 #endif                                                      //|
12 
13     // Initialize BasicRF
14     //Basic RF設置地址
15     basicRfConfig.myAddr = LIGHT_ADDR;
16     if(basicRfInit(&basicRfConfig)==FAILED) {
17       HAL_ASSERT(FALSE);
18     }
19     basicRfReceiveOn();    //打開無線接收功能
20 
21     // Main loop
22     //死循環
23     while (TRUE) {
24         while(!basicRfPacketIsReady());      //接收到東西了再繼續,不然循環
25 
26         if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)>0) {  //判斷是否有接收到有效數據
27             if(pRxData[0] == LIGHT_TOGGLE_CMD) {                   //如果接收到剛才發的信號
28                 halLedToggle(1);                                   //改變燈的狀態(開變關,關變開)
29             }
30         }
31     }
32 }

點燈也是三步,和按鍵差不多啦~

①初始化Basic RF的地址部分

②打開無線接收功能

③循環,收到東西就改變燈狀態

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM