预备知识
- Zigbee无线通信,需要高频的载波来提供发射效率,Zigbee模块之间要可以正常的收发,接收模块必须把接收频率设置和发射模块的载波频率一致。
- Zigbee有27个载波可以进行通信,载波叫做信道(无线通信的通道)。这些载波的频率落在某些频率区段,我们把这些区段叫做频段。
- 2.4G频段 16个信道
- 915M频段 896M频段 11个信道
- 但TI的所有支持Zigbee底层协议的芯片只能在2.4G频段的16个信道里进行通信,即11-26信道。
- 网络地址:在Zigb
- ee无线局域网里,每一模块都一个在该网络里唯一的2个字节的地址,这个地址叫做网络地址,网络短地址。
- PANID:这是一个2个字节的编码,用来区别不同的Zigbee无线局域网,个域网ID.
代码分析
这里不在详细介绍,只给出关键配置代码的代码模板
对于数据发送接收的程序来说,基本的无线通信的基础配置是固定的,只需要知道里面需要自己每次更改的部分即可
将两个接收和发送的代码分别烧录到两个开发板中,实验现象是:发送板按下按键发送你设定的数字SENDVAL
到接收板,接收板通过数码管显示该数字
发送数据
分析
void halRfInit(void)
:无线通信初始化函数
void RFSend(char *pstr,char len)
:无线数据发送函数
__interrupt void RF_IRQ(void)
:无线通信中断函数
void RevRFProc()
:无线数据接收函数
无线通信初始化函数
在这个函数中,需要修改的只有FREQCTRL
和PAN_ID1
两项的值
无线数据发送函数
可以直接看注释,这个函数基本不用改动,使用时直接掉这个函数就行,传入发送数组和数组长度即可
中断函数
发送数据包数组
1
| char SendPacket[]={0x0c,0x61,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,SENDVAL};
|
- 第一个字节0x0C含义,这个自己后面还有12个字节要发送,实际上是10(后面跟的)+2(默认自动添加的CRC 码)
- 第5 6个字节表示的是PANID
- 第7 8个字节是无线模块目标设备的网络地址 0xBEEF
- 第9 10就是本地模块的网络地址
- 11 个字节是我们有用的数据
- CRC码 12 13个字节 是硬件自动追加
主函数中的注意事项
发送数据模板代码
将两个接收和发送的代码分别烧录到两个开发板中,实验现象是:发送板按下按键发送你设定的数字SENDVAL
到接收板,接收板通过数码管显示该数字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
| #include<iocc2530.h> #include"74LS164_8LED.h" #define SENDVAL 5
char SendPacket[]={0x0c,0x61,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,SENDVAL};
void Delay() { int y,x; for(y=1000;y>0;y--) for(x=30;x>0;x--); }
void Init32M() { SLEEPCMD &=0xFB; while(0==(SLEEPSTA & 0x40)); Delay(); CLKCONCMD &=0xF8; CLKCONCMD &=0XBF; while(CLKCONSTA & 0x40); }
void KeysIntCfg() { IEN2|=0x10; P1IEN|=0x02; PICTL|=0x02; EA=1; } void halRfInit(void) { EA=0; FRMCTRL0 |= 0x60;
TXFILTCFG = 0x09; AGCCTRL1 = 0x15; FSCAL1 = 0x00; RFIRQM0 |= 0x40; IEN2 |= 0x01; FREQCTRL =(11+(25-11)*5); PAN_ID0=0x07; PAN_ID1=0x20; 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; while(!(RFIRQF1 & 0x02) ); RFIRQF1 = ~0x02; }
void main() { LS164_Cfg(); Init32M(); KeysIntCfg(); halRfInit(); SHORT_ADDR0=0x50; SHORT_ADDR1=0x20; LS164_BYTE(1); while(1); }
#pragma vector=P1INT_VECTOR __interrupt void Key3_ISR() { 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) { EA=0; if( RFIRQF0 & 0x40 ) { RFIRQF0&= ~0x40; } S1CON= 0; RFST = 0xEC; RFST = 0xE3; EA=1; }
|
接收数据
分析
初始化函数和发送数据的初始化函数一样,只需要把发送函数去掉,添加一个接收函数即可
注意
- 两相互通信的模块之间,初始化函数中的接收和发送的信道和PANID一定要一样
- 接收工程的主函数中设置的
SHORT_ADDR
网络地址需要和发送的数据包中的第7、8两个字节所生成的网络地址一致
中断函数
无线数据接收函数
接收数据模板代码
将两个接收和发送的代码分别烧录到两个开发板中,实验现象是:发送板按下按键发送你设定的数字SENDVAL
到接收板,接收板通过数码管显示该数字
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| #include<iocc2530.h> #include"74LS164_8LED.h" #define SENDVAL 5
char SendPacket[]={0x0c,0x61,0x88,0x00,0x07,0x20,0xEF,0xBE,0x20,0x50,SENDVAL};
void Delay() { int y,x; for(y=1000;y>0;y--) for(x=30;x>0;x--); }
void Init32M() { SLEEPCMD &=0xFB; while(0==(SLEEPSTA & 0x40)); Delay(); CLKCONCMD &=0xF8; CLKCONCMD &=0XBF; while(CLKCONSTA & 0x40); }
void halRfInit(void) { EA=0; FRMCTRL0 |= 0x60;
TXFILTCFG = 0x09; AGCCTRL1 = 0x15; FSCAL1 = 0x00; RFIRQM0 |= 0x40; IEN2 |= 0x01; FREQCTRL =(11+(25-11)*5); PAN_ID0=0x07; PAN_ID1=0x20;
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; IEN2 |= 0x01; }
void main() { LS164_Cfg(); Init32M(); halRfInit(); SHORT_ADDR0=0xEF; SHORT_ADDR1=0xBE; LS164_BYTE(2); while(1); }
#pragma vector=RF_VECTOR __interrupt void RF_IRQ(void) { EA=0; if( RFIRQF0 & 0x40 ) { RevRFProc(); RFIRQF0&= ~0x40; } S1CON= 0; RFST = 0xEC; RFST = 0xE3; EA=1; }
|