开发环境:IAR 8.10 Z-stack 2.5
功能:协调器与终端节点组网,实现点对点通信。终端向协调器发送“D1”,协调器LED灯闪烁。
流程图:
具体代码:
endPointDesc_t GenericApp_epDesc;
byte GenericApp_TaskID;
devStates_t GenericApp_NwkState;
byte GenericApp_TransID;
SimpleDescriptionFormat_t 是一个结构体,我们可以具体分析一下,这里是它的定义:
const SimpleDescriptionFormat_t GenericApp_SimpleDesc =
{
GENERICAPP_ENDPOINT, //端口号
GENERICAPP_PROFID, //Profile的ID
GENERICAPP_DEVICEID, //设备ID
GENERICAPP_DEVICE_VERSION, //设备版本号,只占前四位
GENERICAPP_FLAGS, //预留位,只占前四位
0, //输入命令数
(cId_t *)NULL //输入命令地址
GENERICAPP_MAX_CLUSTERS, //输入命令数
(cId_t *)GenericApp_ClusterList, //输入命令地址
};
由于在本次实验中终端节点角度(命令的一方)所以要求是输出命令
const cId_t GenericApp_ClusterList[GENERICAPP_MAX_CLUSTERS] =
{
GENERICAPP_CLUSTERID //命令号
};
//任务初始化函数, 系统初始化时会被调用
void GenericApp_Init( byte task_id )
{
//保存系统分配的任务ID
GenericApp_TaskID = task_id;
//设备未连接到任何网络,使用初始状态
GenericApp_NwkState = DEV_INIT;
//
GenericApp_TransID = 0;
// Fill out the endpoint description.
//填充端点描述符
GenericApp_epDesc.endPoint = GENERICAPP_ENDPOINT;
GenericApp_epDesc.task_id = &GenericApp_TaskID;
GenericApp_epDesc.simpleDesc
= (SimpleDescriptionFormat_t *)&GenericApp_SimpleDesc;
GenericApp_epDesc.latencyReq = noLatencyReqs;
// Register the endpoint description with the AF
//注册端点描述符, 如果没有,不能使用OSAL提供的服务
afRegister( &GenericApp_epDesc );
}
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events )
{
afIncomingMSGPacket_t *MSGpkt; //消息包指针
if ( events & SYS_EVENT_MSG ) //判断是否是系统事件
{
//从消息队列中读取(接收)当前任务的消息
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
while ( MSGpkt ) //循环处理消息
{
switch ( MSGpkt->hdr.event )
{
case ZDO_STATE_CHANGE:
GenericApp_NwkState = (devStates_t)MSGpkt->hdr.status;
if( (GenericApp_NwkState == DEV_END_DEVICE) //设备状态为终端设备,加入网络成功
|| (GenericApp_NwkState == DEV_ROUTER) ) //设备状态为路由设备,加入网络成功
{
//向协调器发送数据
GenericApp_SendTheMessage();
}
break;
default:
break;
}
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
// Next 再次读取当前任务的消息
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( GenericApp_TaskID );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
//用户事件
// Discard unknown events
return 0;
}
static void GenericApp_SendTheMessage(void)
{
char theMessage[] = "D1";
afAddrType_t GenericApp_DstAddr;
GenericApp_DstAddr.addr.shortAddr = 0x0000; //短地址(逻辑地址、网络地址)
GenericApp_DstAddr.addrMode = afAddr16Bit; //通信模式 通过短地址进行点对点
GenericApp_DstAddr.endPoint = GENERICAPP_ENDPOINT; //目的地址(接收端)的端点号
if( AF_DataRequest(&GenericApp_DstAddr, //目的地址
&GenericApp_epDesc, //源(发送端)端点号
GENERICAPP_CLUSTERID, //命令号(簇ID)
(uint16)(osal_strlen(theMessage)), //发送数据长度
(byte*)theMessage, //消息内容
&GenericApp_TransID, //指向发送序号
AF_DISCV_ROUTE, //
AF_DEFAULT_RADIUS
) == afStatus_SUCCESS)
{
//LED1闪烁
HalLedBlink(HAL_LED_1, 5, 50, 5000);
}
else
{
//熄灭
HalLedSet(HAL_LED_1, HAL_LED_MODE_OFF); //关灯
}
}
#ifndef ENDDEVICE_H_
#define ENDDEVICE_H_
#define GENERICAPP_MAX_CLUSTERS 1 //输出簇的个数
#define GENERICAPP_CLUSTERID 0001 //输出簇的ID
#define GENERICAPP_ENDPOINT 10 //端点ID
#define GENERICAPP_PROFID 0x0F04 //规约ID
#define GENERICAPP_DEVICEID 0x0002 //设备ID
#define GENERICAPP_DEVICE_VERSION 0 //版本号
#define GENERICAPP_FLAGS 0 //保留位
void GenericApp_Init( byte task_id );
UINT16 GenericApp_ProcessEvent( byte task_id, UINT16 events );
#endif
本文是看里B站视频做的笔记,这里是链接:https://www.bilibili.com/video/av54057090?p=22