• 「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的地址部分

    ②打开无线接收功能

    ③循环,收到东西就改变灯状态

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    算法笔记--贪心
    算法笔记--递归
    算法笔记--哈希
    算法笔记--散列
    算法笔记--排序算法
    算法笔记--简单编程训练
    算法笔记--简单模拟
    算法笔记--注意事项
    3.4 空间滤波
    【解题报告】【概率DP入门】 P1850 换教室
  • 原文地址:https://www.cnblogs.com/Donut/p/4132324.html
Copyright © 2020-2023  润新知