预备知识
- 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; }
|