Zigbee无线收发串口实验注释代码19-4-10
<p>效果是协调器建立网络后,终端加入网络并向协调器发送字符串,协调器通过串口将收到的字符串发到PC<br/></p><p><br/></p><p>Coordinator.c</p><pre class="prism-highlight prism-language-c">#include "OSAL.h"//为了实现多事件和多任务切换,需要把事件和任务对应的应用,并起一个名字OSAL操作系统抽象层。
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDprofile.h"
#include <string.h>
#include "Coordinator.h"
#include "DebugTrace.h"
#if !defined( WIN32)
#include "OnBoard.h"
#endif
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{
GENERICAPP_CLUSTERID
};//const 常量
const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{
GENERICAPP_ENDPOINT, // int Endpoint;
GENERICAPP_PROFID, // uint16 AppProfId[2];
GENERICAPP_DEVICEID, // uint16 AppDeviceId[2];
GENERICAPP_DEVICE_VERSION, // int AppDevVer:4;
GENERICAPP_FLAGS, // int AppFlags:4;
GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters;
(cId_t *)GenericApp_ClusterList, // byte *pAppInClusterList;
0, // byte AppNumInClusters;
(cId_t *)NULL // byte *pAppInClusterList;
};//上述数据姐构体可以用来描述一个eigbee设备节点,成为简单设备描述符
endPointDesc_t GenericApp_epDesc;//endPointDesc_t 是结构体,定义在AF.h
byte GenericApp_TaskID;
byte GenericApp_TransID;
//unsigned char uartbuf[128];//串口缓冲区
//节点描述符 GenericApp_epDesc 任务优先级TaskID 数据发送序列号TransID
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );//消息处理函数
void GenericApp_SendTheMessage( void );//数据发送函数
//static void rxCB(uint8 port,uint8 event);//串口相关
void GenericApp_Init( byte task_id )
{
halUARTCfg_t uartConfig;//定义串口配置结构体
GenericApp_TaskID = task_id;//初始化任务优先级
GenericApp_TransID = 0;//将发送数据包序号初始化,
//每发送一个包自动加一,在接收端查看以计算丢包率
GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;//
GenericApp_epDesc.task_id = &GenericApp_TaskID;//
GenericApp_epDesc.simpleDesc
= (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;//
GenericApp_epDesc.latencyReq = noLatencyReqs;//
afRegister( &GenericApp_epDesc );//调用函数为节点描述符注册,以使用OSAL提供的服务
/*以下是串口收发实验新增部分,对串口进行配置,如是否打开串口,波特率,是否使用流控等*/
uartConfig.configured = TRUE;
uartConfig.baudRate = HAL_UART_BR_115200;
uartConfig.flowControl = FALSE;
uartConfig.callBackFunc = NULL;//在串口配置部分,回调函数不需要了
HalUARTOpen(0,&uartConfig);//最后使用HalUARTOpen对串口进行初始化
}
// 上述代码是该任务初始化函数
//注释为空的部分较为固定,不用修改
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{
//以下代码在基础串口收发实验时不用 ,将事件处理函数改为空函数
afIncomingMSGPacket_t *MSGpkt;//定义了一个指向消息接受结构体的指针MSGpkt
if(events & SYS_EVENT_MSG)
{
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(GenericApp_TaskID);//使用osal_msg_receive函数从消息队列上接受消息
//该消息包含了指向接收到数据包的指针
while(MSGpkt)
{
switch(MSGpkt->hdr.event)
{case AF_INCOMING_MSG_CMD://如果是无线数据,用下面函数处理
GenericApp_MessageMSGCB( MSGpkt);//11111
break;
default:
break;
}
osal_msg_deallocate( (uint8 *)MSGpkt);//处理完消息需要释放内存空间,调用deallocate函数以释放
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive
(GenericApp_TaskID);//处理队列中下一个消息直到处理完
}
return(events ^ SYS_EVENT_MSG);
}
return 0;
}
//上述代码是消息处理函数,大部分固定,唯一可以修改的是注释标记处
//需要熟悉该函数的格式
/*串口实验中新增*/
/*static void rxCB(uint8 port,uint8 event)
{
HalUARTRead(0,uartbuf,7);//调用函数,从串口读取数据并存放在uartbuf中
if(osal_memcmp(uartbuf,"ldztzrh",7))//判断接受到的数据,如果是,返回TURE
{
HalUARTWrite(0,uartbuf,8);//调用该函数,发送收到的数据
}
}*/
//osal_memcmp()经常使用,是一个回调函数,在 uartConfig.callBackFunc = rxCB; 处
//将rxCB传递给了成员callBackFunc,是一个函数指针,也就是将函数的地址传给callBackFunc
//这样就可以通过callBackFunc成员函数来调用rxCB()函数了。
//回调函数是在特定条件或事件发生时,由另一方调用的,用于响应
//以下代码在基础串口收发实验时不用
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
unsigned char buffer[10];
switch(pkt->clusterId)
{
case GENERICAPP_CLUSTERID:
osal_memcpy(buffer,pkt->cmd.Data,10);//使用osal_memcpy函数将接收到的数据拷贝到buffer中
HalUARTWrite(0,buffer,10);//串口写函数
break;
}
}</pre><p>Enddevice.c</p><pre class="prism-highlight prism-language-c">#include "OSAL.h"
#include "AF.h"
#include "ZDApp.h"
#include "ZDObject.h"
#include "ZDProfile.h"
#include <string.h>
#include "Coordinator.h"
#include "DebugTrace.h"
#if !defined( WIN32 )
#include "OnBoard.h"
#endif
#include "hal_lcd.h"
#include "hal_led.h"
#include "hal_key.h"
#include "hal_uart.h"
#define SEND_DATA_EVENT 0x01//添加新事件
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{
GENERICAPP_CLUSTERID
};
const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{
GENERICAPP_ENDPOINT, // int Endpoint;
GENERICAPP_PROFID, // uint16 AppProfId[2];
GENERICAPP_DEVICEID, // uint16 AppDeviceId[2];
GENERICAPP_DEVICE_VERSION, // int AppDevVer:4;
GENERICAPP_FLAGS, // int AppFlags:4;
GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters;
(cId_t *)GenericApp_ClusterList, // byte *pAppInClusterList;
GENERICAPP_MAX_CLUSTERS, // byte AppNumInClusters;
(cId_t *)GenericApp_ClusterList // byte *pAppInClusterList;
};//描述一个设备节点,参考coordinator.c文件
endPointDesc_t GenericApp_epDesc;
byte GenericApp_TaskID;
byte GenericApp_TransID;
devStates_t GenericApp_NwkState;
/*定义四个变量
//节点描述符 GenericApp_epDesc 任务优先级TaskID 数据发送序列号TransID
GenericApp_NwkState 保存节点状态*/
void GenericApp_MessageMSGCB( afIncomingMSGPacket_t *pckt );
void GenericApp_SendTheMessage( void );//发送函数
void GenericApp_Init( byte task_id )
{
GenericApp_TaskID = task_id;//初始化任务优先级
GenericApp_NwkState = DEV_INIT;//状态初始化为DEV_INIT表示该节点没有链接到网络
GenericApp_TransID = 0;//将发送数据包序号初始化,
//每发送一个包自动加一,在接收端查看以计算丢包率
GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;//
GenericApp_epDesc.task_id = &GenericApp_TaskID;//
GenericApp_epDesc.simpleDesc
= (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;//
GenericApp_epDesc.latencyReq = noLatencyReqs;//
afRegister( &GenericApp_epDesc );//调用函数为节点描述符注册,以使用OSAL提供的服务
}
// 上述代码是该任务初始化函数
//注释为空的部分较为固定,不用修改
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{
afIncomingMSGPacket_t *MSGpkt;//定义了一个指向消息接受结构体的指针MSGpkt
if(events & SYS_EVENT_MSG)
{
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive(GenericApp_TaskID);//使用osal_msg_receive函数从消息队列上接受消息
//该消息包含了指向接收到数据包的指针
while(MSGpkt)
{
switch(MSGpkt->hdr.event)
{
case ZDO_STATE_CHANGE:
GenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);//读取设备类型
if (GenericApp_NwkState == DEV_END_DEVICE)//如果是终端节点,类型码为DEV_END_DEVICE
{
osal_set_event(GenericApp_TaskID,SEND_DATA_EVENT);//当终端加入节点,用此函数设置事件
//此函数设置某一事件,事件发生后,执行事件处理函数
}
break;
default:
break;
}
osal_msg_deallocate( (uint8 *)MSGpkt);//处理完消息需要释放内存空间,调用deallocate函数以释放
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive
(GenericApp_TaskID);//处理队列中下一个消息直到处理完
}
return(events ^ SYS_EVENT_MSG);
}
if(events & SEND_DATA_EVENT)
{
GenericApp_SendTheMessage();
osal_start_timerEx(GenericApp_TaskID,SEND_DATA_EVENT,1000);//下一行解释三个参数
//(时间到达后,对其做出响应的任务,时间到达后,该事件发生,定时时间 ms)
return (events ^ SEND_DATA_EVENT);//清除事件标志
}
return 0;
}
/*在串口收发实验中,作用是调用无线发送函数,并且定时1s*/
/*
上述代码是消息处理函数,大部分固定
需要熟悉该函数的格式
*/
void GenericApp_SendTheMessage(void)
{
unsigned char theMessageData[10] = "EndDevice";//用于存放要发送的数据
afAddrType_t my_DstAddr;//为满足AF_DataRequest第一个参数定义的变量
my_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;//何种方式发送(单播)
my_DstAddr.endPoint = GENERICAPP_ENDPOINT;//初始化端口号
my_DstAddr.addr.shortAddr = 0x0000;//协调器地址固定为0x0000
AF_DataRequest( &my_DstAddr, //目的地节点的网络地址和发送数据的格式
&GenericApp_epDesc,//端口号
GENERICAPP_CLUSTERID,//命令号
osal_strlen("EndDevice")+1,//数据长度,发送时需要将结尾结束符一起发
theMessageData,//指向数据缓冲区的指针
&GenericApp_TransID,
AF_DISCV_ROUTE,
AF_DEFAULT_RADIUS);
/*调用数据发送函数AF_DataRequest进行无线数据发送 */
/HalLedBlink(HAL_LED_2,0,50,500);
}
/*数据类型afAddrType和函数AF_DataRequest原型都在书上*/</pre><p><br/></p>
Q.E.D.