應用場景描述:
多個發送端在不同的信道上發送信息(11~26)信道,接收端輪詢所有信道(11~26),若有信號,則接收,若無信號則繼續輪詢。形成多個點對點的收發系統。
一、問題1
Ø 問題現象描述:
Zigbee接收端輪詢信道,當發送端正常時
實驗一:1.若發送端由A信道發,可正確接收;2.若發送端由A+4信道發,則不可正確接收。
實驗二:1.若發送端由A信道發,可正確接收;2若發送端由A+2信道發,可正確接收;.3.若發送端由A+4信道發,可正確接收;
以上現象經確認與發送端無關,且接收端硬件復位無用。
Ø 問題分析
1.經過在接收中斷中加入LED燈閃,發現切換信道后沒有收到信息的原因是壓根沒有進入接收中斷。
2.沒有進入中斷,說明在從天線接下信號后的處理中,沒有正確分辨出信號。且切換信道主要是切換接收頻率。所以問題可能頻率有關。
3.點對點的情況下不會出現該問題。
4.在CC2530_userguide中找到frequency calibration相關的寄存器RFST的ISRXON指令。(在代碼中為由light_switch.c調用的basicRfReceiveOn()。)其作用Enable and calibrate frequency synthesizerfor RX。所以加入basicRfReceiveOn()與basicRfReceiveOff(),便解決問題。
二、問題2
Ø 問題現象描述:
Zigbee發送正常,當加入了basicRfReceiveOn()后,可以接收到所有信道信息,但是個別信道上信息會發生錯誤。
Ø 問題分析
1.改為點對點,即接收端不輪詢。因為加入了basicRfReceiveOn(),同樣也會出現問題,所以問題是由basicRfReceiveOn()引起的,而非輪詢等。
2.考慮到basicRfReceiveOn()有校正頻偏的作用,所以需要一定的時間,加入Delay問題解決。
三、問題3
Ø 問題現象描述:
Zigbee接收端運行一段時間會接收不到數據,經在中斷中加入LED燈閃和在接收while中加入打印,確定程序在運行,但沒有收到數據。
Ø 問題分析
1.發送端連續發送數據55 55 BB BB BB BB BB BB BB BB BB BB BB BB BB AA AA。
通過MATLAB仿真Zigbee調制,確定問題為發送序列過於有規律的問題。
可知,其頻譜如下:
當改為發送隨機信號時,其頻譜為
四、附:
A. light_switch.c最終版代碼

/*********************************************************************************** Filename: light_switch.c Description: This application function either as a light or a switch toggling the ligh. The role of the application is chosen in the menu with the joystick at initialisation. Push S1 to enter the menu. Choose either switch or light and confirm choice with S1. Joystick Up: Sends data from switch to light ***********************************************************************************/ /*********************************************************************************** * INCLUDES */ #include <hal_lcd.h> #include <hal_led.h> #include <hal_joystick.h> #include <hal_assert.h> #include <hal_board.h> #include <hal_int.h> #include "hal_mcu.h" #include "hal_button.h" #include "hal_rf.h" #include "util_lcd.h" #include "basic_rf.h" /*********************************************************************************** * CONSTANTS */ // Application parameters #define RF_CHANNEL 11 // 2.4 GHz RF channel // BasicRF address definitions #define PAN_ID 0x2007 #define SWITCH_ADDR 0x2520 #define LIGHT_ADDR 0xBEEF #define APP_PAYLOAD_LENGTH 18 //#define LIGHT_TOGGLE_CMD 0 // Application states #define IDLE 0 #define SEND_CMD 1 // Application role #define NONE 0 #define SWITCH 1 #define LIGHT 2 #define APP_MODES 2 #define LED P1_2 //定義LED為P12口控制 /*********************************************************************************** * LOCAL VARIABLES */ static uint8 pTxData[APP_PAYLOAD_LENGTH]; static uint8 pRxData[APP_PAYLOAD_LENGTH]; static basicRfCfg_t basicRfConfig; unsigned char Recdata[30]="CHENGDU JIALI TECH.INC\r\n"; unsigned char Recdata_bak[30]="CHENGDU JIALI TECH.INC\r\n"; unsigned char Recdata_consol[1]; unsigned char Testdata[1]; unsigned char RXTXflag = 1; unsigned char temp=0; unsigned int datanumber = 0; int flag=0; #ifdef SECURITY_CCM // Security key static uint8 key[]= { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, }; #endif /*********************************************************************************** * LOCAL FUNCTIONS */ static void appLight(); static void appSwitch(); void initUART_TX(void);//************************* void initUART_RX(void);//************************** void UartTX_Send_String(int8 *Data,int len);//********************** /**************************************************************** 發送ZIGBEE,初始化串口0函數 ****************************************************************/ void initUART_TX(void) { CLKCONCMD &= ~0x40; //設置系統時鍾源為32MHZ晶振 while(CLKCONSTA & 0x40); //等待晶振穩定 CLKCONCMD &= ~0x47; //設置系統主時鍾頻率為32MHZ PERCFG = 0x00; //位置1 P0口 P0SEL = 0x0c; //P0用作串口 // P0SEL = 0x0c; //P0用作串口 P2DIR &= ~0XC0; //P0優先作為UART0 U0CSR |= 0x80; //串口設置為UART方式 U0GCR |= 11; U0BAUD |= 216; //波特率設為115200 UTX0IF = 1; //UART0 TX中斷標志初始置位1 U0CSR |= 0X40; //允許接收 //IEN0 |= 0x84; //開總中斷,接收中斷 URX0IE=1; EA=1; } /**************************************************************** 接收ZIGBEE,串口初始化函數 ****************************************************************/ void initUART_RX(void) { PERCFG = 0x00; //位置1 P0口 P0SEL = 0x0c; //P0_2,P0_3用作串口(外部設備功能) P2DIR &= ~0XC0; //P0優先作為UART0 U0CSR |= 0x80; //設置為UART方式 U0GCR |= 11; U0BAUD |= 216; //波特率設為115200 UTX0IF = 0; //UART0 TX中斷標志初始置位0 } /**************************************************************** 串口發送字符串函數 ****************************************************************/ void UartTX_Send_String(int8 *Data,int len) { int j; for(j=0;j<len;j++) { U0DBUF = *Data++; while(UTX0IF == 0); UTX0IF = 0; } } void Delay(unsigned long n) { unsigned long tt; for(tt = 0;tt<n;tt++); for(tt = 0;tt<n;tt++); for(tt = 0;tt<n;tt++); for(tt = 0;tt<n;tt++); for(tt = 0;tt<n;tt++); } /*********************************************************************************** * @fn appLight * * @brief Application code for light application. Puts MCU in endless * loop waiting for user input from joystick. jiali * * @param basicRfConfig - file scope variable. Basic RF configuration data * pRxData - file scope variable. Pointer to buffer for RX data * * @return none jaalee */ static void appLight() { unsigned int i=1,j=0; int8 tmp; #ifdef ASSY_EXP4618_CC2420 halLcdClearLine(1); #endif // Initalise uart initUART_RX(); UartTX_Send_String("Begin~!!\n",10); // Initialize BasicRF basicRfConfig.myAddr = LIGHT_ADDR; basicRfConfig.channel = RF_CHANNEL+i; if(basicRfInit(&basicRfConfig)==FAILED) { HAL_ASSERT(FALSE); } basicRfReceiveOn(); LED=0; // Main loop while (TRUE) { basicRfConfig.myAddr = LIGHT_ADDR; basicRfConfig.channel = RF_CHANNEL+i; i=(i++)%16; if(basicRfInit(&basicRfConfig)==FAILED) { HAL_ASSERT(FALSE); } basicRfReceiveOn();//////////問題1時無此句//////////////////////////// Delay(800);//////////問題1時無此句//////////////////////////// if(basicRfPacketIsReady()) if(basicRfReceive(pRxData, APP_PAYLOAD_LENGTH, NULL)>0) { UartTX_Send_String(pRxData,APP_PAYLOAD_LENGTH);//////////////////////// } basicRfReceiveOff();//////////問題1時無此句//////////////////////////// } } /*********************************************************************************** * @fn appSwitch * * @brief Application code for switch application. Puts MCU in * endless loop to wait for commands from from switch * * @param basicRfConfig - file scope variable. Basic RF configuration data * pTxData - file scope variable. Pointer to buffer for TX * payload * appState - file scope variable. Holds application state * * @return none */ static void appSwitch() { // int flag=0; unsigned int i=0; #ifdef ASSY_EXP4618_CC2420 halLcdClearLine(1); #endif initUART_TX(); UartTX_Send_String("Begin~!!\n",10); // Initialize BasicRF basicRfConfig.channel = RF_CHANNEL+1; basicRfConfig.myAddr = SWITCH_ADDR; if(basicRfInit(&basicRfConfig)==FAILED) { HAL_ASSERT(FALSE); } // Keep Receiver off when not needed to save power basicRfReceiveOff(); datanumber=0; RXTXflag = 1; while(1) { /* if(RXTXflag == 3) //發送狀態 { U0CSR &= ~0x40; // UartTX_Send_String(Recdata,datanumber); U0CSR |= 0x40; //允許接收 RXTXflag = 1; //恢復到接收狀態 datanumber = 0; //指針歸0 LED=~LED; Recdata_consol[0]=0xac; UartTX_Send_String(Recdata_consol,1);//不能收數 flag=1; for(i=0;i<17;i++) { Recdata_bak[i]=Recdata[i]; } } */ if(flag==1) { basicRfSendPacket(LIGHT_ADDR, Recdata_bak, 18); } } } /*********************************************************************************** * @fn main * * @brief This is the main entry of the "Light Switch" application. * After the application modes are chosen the switch can * send toggle commands to a light device. * * @param basicRfConfig - file scope variable. Basic RF configuration * data * appState - file scope variable. Holds application state * * @return none */ void main(void) { unsigned int i=0; // Config basicRF basicRfConfig.panId = PAN_ID; basicRfConfig.channel = RF_CHANNEL; basicRfConfig.ackRequest = TRUE; #ifdef SECURITY_CCM basicRfConfig.securityKey = key; #endif // Initalise board peripherals halBoardInit(); // Initalise hal_rf if(halRfInit()==FAILED) { HAL_ASSERT(FALSE); } // Indicate that device is powered //appSwitch(); appLight(); } /**************************************************************** 串口接收一個字符:一旦有數據從串口傳至CC2530,則進入中斷,將接收到的數據賦值給變量temp. ****************************************************************/ #pragma vector = URX0_VECTOR __interrupt void UART0_ISR(void) { URX0IF = 0; //清中斷標志 temp = U0DBUF; int i; if(datanumber==0) { if(temp==0x55) Recdata[datanumber++] = temp; else { datanumber=0; } } else if(datanumber==1) { if(temp==0x55) Recdata[datanumber++] = temp; else { datanumber=0; } } else if(datanumber==15) { if(temp==0xaa) Recdata[1+datanumber++] = temp; else { datanumber=0; } } else if(datanumber==16) { if(temp==0xaa) { Recdata[1+datanumber++] = temp; Recdata[2]=2; RXTXflag = 3; U0CSR &= ~0x40; // UartTX_Send_String(Recdata,datanumber); U0CSR |= 0x40; //允許接收 RXTXflag = 1; //恢復到接收狀態 datanumber = 0; //指針歸0 LED=~LED; flag=1; for(i=0;i<18;i++) { Recdata_bak[i]=Recdata[i]; } } else { datanumber=0; } } else { Recdata[1+datanumber++] = temp; } temp = 0; }
B. ZIGBEE_OQPSK調制MATLAB代碼

clear all % close all D=[]; Data=[]; % data_hex='5555CCCCCCCCCCCCCCCCCCCCCCCCCCAAAA'; % data_hex='5555BBBBBBBBBBBBBBBBBBBBBBBBBBAAAA'; data_hex='51555086F61C3CA2F7C71A4B4C046ADAAAA'; data_map=[ '11011001110000110101001000101110'; '11101101100111000011010100100010'; '00101110110110011100001101010010'; '00100010111011011001110000110101'; '01010010001011101101100111000011'; '00110101001000101110110110011100'; '11000011010100100010111011011001'; '10011100001101010010001011101101'; '10001100100101100000011101111011'; '10111000110010010110000001110111'; '01111011100011001001011000000111'; '01110111101110001100100101100000'; '00000111011110111000110010010110'; '01100000011101111011100011001001'; '10010110000001110111101110001100'; '11001001011000000111011110111000']; for i=1:length(data_hex) tmp=hex2dec(data_hex(i)); Data=[Data data_map(tmp+1,:)]; end for i=1:2:length(Data) t=[Data(i) Data(i+1)]; T2=bin2dec(t); D=[D repmat(T2,1,fs/fb)]; end modObj = modem.oqpskmod; M1=modulate(modObj,D'); M=M1(3:length(M1)); N1=0:length(M)/2-1; N2=-length(M)/2:-1; N=[N1,N2]; figure,plot(N,abs(fft(M))); figure,plot(real(M),imag(M),'*');