Z-stack协议栈简单知识:
IEEE 802.15.4 定义了 PHY(物理层)和 MAC(介质访问层)技术规范;ZigBee 联盟定义了 NWK(网络层)、APS(应用程序支持子层)、APL(应用层)技术规范ZigBee 协议栈就是将各个层定义的协 议都集合在一起 ,以函数的形式实现,并供给用户提供 API( 应用层) ,用户可以直接调用。
用zigbee协议栈使用协调器和节点之间传输数据实验:
在ZZApp.c中对协调器和节点初始化设置
case ZDO_STATE_CHANGE:
ZZApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
// if ( (ZZApp_NwkState == DEV_ZB_COORD)
// || (ZZApp_NwkState == DEV_ROUTER)
// || (ZZApp_NwkState == DEV_END_DEVICE) )
// {
// // Start sending "the" message in a regular interval.
// osal_start_timerEx( ZZApp_TaskID,
// ZZApp_SEND_MSG_EVT,
// ZZApp_SEND_MSG_TIMEOUT );
// }
if (ZZApp_NwkState == DEV_ZB_COORD)
{
LCD_Init();
LCD_CLS();
LCD_P8x16Str(4, 0, "COORD");
//D1 P1_0
P1SEL &= ~0x01;
P1DIR |= 0x01;
//D2 P1_1
P1SEL &= ~0x02;
P1DIR |= 0x02;
//D3 P0_4
P0SEL &= ~0x10;
P0DIR |= 0x10;
//
P1_0 = 1;
P1_1 = 1;
P0_4 = 0;
}
if (ZZApp_NwkState == DEV_END_DEVICE)
{
LCD_Init();
LCD_CLS();
LCD_P8x16Str(4, 0, "END");
//D1 P1_0
P1SEL &= ~0x01;
P1DIR |= 0x01;
//D2 P1_1
P1SEL &= ~0x02;
P1DIR |= 0x02;
//D3 P0_4
P0SEL &= ~0x10;
P0DIR |= 0x10;
//
P1_0 = 1;
P1_1 = 1;
P0_4 = 0;
}
break;
}
导入入按键中断源文件
#include<iocc2530.h>
#include "ZZApp.h"
extern unsigned char ZZApp_TaskID;
#include "OSAL_Timers.h"
void KeysIntCfg()
{
P0SEL &=~0X02;
P0DIR &=~0X02;
IEN1|=0x20;
P0IEN|=0x02;
PICTL|=0x01;//设置P0_1为下降沿
P2SEL &=~0X01;
P2DIR &=~0X01;
IEN2|=0x02;
P2IEN|=0x01;
PICTL|=0x08;//设置P2_0为下降沿
EA=1; //开总中断
}
#pragma vector=P0INT_VECTOR
__interrupt void Key3_ISR() //P0_1
{
if(P0IFG & 0X02)
{
osal_start_timerEx(ZZApp_TaskID,ZZApp_MY_EVT,25);
}
P0IFG =0;
P0IF=0;
}
#pragma vector=P2INT_VECTOR
__interrupt void Key4_ISR()//P2_0
{
if(P2IFG & 0X01)
{
osal_start_timerEx(ZZApp_TaskID,ZZApp_MY_EVT,25);
}
P2IFG =0;
P2IF=0;
}
导入按键中断的头文件
#ifndef ZH_KEY_H
#define ZH_KEY_H
void KeysIntCfg();
#endif
Zmain.c中声明按键中断头文件
#include "ZZ_Key.h"
Zmain.c中初始化按键中断配置
KeysIntCfg();
光这样还不行,zigbee协议栈中默认初始化了P0和P2口的中断,就和我们定义的中断产生了冲突,因此要先把默认初始化给注释掉才可以正常使用(HAL/Target/CC2530EB/Drivers/hal_key.c)
导入OLED的库文件和头文件,因为OLED的型号不同,这里就不贴了,以免产生误导
发送端(节点):
ZZApp.h中定义事件
#define ZZApp_MY_EVT 0x0002
ZZApp.c中应用事件
if ( events & ZZApp_MY_EVT )
{
if(P0_1 == 0)//S1按键按下
{
char theMessageData[] = "HELLO WORLD!";
ZZApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
ZZApp_DstAddr.addr.shortAddr = 0x0000;//接受端地址,协调器默认是0x0000
// Take the first endpoint, Can be changed to search through endpoints
ZZApp_DstAddr.endPoint = 1;//接受端的端口
AF_DataRequest( &ZZApp_DstAddr, &ZZApp_epDesc,
0x0001,//接受端的簇
(byte)osal_strlen( theMessageData ) + 1,//发送字符串的长度
(byte *)&theMessageData,
&ZZApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
P1_0 = ~P1_0;//D1灯取反表示数据已发送
}
if(P2_0 == 0)//S2按键按下
{
char theMessageData[] = "hello world!";
ZZApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
ZZApp_DstAddr.addr.shortAddr = 0x0000;//接受端地址,协调器默认是0x0000
// Take the first endpoint, Can be changed to search through eddpoints
ZZApp_DstAddr.endPoint = 2;//接受端的端口
AF_DataRequest( &ZZApp_DstAddr, &ZZApp_epDesc,
0x0001,//接受端的簇
(byte)osal_strlen( theMessageData ) + 1,//发送字符串的长度
(byte *)&theMessageData,
&ZZApp_TransID,
AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
P1_1 = ~P1_1;//D2灯取反表示数据已发送
}
return (events ^ ZZApp_MY_EVT);
}
接收端(协调器):
ZZApp.c中定义端点1和端点2
// Fill out the endpoint description.
ZZApp_epDesc.endPoint = 1,//ZZApp_ENDPOINT;
ZZApp_epDesc.task_id = &ZZApp_TaskID;
ZZApp_epDesc.simpleDesc
= (SimpleDescriptionFormat_t *)&ZZApp_SimpleDesc;
ZZApp_epDesc.latencyReq = noLatencyReqs;
// Register the endpoint description with the AF
afRegister( &ZZApp_epDesc );
// Fill out the endpoint description.
ZZApp_epDesc1.endPoint = 2,//ZZApp_ENDPOINT;
ZZApp_epDesc1.task_id = &ZZApp_TaskID;
ZZApp_epDesc1.simpleDesc
= (SimpleDescriptionFormat_t *)&ZZApp_SimpleDesc;
ZZApp_epDesc1.latencyReq = noLatencyReqs;
// Register the endpoint description with the AF
afRegister( &ZZApp_epDesc1 );
ZZApp.c中编写接收函数
void ZZApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )
{
// switch ( pkt->clusterId )
// {
// case ZZApp_CLUSTERID:
// // "the" message
//#if defined( LCD_SUPPORTED )
// HalLcdWriteScreen( (char*)pkt->cmd.Data, "rcvd" );
//#elif defined( WIN32 )
// WPRINTSTR( pkt->cmd.Data );
//#endif
// break;
// }
if(pkt->endPoint==1)
{
switch(pkt->clusterId)
{
case 0x0001:LCD_P8x16Str(8, 2, pkt->cmd.Data);
//D1 P1_0
P1SEL &= ~0x01;
P1DIR |= 0x01;
P1_0 = ~P1_0;
break;
}
}
if(pkt->endPoint==2)
{
switch(pkt->clusterId)
{
case 0x0001:LCD_P8x16Str(8, 2, pkt->cmd.Data);
//D2 P1_1
P1SEL &= ~0x02;
P1DIR |= 0x02;
P1_1 = ~P1_1;
break;
}
}
}
现象:
协调器显示COORD表示已创建协调器网络
节点显示END表示已加入协调器创建的网络
节点按键S1按下时出现大写HELLO WORLD!
节点按键S2按下时出现小写hello world!