Zigbee通信

这篇文章就是将末尾的PPT重新复制到了文章之中,别问,问就是懒

0x01无线通信

1.无线通信理论

  • Zigbee无线通信,需要高频的载波来提供发射频率,Zigbee模块之间要可以正常通信,接收模块和发送模块的频率要一致。

  • Zigbee有27个载波可以进行通信,载波又叫做信道。这些载波的频率落在某些频率区段,我们把这些区段叫做频段。

    2.4G频段 16个信道

    915M频段 896M频段 11个信道

    但TI的所有支持Zigbee底层协议的芯片只能在2.4G频段的16个信道里进行通信。即1126信道(010信道在915M和896M的频段内)

  • 网络地址

    • 在Zigbee无线局域网里,每一个模块都有一个在该网络里唯一的2个字节的地址,这个地址我们叫做网络地址(或者叫做网络短地址)。
  • PANID

    • 这也是一个2个字节的编号,用来区分不用的Zigbee无线局域网,我们称为个域网ID。两个模块之间要进行通信,PANID一定要一样。
  • 信道与PANID的设置

    • 在Tools文件组里的f8wConfig.cfg文件中

    • (1)设置信道

      -DDEFAULT_CHANLIST=0x00000800 // 11 - 0x0B

    • (2)设置PANID

      -DZDAPP_CONFIG_PAN_ID=0x1234

      注意:如果把PANID设置为0xFFFF,则意味着该模块不受PANID的限制

2.网络组建理论

  • 在Zigbee无线局域网里,节点(无线模块)按照在网络里的功能可以划分为:协调器、路由器、终端这三种角色

  • 它们的硬件可以是一模一样的,之所以在网络里表现出不同的功能,是因为它们下载了不同功能版本的程序,在同一个网络里担当了不同的角色功能。

    image-20210531092938956

  • 下载了路由器和终端代码的模块,它们上电后的第一件事情去寻找网络,请求加入。然而网络不会无缘无故产生,是由下载了协调器代码的模块创建的。

  • 下载了协调器代码的模块上电后的第一件事就是创建网络。

  • 任何一个网络里,第一个节点一定是该网络的协调器,有且只能有一个协调器

  • 任何一个Zigbee模块要加入到某个网络,一定要一个处于该网络里的节点作为介绍人,并且这个介绍人不能是终端节点(即路由器或者协调器)。在加入网络以后,介绍人节点和被介绍加入的节点互为父子关系。

  • 介绍人是被介绍人的父节点,被介绍人是介绍人的、子节点。有多个可作为介绍人资格的节点,会选择信号强度高的节点作为介绍人。

  • 协调器在创建完网络后,在网络里的功能与路由器没有任何区别,只不过协调器的网络地址比较特殊只能是0x0000,而其他加入的节点的网络地址是动态分配的。

  • 终端节点与其他模块的通信必须要通过它的父节点,而路由器(协调器)之间通信可以直接通信的。

  • 因此,路由器在网络里充当的是拓扑扩展的中转站的功能

  • 综合

    • 我们可以在GenericApp.c文件中的GenericApp_ProcessEvent函数中的switch语句的 case ZDO_STATE_CHANGE中修改代码内容,让模块在不同的网络状态下亮不同的灯。
    • 注意:下载了协调器的代码的模块,创建了网络之后就是协调器状态,而终端和路由器要加入了网络才是对应的状态。终端和路由器要加入网络的条件是,信道和PANID要一致。

3.三种网络架构

  1. 星形拓扑

    • 星形拓扑是最简单的一种拓扑形式,他包含一个Co-ordinator(协调者) 节点和一系列的 End Device(终端)节点。每一个End Device 节点只能和 Co-ordinator 节点进行通讯。如果需要在两个 End Device 节点之间进行通讯必须通过Co-ordinator 节点进行信息的转发。

      image-20210531093356279

  2. 树形拓扑

    • 树形拓扑包括一个Co-ordinator(协调者)以及一系列的 Router(路由器) 和 End Device(终端)节点。Co-ordinator 连接一系列的 Router 和 End Device, 他的子节点的 Router也可以连接一系列的 Router 和End Device. 这样可以重复多个层级。

      image-20210531093438391

  3. Mesh拓扑(网状拓扑)

    • 包含一个Co-ordinator和一系列的Router 和End Device。这种网络拓扑形式和树形拓扑相同;请参考上面所提到的树形网络拓扑。但是,网状网络拓扑具有更加灵活的信息路由规则,在可能的情况下,路由节点之间可以直接的通讯。这种路由机制使得信息的通讯变得更有效率,而且意味这一旦一个路由路径出现了问题,信息可以自动的沿着其他的路由路径进行传输。 网状拓扑的示意图如下所示:

      image-20210531093511344

  4. 架构比较

    • MESH 网状网络拓扑结构的网络具有强大的功能,网络可以通过“多级跳”的方式来通信;该拓扑结构还可以组成极为复杂的网络;网络还具备自组织、自愈功能;

    • 星型和族树型网络适合点多多点、距离相对较近的应用。

    • 代码设置,在“nwk_global.h”文件中进行设置,159行处

      image-20210531093825604

0x02 单播通信

1.单播通信理论

  • Zigbee网络通信方式有4种:单播,广播,组播,绑定(MAC)。

  • 单播通信的特点:在Zigbee网络里,模块之间要进行通信,发射模块要明确知道接收模块的网络地址。

  • Zigbee模块的地址特点:模块在加入网络的时候,父节点随机分配网络地址给子节点。但是协调器模块在网络里的地址永远都是0x00。

  • 单播发送数据需要明确的信息

    • (1)目标地址
    • (2)目标端点与簇
    • (3)要发送的数据大小

2.GenericApp_SendTheMessage()

  • 该函数在GenericApp.c里的GenericApp_SendTheMessage函数里:
1
2
3
4
5
6
7
8
AF_DataRequest(
&GenericApp_DstAddr, //目标的网络地址指针
&GenericApp_epDesc,//端点描述符指针
GENERICAPP_CLUSTERID,//目标簇
(byte)osal_strlen( theMessageData ) + 1,//发送数据的大小
(byte *)&theMessageData,//发送数据缓冲区的地址
&GenericApp_TransID,//这是个全局变量,用来保存发送的次数
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );//发送路径,don't care

3.网络地址结构体

  • 网络地址结构体就是定义在GenericApp.c前面的一个结构体变量,该类型为afAddrType_t,系统已经默认定义了一个网络地址结构体变量GenericApp_DstAddr,我们可以在GenericApp_Init()函数中,对网络地址结构体变量的成员进行赋值。
1
2
3
4
5
6
7
8
9
10
11
12
// 网络地址结构体:
typedef struct
{
union
{
uint16 shortAddr;//网络地址
ZLongAddr_t extAddr; //MAC地址
} addr;
afAddrMode_t addrMode;//通信模式
byte endPoint; //指定的端点
uint16 panId; //don't care
} afAddrType_t;
1
2
3
4
5
6
7
8
9
10
// 通信模式枚举类型:
typedef enum
{
afAddrNotPresent = AddrNotPresent,//当前不确定
afAddr16Bit = Addr16Bit,//单播通信模式
afAddr64Bit = Addr64Bit,//MAC通信模式
afAddrGroup = AddrGroup,//组播通信模式
afAddrBroadcast = AddrBroadcast//广播通信模式
} afAddrMode_t;

4.端点

  • (1)通常发送的数据要明确该数据是给接收模块的哪个任务层用的,而这个就是用端点来指定的

  • (2)端点是一个字节的编号,通常为定义在GenericApp.h中的一个宏。端点必须要与任务层绑定,而这个就是用端点描述符来实现的。

  • (3)端点描述符是一个结构体变量,该变量定义在GenericApp.c开头,我们也可以定义新的端点描述符。该结构体的类型为 endPointDesc_t,系统也默认定义了一个端点描述符GenericApp_epDesc。

  • (4)我们可以在 GenericApp_Init()函数中,把新的端点描述符变量赋值,使新的端点与某个任务层绑定。

1
2
3
4
5
6
7
8
9
// 端点结构体类型:
typedef struct
{
byte endPoint;//端点的值
byte *task_id; //与端点绑定的任务层ID
SimpleDescriptionFormat_t *simpleDesc;//端点的描述信息,don’t care
afNetworkLatencyReq_t latencyReq;//don’t care
} endPointDesc_t;

5.簇

  • (1)在接收模块中,每个任务层可以对不同种类的数据采取不同的处理方式,这里的数据种类就是簇(CLUSTER)

  • (2)在发送模块中,簇是定义在GenericApp.h中的一个宏,我们也可以定义新的簇。

  • (3) 系统也默认定义了一个簇 GenericApp_CLUSTERID,在GenericApp.h中

6.应用任务层数据接收函数

  • (1)该函数为GenericApp.c中的 void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )

  • (2)在switch语句中可以定义对不同的簇采用不同的方式处理数据

  • (3)该函数中的pkt->cmd.Data就是接收数据的首地址

0x03 无线通信代码编写过程

1.设置信道与PANID

在Tools文件组里的f8wConfig.cfg文件中

-DDEFAULT_CHANLIST=0x00000800 // 11 - 0x0B

-DZDAPP_CONFIG_PAN_ID=0x1234

2.设置AF_DataRequest结构体

在GenericApp.c里的GenericApp_SendTheMessage函数

1
2
3
4
5
6
7
8
AF_DataRequest(
&GenericApp_DstAddr, //目标的网络地址指针
&GenericApp_epDesc,//端点描述符指针
GENERICAPP_CLUSTERID,//目标簇
(byte)osal_strlen( theMessageData ) + 1,//发送数据的大小
(byte *)&theMessageData,//发送数据缓冲区的地址
&GenericApp_TransID,//这是个全局变量,用来保存发送的次数
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );//发送路径,don't care

image-20210528162437459

image-20210528164343762

image-20210528164903849