无线通信,需要高频的载波来提高发射效率。
Zigbee模块间,可以正常收发,接收模块必须把接收频率设置和发射模块的载波频率一致。
Zigbee中有27个高频载波可以进行通信,载波又叫作信道。载波的频率落在某些频率区段,把区段叫作频段。
总共有3种频段:
2.4G频段 含有16个信道
915M频段,896M频段 含有11个信道
但是TI的所有支持Zigbee底层协议的芯片只能落在2.4G频段的信道中进行通信。(硬件决定)
信道编号从11到26为可用信道(前11个在915M和896M中)
信道与频段(每5M更换一个信道)
11 2405M
12 2410M
13 2415M
…
26 2480M
在Zigbee中,每个模块都有在该网络里唯一的2字节的地址,为该模块的网络地址。
PANID是一个2个字节的编码,来区别不同的Zigbee无线局域网,称为个域网ID。
了解了以上之后上手写一个传输数据的例子,分为发送方和接收方
首先是发送方
需要定义一个char数组,保证发送的数据
#define SENDVAL 5
char SendPacket[]={0x0c,0x61,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,SENDVAL};
//第一个字节0x0C含义,这个自己后面还有12个字节要发送
//第5 6个字节表示的是PANID 就是个域网ID
//第7 8个字节是无线模块目标设备的网络地址 0xBEEF 对象ID
//第9 10就是本地模块的网络地址 自己ID
//11 个字节是我们有用的数据
// CRC码 12 13个字节 是硬件自动追加
其实数组只有11个成员,第12和13个不属于我们考虑的范围,但需要将他算入包的大小里,也就是第一个字节。
第234个字节的含义以后再说,目前没搞懂
这种数据包的封装方式和以太网数据包其实类似,包含了包长,包所在环境,对方IP,自己IP和数据具体内容
然后将发送方设置成32M晶振时钟,
///发送方初始化
///channelID 信道号
void halRfInit(int channelID)
{
EA=0;
FRMCTRL0 |= 0x60;
// Recommended RX settings
TXFILTCFG = 0x09;
AGCCTRL1 = 0x15;
FSCAL1 = 0x00;
// enable RXPKTDONE interrupt
RFIRQM0 |= 0x40;//把射频接收中断打开
// enable general RF interrupts
IEN2 |= 0x01;
FREQCTRL =(11+(channelID-11)*5);//(MIN_CHANNEL + (channel - MIN_CHANNEL) * CHANNEL_SPACING);
//11~26是有效信道号 会转成载波存储在此
PAN_ID0=0x07;
PAN_ID1=0x20; //0x0720 表示个域网ID
RFST = 0xEC;//清洗接收缓冲器
RFST = 0xE3;//开启接收使能
EA=1;//打开总中断
}
初始化完成后我们就可以开始写发送的方法了
///发送数据
///pstr 要发送的数据内容 配合上方SendPacket结合
void RFSend(char *pstr)
{
char i;
RFST = 0xEC; //确保接收是空的
RFST = 0xE3; //清接收标志位
while (FSMSTAT1 & 0x22); //等待射频发送准备好
RFST = 0xEE; //确保发送队列是空
RFIRQF1 &= ~0x02; //清发送标志位
//为数据发送做好准备工作
for(i=0;i
然后可配合按键中断来发送数据包。
在main函数中
void main(){
Init32M(); //切换晶振
halRfInit(); //初始化无线
SHORT_ADDR0=0x50;
SHORT_ADDR1=0x20; //设置本模块的短地址为0x2050
while(1); //死循环 所有操作让中断来做
}
接收数据中断.
Zigbee的中断很有意思
当收到的数据包与自己的本地地址或PANID有一者不一样时,就无法进入中断
这一定程度上也保证了Zigbee的安全性。
#pragma vector=RF_VECTOR
__interrupt void RF_IRQ(void)
{//这个是射频中断函数
EA=0;
if( RFIRQF0 & 0x40 )
{
RevRFProc();
//这里可以做些什么,将数据从RFD缓冲器中取出 RFD类似队列的玩法,获取一个自动去掉一个。推也是一样,按队列推入。不需要+=或者去除操作
//注意的是,接到的数据会是发送数据字节+2 因为CRC
//这里以RevRFProc函数为例
RFIRQF0&= ~0x40; // 清中断标识位
}
S1CON= 0; //清中断标识位
RFST = 0xEC;// 清接收缓冲器
RFST = 0xE3;// 开启接收使能
EA=1;
}
//RF数据接受处理
void RevRFProc()
{
static char len;
static char ch;
len=ch=0; //初始化
RFIRQM0 &= ~0x40; //关闭RF打断
IEN2 &= ~0x01; //关闭RF组打断
EA=1; //总打断开着
len=RFD; //读第一个字节判断这一串数据后面有几个字节;
//len=0x0C 12
while (len>0)
{//只要后面还有数据那么就把他都从接受缓冲区取出来
ch=RFD; //依次读后面的字节。因为前10个字节都已经在打断外做处理,这里直接不做操作
if(3==len)
{//如果倒数第三个字节,就是我们要获取的真正字节
//这里可以写 接收方 真正做的逻辑
}
len--;
}
EA=0; //关总打断
RFIRQM0 |= 0x40; //开RF打断
IEN2 |= 0x01; //开RF组打断
}
发送方和接收方唯一的区别就是在main函数的模块ID上有区别
Zigbee底层协议支持IEEE 802.15.4,硬件必须支持,才会引发中断。
IEEE 802.15.4一共定义了4种帧,分别为:信标帧、数据帧、确认帧和MAC命令帧。
想要知道帧的类型,需要用到Dongle进行空气报文捕捉,操作过程和wireshark类似。
这里发送的是数据帧,随着学习的跟进,会逐步探索到这4种帧类型。
wifi和这个不是一种通信协议。,
zigbee基于802.15.4
wifi是基于802.11的。
一直在用WiFi 无线原来如此~