首页 > 技术文章 > CC2530调试过程中遇到的问题们

ben-ben 2013-07-21 20:49 原文

应用场景描述:

多个发送端在不同的信道上发送信息(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相关的寄存器RFSTISRXON指令。(在代码中为由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;
 }
View Code

 

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),'*');
View Code

 

 

 

 

 

推荐阅读