Zigbee学习日记(六)无线通信原理
goJhou 发布于2017-12-30 浏览:3805 回复:2
3
收藏

无线通信,需要高频的载波来提高发射效率。

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种帧类型。

 

 

收藏
点赞
3
个赞
共2条回复 最后由goJhou回复于2018-01-10
#3goJhou回复于2018-01-10
#2 荒墨丶迷失回复
一直在用WiFi 无线原来如此~

wifi和这个不是一种通信协议。,

zigbee基于802.15.4

wifi是基于802.11的。

0
#2荒墨丶迷失回复于2018-01-10

一直在用WiFi 无线原来如此~

1
TOP
切换版块