zigbee协议栈应用(四)广播组网-无线数据传输
来源:互联网 发布:毒性数据库 编辑:程序博客网 时间:2024/05/02 02:54
1.具体实现:终端通过无线把数据传给协调器,协调器再将数据通过串口传给电脑显示~
打开之前的串口程序,串口部分就不用讲了,直接进入无线的收发
2.代码的增加:
1). 接收数据 (红色字体为新增代码)
SampleApp_MessageMSGCB, , 在 函数 case SAMPLEAPP_PERIODIC_CLUSTERID: 下 面增 加 三
行代码,修改后如下:
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) // 接收数据
{
uint16 flashTime;
switch ( pkt->clusterId )
{
case SAMPLEAPP_PERIODIC_CLUSTERID:
HalUARTWrite(0, "Rx:", 3); // 提示信息
HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); // 输出接收到的数据
HalUARTWrite(0, "\n", 1); // 回车换行
break;
case SAMPLEAPP_FLASH_CLUSTERID: // 此实验没有使用,到后面实验详解
flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );
HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );
break;
}
}
2). 发送数据 (红色字体为新增代码)
void SampleApp_SendPeriodicMessage( void ) // 周期发送函数
{
uint8 data[11]="0123456789";
// 调用 AF_DataRequest 将数据无线广播出去,在第一个实验详解里就不重复了。
if ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
SAMPLEAPP_PERIODIC_CLUSTERID,
10,
data,
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )
{
}
else
{
// Error occurred in request to send.
}
}
1).选择 CoodinatorEB, 下载到板 A;作为协调器,通过 USB 线跟电脑连接.
2).选择 EndDeviceEB, 下载到板 B;作为终端设备无线发送数据给协调器
3).给两块开发板 上电,打开串口调试助手,设为:115200 8N1 ,协调器间隔 5S 会收到终端发过来的数据。
3.重点难点理解
接收部分: 接收数据主要工作:
1) 读取接收到的数据
2) 把数据通过串口发送给 C PC 机 在
SampleApp.c 中搜索 SampleApp_ProcessEvent ,找到如下代码处:
case AF_INCOMING_MSG_CMD:
SampleApp_MessageMSGCB( MSGpkt );
break;
其中 SampleApp_MessageMSGCB( MSGpkt );就是接收处理函数。
void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt ) // 接收数据
{
uint16 flashTime;
switch ( pkt->clusterId )
{
case SAMPLEAPP_PERIODIC_CLUSTERID:
HalUARTWrite(0, "Rx:", 3); // 提示信息
HalUARTWrite(0, pkt->cmd.Data, pkt->cmd.DataLength); //
HalUARTWrite(0, "\n", 1); // 回车换行
break;
}
}
SAMPLEAPP_PERIODIC_CLUSTERID 这个宏定义是不是有点眼熟?没错,这就是我们前面
发送函数定义的数据包的 ID 号,它的作用很明显了,如果收到的 ID 号相同说明是我们自己
定 义的周期性广播包。所有的数据和信息都在函数传入来的 afIncomingMSGPacket_t *pkt里
面, 进入 afIncomingMSGPacket_t 的定义,它是一个结构体,内容如下:
typedef struct
{
osal_event_hdr_t hdr; /* OSAL Message header OSAL 消息头 */
uint16 groupId; /* Message's group ID - - 0 0 if not set 消息组 ID */
uint16 clusterId; /* Message's cluster ID 消息族 ID */
afAddrType_t srcAddr; /* Source Address, if endpoint is STUBAPS_INTER_PAN_EP,
it's an InterPAN message 源地址类型 */
uint16 macDestAddr; /* MAC header destination short address C MAC 物理地址 */
uint8 endPoint; /* destination endpoint MAC 目的端点 */
uint8 wasBroadcast; /* 广播地址 */
uint8 LinkQuality; /* 接收数据帧的链路质量 */
uint8 correlation; /* 接收数据帧的未加工相关值 */
int8 rssi; /* The received RF power in units m dBm 接收的射频功率 */
uint8 SecurityUse; /* deprecated 弃用 */
uint32 timestamp; /* receipt timestamp from C MAC 收到时间标记 */
afMSGCommandFormat_t cmd; /* Application Data 应用程序数据*/
} afIncomingMSGPacket_t; // 无线数据包格式结构体
那么数据在哪里呢?在红色那行,又是一个结构体,继续进入。
// Generalized MSG Command Format
typedef struct
{ {
byte TransSeqNumber;
uint16 DataLength; // Number of bytes in TransData
byte *Data;
} } afMSGCommandFormat_t; 千呼万唤始出来,现在就可以通过程序将数据读出了。通过
osal_memcpy 复制到数据中处理了, 如:osal_memcpy( buf, MSGpkt->cmd.Data, MSGpkt-
>cmd.DataLength );
二、 发送部分 发送部分主要工作:设置发送内容,启动定时器,周
期性地发送。同样在 SampleApp_ProcessEven 函数找到如下代码:
1. case ZDO_STATE_CHANGE: // 当网络状态改变,所有节点都会发生
2. SampleApp_NwkState = = (devStates_t)(MSGpkt- - >hdr.status);
3. if ( ( //(SampleApp_NwkState == DEV_ZB_COORD) || // 协议器不用发送所以屏蔽
4. (SampleApp_NwkState == DEV_ROUTER) // 路由器
5. || (SampleApp_NwkState == DEV_END_DEVICE) ) ) // 终端设备
6. { {
7. // Start sending the periodic message in a a regular interval.
8. osal_start_timerEx( SampleApp_TaskID,
SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );
9. } }
第 8 行:红色字体标出的为关键代码。osal_start_timerEx 三个参数决定着周期性发送数据的
命脉。我们逐一分析。
Sample e App_ _ TaskID D :任务 ID,函数 SampleApp_Init ()开头定义了 SampleApp_TaskID = task_id;
也就是 SampleApp 初始化的任务 ID 号。
SAMPLEAPP_AA_PERIODIC_MSG_EVT :
#define SAMPLEAPP_SEND_PERIODIC_MSG_EVT 0x0001
同一个任务下可以有多个事件,这个是事件的编号。我们可以定义自己的事件,但是编号不
能重复。
SAMPLEAPP_AA_PERIODIC_MSG_TIMEOUT :
#define SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT 5000
事件重复执行的时间。这里以毫秒为单位,所以是 5s,也就是刚刚实验为什么间隔约 5s 收到数
据的原因。这里可以改成你需要发送的时间间隔。 注意:ZDO_STATE_CHANGE 只有当设
备网络发生改变后才会触发,所以在此处可做一些 初始化工作;如果网络一直连接的就不会
再次进入这个函数了,只执行 1 次。 在同一函数内找到如下代码:
// 判断 T SAMPLEAPP_SEND_PERIODIC_MSG_EVT 有没有发生,如果有的就执行下面函数
1. if ( ( events & & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) )
2. { {
3. // Send the periodic message
4. SampleApp_SendPeriodicMessage();
5. // Setup to send message again in normal period (+ a a little jitter)
6. osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,
7. (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + + (osal_rand() & & 0x00FF)) );
8. // return unprocessed events
9. return (events ^ ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);
10. } }
第 4 行: SampleApp_SendPeriodicMessage();是我们发送数据的函数:
void SampleApp_SendPeriodicMessage( void ) )
{ {
uint8 data[11]="0123456789";
if ( ( AF_DataRequest( &SampleApp_Periodic_DstAddr, &SampleApp_epDesc,
{ {
} }
else
{ {
SAMPLEAPP_PERIODIC_CLUSTERID, //簇 簇 ID
10, // 发送数据的长度
data, // 数据的缓冲区
&SampleApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS ) ) == afStatus_SUCCESS ) )
// Error occurred in request to send.
} }
} }
如果想修改发送的字符,只需修改 data 和 len 即可
- zigbee协议栈应用(四)广播组网-无线数据传输
- ZigBee组网学习笔记(五)--无线数据传输
- 170806 通信-ZigBee协议栈广播组网(接收)
- 170809 通信-ZigBee协议栈广播组网(发送)
- ZigBee组网学习笔记(四)--协议栈按键实验
- ZigBee组网学习笔记(三 )--协议栈串口实验
- ZigBee组网学习笔记(六)--网络通讯(广播)
- zigbee协议栈学习(四)
- zigbee协议栈学习(四)
- ZigBee组网学习笔记(七)--协议栈网络管理
- 短距离无线数据低功耗传输协议研究
- ZIGBEE的组网和传输距离
- zigbee协议栈应用(二)基础协议栈入门
- ZigBee组网(原理分析)
- zigbee组网
- ZigBee组网
- ZigBee组网
- Zigbee 组网
- [线性常微分方程][5]SPECIAL CASES REPEATED AND ZERO EIGENVALUES
- 为什么我的hosts文件修改无效?
- HttpURLConnection、Handler、新闻客户端案例、get和post提交数据
- LeetCode:Combination Sum III
- WindowsServer2012 搭建多台Tomcat
- zigbee协议栈应用(四)广播组网-无线数据传输
- 复制mp3、复制文件夹下所有文件的思路
- android ui 练习
- poj3281Dining
- C++复习1.const用法
- 110. Balanced Binary Tree
- 使用RAII来管理对象资源
- ajax笔记
- 《JavaScript学习笔记》:第一个面向对象的程序