ZIGBEE通过协议栈点对点通信流程

笔记 整理 同时被 2 个专栏收录
6 篇文章 0 订阅
5 篇文章 0 订阅

通过ZigBee2007 的协议栈 Z-Stack-CC2530-2.3.0。

一.实现一个无线数据通信时的一般步骤

1、组网:调用协议栈的组网函数、加入网络函数,实现网络的建立与节点的加入。

2、发送:发送节点调用协议栈的无线数据发送函数,实现无线数据发送。

3、接收:接收节点调用协议栈的无线数据接收函数,实现无线数据接收。 看起来是不是很简单呢,是不是有动手试试的冲动。具体的例程讲解在这里就不说先了,在接下来的教程里面会详细地和大家一起讨论 ZigBee 协议栈架构中每个层所包含的内容和功能及 Z-stack 的软件架构。

 

二:关键字

CCM  - Counter with CBC-MAC (mode of operation) 

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

PAN   - Personal Area Network          (个人局域网)

RF      - Radio Frequency                (射频)

RSSI  - Received Signal Strength Indicator   (接收信号强度指示)

 

三:协议的结构

-Hardware layer

放在最底,实现数据传输的基础。

-Hardware Abstraction layer

提供了一种接口来访问 TIMER,GPIO,UART,ADC 等。这些接口都通过相应的函数进行实现。

-Basic RF layer

为双向无线传输提供一种简单的协议。

-Application layer

用户应用层,它相当于用户使用 Basic RF 层和 HAL 的接口,也就是说我们通过在 Application layer 就可以使用到封装好的 Basic RF 和 HAL 的函数。

 

四:Basic RF layer 简介:

Basic RF 由 TI 公司提供,它包含了 IEEE 802.15.4 标准的数据包的收发功能但并没有使用到协议栈,它仅仅是是让两个结点进行简单的通信,也就是说Basic RF 仅仅是包含着 IEEE 802.15.4 标准的一小部分而已。其主要特点有:

1、不会自动加入协议、也不会自动扫描其他节点也没有组网指示灯(LED3)。

2、没有协议栈里面所说的协调器、路由器或者终端的区分,节点的地位都 是相等的。

3、没有自动重发的功能。

-要理解掌握 Basic RF ,通过这个协议能够进行数据的发送和接收。

 

五:Basic RF 的工作过程:启动、发射、接收 。

1、启动 :



/*1、创建一个 basicRfCfg_t 的数据结构,并初始化其中的成员,在 basic_rf.h 代码中可以找到  */
 typedef struct {   
uint16 myAddr;               //16 位的短地址(就是节点的地址)   
uint16 panId;                //节点的 PAN ID   
uint8 channel;               //RF 通道(必须在 11-26 之间)   
uint8 ackRequest;            //目标确认就置 true   
#ifdef SECURITY_CCM          //是否加密,预定义里取消了加密   
uint8* securityKey;       
uint8* securityNonce; 
       #endif 
    } basicRfCfg_t; 


/*2.调用 basicRfInit()函数进行协议的初始化,在 basic_rf.c 代码中可以找到 */

   uint8 basicRfInit(basicRfCfg_t* pRfConfig) ;

/*函数功能:对 Basic RF 的数据结构初始化,设置模块的传输通道,短地址,PAD ID。*/

2、发送

/*
1. 创建一个 buffer,把 payload 放入其中。Payload 最大为 103 个字节.

2. 调用 basicRfSendPacket()函数发送,并查看其返回值 。
在 basic_rf.c 中可以找到 :
*/

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

/*
destAddr 目的短地址 
pPayload 指向发送缓冲区的指针 
length 发送数据长度 
函数功能:给目的短地址发送指定长度的数据,发送成功刚返回 SUCCESS, 失败则返回 FAILED 
*/

3、接收

/*
1、 上层通过 basicRfPacketIsReady()函数来检查是否收到一个 新数据包 。
在 basic_rf.c 中可以找到 :
*/

uint8 basicRfPacketIsReady(void);

//函数功能:检查模块是否已经可以接收下一个数据,如果准备好刚返回 TRUE 。

/*
2、  调用 basicRfReceive()函数,把收到的数据复制到 buffer 中。
代码可以在 basic_rf.c 中可以找到 :
*/

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

//函数功能:接收来自 Basic RF 层的数据包,并为所接收的数据和 RSSI 值 配缓冲区。

使用 Basic RF 实现无线传输只要学会使用这些函数就可以了。

 

六:例程讲解

light_switch.c 代码详解:

无论你看哪个实验的代码,首先要找的就是 main 函数。从 main 函数开始:

(部分已经屏蔽的代码并未贴出,详细的代码请看打开工程)

1. void main(void) 
2. { 
3.   uint8 appMode = NONE;                   //不设置模块的模式 
4.  // Config basicRF 
     basicRfConfig.panId = PAN_ID;           //上面讲的 Basic RF 的启动中的 
5.   basicRfConfig.channel = RF_CHANNEL;     //初始化 basicRfCfg_t  
6.   basicRfConfig.ackRequest = TRUE;        //结构体的成员。
7.  
8.   #ifdef SECURITY_CCM                     //密钥安全通信,本例程不加密 
9.   basicRfConfig.securityKey = key; 
10.   #endif 
11.  
12.   // Initalise board peripherals         初始化外围设备 
13.   halBoardInit(); 
14.   halJoystickInit(); 
15.  
16.   // Initalise hal_rf  硬件抽象层的 rf 进行初始化 
17.   if(halRfInit()= =FAILED)  
18.   { 
19.     HAL_ASSERT(FALSE); 
20.   } 
21.   /***********根据 WeBee 学习底板配置**********/ 
22.   halLedClear(2);                       // 关 LED2 
23.   halLedClear(1);                       // 关 LED1 
24.  
25.  /******选择性下载程序,发送模块和接收模块******/ 
26.   appSwitch();                          //节点为按键 S1        P0_0 
27.   appLight();                           //节点为指示灯 LED1    P1_0 
28.   // Role is undefined. This code should not be reached 
29.   HAL_ASSERT(FALSE); 
30. } 

/*第 22~23 行:关闭 WeBee 底板的 LED2 和 LED1。halLedSet(x)置 1 是使灯 点亮,halLedClear(x)是使灯熄灭。 第 26~27 行:选择其中的一行,并把另外一行屏蔽掉;这两行重要啦,一个是实现发射按键信息的功能,另一个是接收按键信息并改变 LED 状态的功能。分别为 Basic RF 发射和接收。不同模块在 烧写程序时选择不同功能。 
注意:程序会在 appSwitch();  或者 appLight();里面循环或者等待,不会执行到第 29 行。 
*/

//接下来看看 appSwitch()函数,它是如何实现数据发送的呢? 
 
1. static void appSwitch() 
2. { 
3.   #ifdef ASSY_EXP4618_CC2420               //液晶模块的定义,我们不用管他 
4.   halLcdClearLine(1); 
5.   halLcdWriteSymbol(HAL_LCD_SYMBOL_TX, 1); 
6.   #endif 
7.   // Initialize BasicRF                   8~11 Basic RF 启动中的初始化
8.   basicRfConfig.myAddr = SWITCH_ADDR; 
9.   if(basicRfInit(&basicRfConfig)==FAILED){ 
10.   HAL_ASSERT(FALSE); 
11.   } 

12.   pTxData[0] = LIGHT_TOGGLE_CMD; 
13.   /* Basic RF 发射第 1 步,把要发射的数据或者命令放入一个数据 buffer,
      此处把灯状态改变的命令 LIGHT_TOGGLE_CMD 放到 pTxData 中。*/

14.   basicRfReceiveOff();                    //接收屏蔽掉以降低功耗

15.   // Main loop                              程序进入死循环 
16.   while (TRUE)  
17.   { 
          /*halButtonPushed()是 halButton.c 里面的,它的功能是:按键 S1
          有被按动时,就回返回true */
18.     if(halButtonPushed()==HAL_BUTTON_1)    //判断按键 S1 被按下 

19.     { 
20.     basicRfSendPacket(LIGHT_ADDR,pTxData,APP_PAYLOAD_LENGTH); 
21.     //Basic RF 发射第 2 步,发送数据

22.     halIntOff(); 
23.     halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global 

24.     // interrupt enable                     使能中断 
25.     halIntOn(); 
26.     } 
27.    }
28. } 
 
 
//发送的 appSwitch()讲解完毕,接下来就到我们的接收 appLight()函数了 
1. static void appLight() 
2. { 
3.  /************************************************* 
4.    halLcdWriteLine(HAL_LCD_LINE_1, “Light”); 
5.    halLcdWriteLine(HAL_LCD_LINE_2, “Ready”); 
6.  ***************************************************/   

7.   #ifdef ASSY_EXP4618_CC2420                     // LCD 内容
8.   halLcdClearLine(1); 
9.   halLcdWriteSymbol(HAL_LCD_SYMBOL_RX, 1); 
10.   #endif 

11.   // Initialize BasicRF                         Basic RF 启动中的初始化
12.   basicRfConfig.myAddr = LIGHT_ADDR; 
13.   if(basicRfInit(&basicRfConfig)==FAILED) { 
14.   HAL_ASSERT(FALSE); 
15.   } 

/*开启无线接收功能,调用这个函数后模块一直会接收,除非再调用 basicRfReceiveOff()使它关闭接收*/
16.   basicRfReceiveOn(); 

17.   // Main loop                                  程序开始进行不断扫描的循环 
18.   while (TRUE) 
19.    {
20.      while(!basicRfPacketIsReady());           //检查是否接收上层数据
21.      if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)>0) { //判断否接收到有数据 
22.      if(pRxData[0] == LIGHT_TOGGLE_CMD)  
23.      { 
24.       halLedToggle(1);                         //改变 Led1 的状态
25.       } 
26.     } 
27.   } 
28. } 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 5
    点赞
  • 0
    评论
  • 14
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值