一、zigbee四种通讯
1、单播:在Zigbee网络里,模块之间进行通信,发送模块非常明确知道接收模块的网络地址,以这个地址发送数据给接收模块,叫做单播。
2、广播(略)
3、组播(略)
4、绑定(略)
PS:zigbee模块的网络地址的特点:当模块入网时,父节点随机分配网络地址给子节点;协调器作为网络中的第一个节点,它的网络地址固定是0x0000。
二、单播字符收发实验
本次做的实验是一共两个模块,协调器作为接收方,终端作为发送方。实现终端按键1按下,发送数据包;协调器收到数据包后,LED亮灭翻转,将数据包中的有效数据发送给电脑上位机。
本次实验的代码是在zigbee笔记:十一 实验基础上完成的。
1、发送端(终端)代码配置
实现效果:按下按钮KEY1,将数据发送出去。
1)首先在smartHomeApp.c中找到smartHomeApp_ProcessZDOMsgs函数。
选择如下代码,提取出来。
smartHomeApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
smartHomeApp_DstAddr.addr.shortAddr = pRsp->nwkAddr;
smartHomeApp_DstAddr.endPoint = pRsp->epList[0];
/*
smartHomeApp_DstAddr.addr.shortAddr = pRsp->nwkAddr中的
pRsp->nwkAddr表示接收方地址,改为0x0000,作为我们的协调器地址(接收方);
*/
smartHomeApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
smartHomeApp_DstAddr.addr.shortAddr = 0x000;
smartHomeApp_DstAddr.endPoint = pRsp->epList[0];
2)然后在smartHomeApp_Init找到smartHomeApp_ENDPOINT,将其提取出来。
将smartHomeApp_DstAddr.endPoint = pRsp->epList[0]中的pRsp->epList[0]替换为smartHomeApp_ENDPOINT。
smartHomeApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
smartHomeApp_DstAddr.addr.shortAddr = 0x000;
smartHomeApp_DstAddr.endPoint = pRsp->epList[0];
/*
将smartHomeApp_DstAddr.endPoint = pRsp->epList[0]中的pRsp->epList[0]替换为smartHomeApp_ENDPOINT。
*/
smartHomeApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
smartHomeApp_DstAddr.addr.shortAddr = 0x000;
smartHomeApp_DstAddr.endPoint = smartHomeApp_ENDPOINT;
3)找到smartHomeApp_SendTheMessage函数,该函数的作用将"Hello World"字符串发送出去。我们将其中的数组char theMessageData[] = "Hello World"; 和发送信息函数部分拷贝出来,放在第1)步提取的代码后面。如下图和代码
将theMessageData里放一个字符"a",AF_DataRequest函数中只需要修改字符格式即可,而由于存放的是单个字符,且没有'\0'结尾,因此不可以用strlen来计算大小,填1即可,发送模块的代码如下。
// 将theMessageData里放一个字符"a",AF_DataRequest函数中
//只需要修改字符格式即可,而由于存放的是单个字符,且没有'\0'结尾,
//因此不可以用strlen来计算大小,填1即可,发送模块的代码如下。
//char theMessageData[] = "Hello World";
char theMessageData[] = {'a'};
smartHomeApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
smartHomeApp_DstAddr.addr.shortAddr = 0x000;
smartHomeApp_DstAddr.endPoint = smartHomeApp_ENDPOINT;
AF_DataRequest( &smartHomeApp_DstAddr, &smartHomeApp_epDesc,
smartHomeApp_CLUSTERID,
// (byte)osal_strlen( theMessageData ) + 1, 表示发送字节个数
1,
(byte *)&theMessageData,//发送的数组的首地址
&smartHomeApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
//添加一份LED灯,指示按键被按下
4) 将步骤 3)中的代码放在应用处理函数的自定义事件执行内容中。效果是,当终端设备按下按键1,会发送一个字符'a'给协调器,同时LED2亮灭翻转。
5) 选择终端设备编译,然后下载代码
2、接收端(协调器)配置
1)在smartHomeApp.c中找到static void smartHomeApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )函数,smartHomeApp_MessageMSGCB函数的作用是,当发送模块发送数据包,接收模块接收到信息后会进入该函数,无线数据包里的内容会作为afIncomingMSGPacket_t的参数传进来。
在结构体afIncomingMSGPacket_t中有一个小结构体afMSGCommandFormat_t
afMSGCommandFormat_t中有两个域,DataLength表示无线数据包里有用的数据有多少个字节,Data表示具体的内容是从该地址位置往后(数组首地址)。
2)、在 smartHomeApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )函数添加一行代码即可,如图。
3) 选择协调器设备编译,然后下载代码
ps:接收的大概过程
当终端模块发送数据后,协调器模块底层任务接收到无线数据后,会给应用层任务的系统事件发送一个AF_INCOMING_MSG_CMD消息,在消息处理函数中把有用的信息提取出来。
3、效果
在两个设备开启后,当终端设备加入协调器网络后。在终端设备按按键1,终端设备的LED2亮灭翻转一次,同时协调器LED2亮灭也同样翻转一次。
三、单播字符串收发实验
在单播字符收发实验的基础上,添加串口通讯操作,将接收的数据发送到电脑上。
1、发送端(终端)代码配置
实现效果:按下按钮KEY1,将字符串发送出去。发送模块的代码如下。
// 将theMessageData里放一个字符"Hello World",AF_DataRequest函数中
//只需要修改字符格式即可,而由于存放的是字符串 ,且有'\0'结尾,
//因此可以用strlen来计算大小,发送模块的代码如下。
char theMessageData[] = "Hello World";
//char theMessageData[] = {'a'};
smartHomeApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
smartHomeApp_DstAddr.addr.shortAddr = 0x000;
smartHomeApp_DstAddr.endPoint = smartHomeApp_ENDPOINT;
AF_DataRequest( &smartHomeApp_DstAddr, &smartHomeApp_epDesc,
smartHomeApp_CLUSTERID,
(byte)osal_strlen( theMessageData ) + 1, //表示发送字节个数
// 1,
(byte *)&theMessageData,//发送的数组的首地址
&smartHomeApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
//添加一份LED灯,指示按键被按下
2、接收端(协调器)配置
需要添加串口配置,通过串口将接收到的数据发送到电脑。
串口实验参考:zigbee笔记:四、zigbee串口uart通讯_cc2530zigbee通信配置-CSDN博客
1)在工程ZMain目录下的ZMain.c文件添加串口uart0的配置,如下图
//****************** 初始化USART_0为uart模式,使用备用位置1
void ConfigUart0()
{
PERCFG &= 0xfe; // USART_0 , 用备用位置1
P0SEL |= 0x0c; //P0_2,P0_3 设为偏上外设 ,作为Tx和Rx
P2DIR &= ~0xc0; //当PERCFG分配给一些外设到相同引脚的时候,USART 0优先
//串口传输8位数据,无奇偶校验
U0CSR |= 0x80; // USART模式选择为UART
U0CSR |= 0x40; //使能UART0接收器,使之能接收数据
U0UCR &= 0xff; //U0UCR寄存器使用默认值
U0BAUD = 216 ; //设置波特率小数部分的值
U0GCR |= 0x0b ; //设置波特率指数值
// EA = 1; //总中断
// IEN0 |= 0x04; //USART 0 Rx中断使能
//IEN2 |= 0x04; //USART 0 Tx中断使能
// UTX0IF 发送中断标志,URX0IF接收中断标志
}
2)先取消TI在main函数默认对串口的配置,流程如下图。这样才能完成对串口的配置
3)在接收数据的函数中添加串口发送数据函数,发送接收到的数据。
//****************** 初始化USART_0为uart模式,使用备用位置1
void ConfigUart0()
{
PERCFG &= 0xfe; // USART_0 , 用备用位置1
P0SEL |= 0x0c; //P0_2,P0_3 设为偏上外设 ,作为Tx和Rx
P2DIR &= ~0xc0; //当PERCFG分配给一些外设到相同引脚的时候,USART 0优先
//串口传输8位数据,无奇偶校验
U0CSR |= 0x80; // USART模式选择为UART
U0CSR |= 0x40; //使能UART0接收器,使之能接收数据
U0UCR &= 0xff; //U0UCR寄存器使用默认值
U0BAUD = 216 ; //设置波特率小数部分的值
U0GCR |= 0x0b ; //设置波特率指数值
// EA = 1; //总中断
// IEN0 |= 0x04; //USART 0 Rx中断使能
//IEN2 |= 0x04; //USART 0 Tx中断使能
// UTX0IF 发送中断标志,URX0IF接收中断标志
}
//******************
//*****************************uart0发送一个字符
void UTX0SEND( char a )
{
U0DBUF = a;
while( UTX0IF == 0 );
UTX0IF = 0;
}
//***************串口uart0信息发送函数
void InformationSend(unsigned char* send ,unsigned short len)
{
// UTX0SEND( '#' );
// UTX0SEND( ' ' );
// UTX0SEND( ' ' );
for( unsigned short i = 0 ; i < len; i++ )
{
U0DBUF = send[i];
while( UTX0IF == 0 );
UTX0IF = 0;
}
// UTX0SEND( ' ' );
// UTX0SEND( ' ' );
// UTX0SEND( '#' );
UTX0SEND( '\r' );
}
3、效果
在两个设备开启后,当终端设备加入协调器网络后。在终端设备按按键1,终端设备的LED2亮灭翻转一次,同时发送字符串 ''hello world'' 到协调器,协调器的LED2亮灭也同样翻转一次。协调器再将接收到的字符串通过串口发送到电脑上