8. Simple wireless communication

Preliminary knowledge

  • Zigbee wireless communication requires a high-frequency carrier to provide transmission efficiency. For Zigbee modules to be able to send and receive normally, the receiving module must set the receiving frequency to be consistent with the carrier frequency of the transmitting module.
  • Zigbee has 27 carriers for communication, and the carriers are called channels (channels for wireless communication). The frequencies of these carriers fall in certain frequency sections, which we call frequency bands.
    • 16 channels in 2.4G frequency band
    • 915M frequency band 896M frequency band 11 channels
    • However, all TI chips that support the Zigbee underlying protocol can only communicate in 16 channels in the 2.4G frequency band, namely channels 11-26.
  • Network address : on Zigb
  • In ee wireless LAN, each module has a unique 2-byte address in the network. This address is called a network address, a network short address.
  • PANID : This is a 2-byte encoding used to distinguish different Zigbee wireless LAN and personal area network IDs.

code analysis

I won’t introduce it in detail here, but only give the code template of the key configuration code.

For data sending and receiving programs, the basic configuration of basic wireless communication is fixed. You only need to know the parts that need to be changed each time.

Burn the two receiving and sending codes into the two development boards respectively. The experimental phenomenon is: the sending board presses the button to send the number you set SENDVALto the receiving board, and the receiving board displays the number through the digital tube.

send data

analyze

void halRfInit(void): Wireless communication initialization function

void RFSend(char *pstr,char len): Wireless data sending function

__interrupt void RF_IRQ(void): Wireless communication interrupt function

void RevRFProc(): Wireless data receiving function

Wireless communication initialization function

In this function, the only values ​​that need to be modified FREQCTRLare PAN_ID1the two items

image-20231010205943211

image-20231010210142126

image-20231010210253727

Wireless data sending function

You can directly read the comments. This function basically does not need to be modified. Just delete this function when using it. Just pass in the sending array and the array length.

image-20231010210834002

Interrupt function

image-20231010211712457

Send array of packets
char SendPacket[]={
    
    0x0c,0x61,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,SENDVAL};
  • The meaning of the first byte 0x0C is that there are 12 bytes to be sent after this one, which is actually 10 (followed by) + 2 (the CRC code automatically added by default)
  • The 5th and 6th bytes represent PANID
  • The 7th and 8th bytes are the network address of the wireless module target device 0xBEEF
  • Numbers 9 and 10 are the network address of the local module
  • 11 bytes are our useful data
  • CRC code 12 13 bytes are automatically appended by hardware
Things to note in the main function

image-20231010213115722

Send data template code

Burn the two receiving and sending codes into the two development boards respectively. The experimental phenomenon is: the sending board presses the button to send the number you set SENDVALto the receiving board, and the receiving board displays the number through the digital tube.

#include<iocc2530.h>
#include"74LS164_8LED.h"
#define SENDVAL 5

char SendPacket[]={
    
    0x0c,0x61,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,SENDVAL};
//第一个字节0x0C含义,这个自己后面还有12个字节要发送
//第5 6个字节表示的是PANID
//第7 8个字节是无线模块目标设备的网络地址 0xBEEF
//第9 10就是本地模块的网络地址
//11 个字节是我们有用的数据
// CRC码 12 13个字节 是硬件自动追加

void Delay()
{
    
    
    int y,x;
    
    for(y=1000;y>0;y--)
      for(x=30;x>0;x--);
}

void Init32M()
{
    
    
   SLEEPCMD &=0xFB;//1111 1011 开启2个高频时钟源
   while(0==(SLEEPSTA & 0x40));// 0100 0000 等待32M稳定
   Delay();
   CLKCONCMD &=0xF8;//1111 1000 不分频输出
   CLKCONCMD &=0XBF;//1011 1111 设置32M作为系统主时钟
   while(CLKCONSTA & 0x40); //0100 0000 等待32M成功成为当前系统主时钟
}

void KeysIntCfg()
{
    
    //Key3  Key4   Key5
     
     IEN2|=0x10;//开P1IE组中断
     P1IEN|=0x02;//开Key3组内中断
     PICTL|=0x02;//设置P1_1为下降沿 
     EA=1;      //开总中断
}
void halRfInit(void)
{
    
    
    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+(25-11)*5);//(MIN_CHANNEL + (channel - MIN_CHANNEL) * CHANNEL_SPACING);   
                     //设置载波为2475M
    
    //设置ID
    PAN_ID0=0x07;
    PAN_ID1=0x20; //0x2007   
    
    RFST = 0xEC;//清接收缓冲器
    RFST = 0xE3;//开启接收使能 
    EA=1;    
}

//发送无线数据
void RFSend(char *pstr,char len)
{
    
    
    char i;
    RFST = 0xEC; //确保接收是空的
    RFST = 0xE3; //清接收标志位
    while (FSMSTAT1 & 0x22);//等待射频发送准备好
    RFST = 0xEE;//确保发送队列是空
    RFIRQF1 &= ~0x02;//清发送标志位
    //为数据发送做好准备工作

    for(i=0;i<len;i++)
    {
    
    
       RFD=pstr[i];
    }  //循环的作用是把我们要发送的数据全部压到发送缓冲区里面
    
    RFST = 0xE9; //这个寄存器一旦被设置为0xE9,发送缓冲区的数据就被发送出去
    while(!(RFIRQF1 & 0x02) );//等待发送完成
    RFIRQF1 = ~0x02;//清发送完成标志
}


void main()
{
    
    
   LS164_Cfg();//74LS164控制数码管的初始化
   Init32M(); //主时钟晶振工作在32M 
   KeysIntCfg(); 
   
   halRfInit();//无线通信的初始化  初始化相关的寄存器,配置工作信道,和PANID
   
   SHORT_ADDR0=0x50;
   SHORT_ADDR1=0x20;//设置本模块地址  设置本模块的网络地址0x2050
   //大小端模式问题,
  
    LS164_BYTE(1); 
    while(1);
}

#pragma vector=P1INT_VECTOR
__interrupt void Key3_ISR() //P1_1
{
    
    
     if(0x02 & P1IFG)
     {
    
    
         Delay();
         if(0==P1_1)
         {
    
               
           P1DIR |=0X01;
           P1_0 ^=1;
           RFSend(SendPacket,11);//发送数据
         }     
     }

     P1IFG=0;
     P1IF=0;
}


#pragma vector=RF_VECTOR
__interrupt void RF_IRQ(void)
{
    
    //这个是射频中断函数,当小灯模块接收到开关模块发送来的数据时,小灯模块的CPU就会进入中断函数执行
    EA=0;
    if( RFIRQF0 & 0x40 )
    {
    
                
        RFIRQF0&= ~0x40;   // Clear RXPKTDONE interrupt
    }
    S1CON= 0;                   // Clear general RF interrupt flag
    RFST = 0xEC;//清接收缓冲器
    RFST = 0xE3;//开启接收使能 
    EA=1;
}

Receive data

analyze

The initialization function is the same as the initialization function for sending data. You only need to remove the sending function and add a receiving function.

Notice

  1. Between two modules that communicate with each other, the receiving and sending channels and PANID in the initialization function must be the same.
  2. The network address set in the main function of the receiving project SHORT_ADDRneeds to be consistent with the network address generated by the 7th and 8th bytes in the sent data packet.
Interrupt function

image-20231010213214831

Wireless data receiving function

image-20231010214105096

Receive data template code

Burn the two receiving and sending codes into the two development boards respectively. The experimental phenomenon is: the sending board presses the button to send the number you set SENDVALto the receiving board, and the receiving board displays the number through the digital tube.

#include<iocc2530.h>
#include"74LS164_8LED.h"
#define SENDVAL 5

char SendPacket[]={
    
    0x0c,0x61,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,SENDVAL};
//第一个字节0x0C含义,这个自己后面还有12个字节要发送
//第5 6个字节表示的是PANID
//第7 8个字节是无线模块目标设备的网络地址 0xBEEF
//第9 10就是本地模块的网络地址
//11 个字节是我们有用的数据
// CRC码 12 13个字节 是硬件自动追加

void Delay()
{
    
    
    int y,x;
    
    for(y=1000;y>0;y--)
      for(x=30;x>0;x--);
}

void Init32M()
{
    
    
   SLEEPCMD &=0xFB;//1111 1011 开启2个高频时钟源
   while(0==(SLEEPSTA & 0x40));// 0100 0000 等待32M稳定
   Delay();
   CLKCONCMD &=0xF8;//1111 1000 不分频输出
   CLKCONCMD &=0XBF;//1011 1111 设置32M作为系统主时钟
   while(CLKCONSTA & 0x40); //0100 0000 等待32M成功成为当前系统主时钟
}

void halRfInit(void)
{
    
    
    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+(25-11)*5);//(MIN_CHANNEL + (channel - MIN_CHANNEL) * CHANNEL_SPACING);   
                     //设置载波为2475M
    
    //设置ID
    PAN_ID0=0x07;
    PAN_ID1=0x20; //0x2007   
    
//halRfRxInterruptConfig(basicRfRxFrmDoneIsr); 
    
    RFST = 0xEC;//清接收缓冲器
    RFST = 0xE3;//开启接收使能 
    EA=1;    
}

//接受无线数据
void RevRFProc()
{
    
    
	static char len;
	static char  ch;

    len = ch = 0;
    RFIRQM0 &= ~0x40;
    IEN2 &= ~0x01;
    EA = 0;
 
    len = RFD;//读第一个字节判断这一串数据后面有几个字节;

    while (len > 0) 
    {
    
    //只要后面还有数据那么就把他都从接受缓冲区取出来
        ch=RFD;
        if(3 == len)
        {
    
    //读取倒数第三个字节的数字,通过数码管显示
           LS164_BYTE(ch);
        }
        len--;
     }     
    EA=1;
    RFIRQM0 |= 0x40;
    // enable general RF interrupts
    IEN2 |= 0x01;        
}


void main()
{
    
    
  
  LS164_Cfg();//74LS164控制数码管的初始化
  Init32M(); //主时钟晶振工作在32M 
  halRfInit();
   
  SHORT_ADDR0=0xEF;
  SHORT_ADDR1=0xBE;//设置本模块地址  0xBEEF
  
  LS164_BYTE(2); 
  while(1);
}

#pragma vector=RF_VECTOR
__interrupt void RF_IRQ(void)
{
    
    //这个是射频中断函数,当小灯模块接收到开关模块发送来的数据时,小灯模块的CPU就会进入中断函数执行
    EA=0;
    if( RFIRQF0 & 0x40 )
    {
    
    
        
        RevRFProc();
             
        RFIRQF0&= ~0x40;   // Clear RXPKTDONE interrupt
    }
    S1CON= 0;                   // Clear general RF interrupt flag
    RFST = 0xEC;//清接收缓冲器
    RFST = 0xE3;//开启接收使能 
    EA=1;
}

おすすめ

転載: blog.csdn.net/qq_61228493/article/details/133834667