⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cc1000.c

📁 CC1000 RF芯片的初始化及发送程序
💻 C
字号:

#pragma sfr
#pragma nop

#define PCLK   P2.0
#define PALE   P2.1
#define PDATA  P2.2
#define  PDATA_mode  PM2.2

/* Register addresses */

#define CC1000_MAIN            0x00
#define CC1000_FREQ_2A         0x01
#define CC1000_FREQ_1A         0x02
#define CC1000_FREQ_0A         0x03
#define CC1000_FREQ_2B         0x04
#define CC1000_FREQ_1B         0x05
#define CC1000_FREQ_0B         0x06
#define CC1000_FSEP1           0x07
#define CC1000_FSEP0           0x08
#define CC1000_CURRENT         0x09
#define CC1000_FRONT_END       0x0A
#define CC1000_PA_PDW          0x0B
#define CC1000_PLL             0x0C
#define CC1000_LOCK            0x0D
#define CC1000_CAL             0x0E
#define CC1000_MODEM2          0x0F
#define CC1000_MODEM1          0x10
#define CC1000_MODEM0          0x11
#define CC1000_MATCH           0x12
#define CC1000_FSCTRL          0x13
#define CC1000_FSHAPE7         0x14
#define CC1000_FSHAPE6         0x15
#define CC1000_FSHAPE5         0x16
#define CC1000_FSHAPE4         0x17
#define CC1000_FSHAPE3         0x18
#define CC1000_FSHAPE2         0x19
#define CC1000_FSHAPE1         0x1A
#define CC1000_FSDELAY         0x1B
#define CC1000_PRESCALER       0x1C
#define CC1000_TEST6           0x40
#define CC1000_TEST5           0x41
#define CC1000_TEST4           0x42
#define CC1000_TEST3           0x43
#define CC1000_TEST2           0x44
#define CC1000_TEST1           0x45
#define CC1000_TEST0           0x46

#define  LOCK_NOK         0x00
#define  LOCK_OK          0x01
#define  LOCK_RECAL_OK    0x02

#define TXCurrent 0xF3
#define RXCurrent 0x8C

// Value of time-out timer during calibration
#define CAL_TIMEOUT   0x7FFE
#define LOCK_TIMEOUT  0x7FFE

// PA power setting
#define PA_VALUE 0xF0


sreg unsigned char addr;
sreg unsigned char data;

// 869.850 MHz, +5 dBm output (Europe)                                                          // address
const unsigned char DefaultConfig868[35] = {0x58,0x60,0x00,0x58,0x5B,0x43,0x01,0xAB,0x8C,0x32,  // 01 ~ 0a
                                            0xFF,0x30,0x10,0x26,0x90,0x69,0x07,0x10,0x01,0x1c,  // 0b ~ 14
                                            0x16,0x10,0x0A,0x06,0x03,0x01,0x0F,0x00,0x00,0x00,  // 15 ~ 1c, 40,41
                                            0x3F,0x00 }; 
const unsigned char TXPLL = 0x30;
const unsigned char RXPLL = 0x30;


void WriteToCC1000Register(char reg_addr, char reg_data)
{
 
  unsigned char  BitCounter;
  PDATA_mode = 0;
  
  addr = reg_addr;
  data = reg_data;
  
  PALE=1;
  NOP();
  PALE=0;
    
  for (BitCounter=0;BitCounter<7;BitCounter++)
  {
    PCLK=1;
    addr=addr<<1;
    PDATA = addr.7 ;
    NOP();
    PCLK=0;
  }
  
  NOP();
  PCLK=1;
  PDATA=1;
  NOP();
  PCLK=0;
  NOP();
  PCLK=1;
  NOP();
  PALE=1;

  for (BitCounter=0;BitCounter<8;BitCounter++)
  {
    PCLK=1;
    PDATA = data.7 ;
    data=data<<1;
    NOP();
    PCLK=0;
  }
  
  NOP();
  PCLK=1;
}

unsigned char ReadFromCC1000Register(char read_addr)
{

  unsigned char  BitCounter;
  
  addr = read_addr;
  
  PDATA_mode = 0;
  
  PALE=1;
  NOP();
  PALE=0;
    
  for (BitCounter=0;BitCounter<7;BitCounter++)
  {
    PCLK=1;
    addr=addr<<1;
    PDATA = addr.7 ;
    NOP();
    PCLK=0;
  }
  
  NOP();
  PCLK=1;
  PDATA=0;
  NOP();
  PCLK=0;
  NOP();
  PCLK=1;
  NOP();
  PALE=1;
  NOP();
  NOP();
  PDATA_mode = 1;
  NOP();
  NOP();
  
  for (BitCounter=0;BitCounter<8;BitCounter++)
  {
    PCLK=0;
    data = data<<1;
    data.0 = PDATA;
    NOP();
    PCLK=1;
  }
  
  NOP();
  PCLK=1;
  
  return(data);
   
}

/****************************************************************************/
/*  This routine set up all register of CC1000.                             */
/****************************************************************************/  

void SetupCC1000All()
{
  unsigned char counter;
  unsigned char value;
  
  for (counter=0x01;counter<=0x1C;counter++) {
    value=DefaultConfig868[counter-1];
    WriteToCC1000Register(counter,value);
  }
  

  for (counter=0x40;counter<=0x44;counter++) {
    value=DefaultConfig868[counter-0x40+0x1C];
    WriteToCC1000Register(counter,value);
  }
  
}

/****************************************************************************/
/*  This routine resets the CC1000, clearing all registers.                 */
/****************************************************************************/  

void ResetCC1000()
{
  unsigned int i;
  unsigned char MainValue;
  
  MainValue=ReadFromCC1000Register(CC1000_MAIN);
  WriteToCC1000Register(CC1000_MAIN,MainValue & 0xFE);         // Reset CC1000
  WriteToCC1000Register(CC1000_MAIN,MainValue | 0x01);         // Bring CC1000 out of reset
  for (i=0;i<0x10000;i++);
}


void CalibrateCC1000()
{
  unsigned int i;
//  unsigned int TimeOutCounter;

  WriteToCC1000Register(CC1000_MAIN,0x11);
  WriteToCC1000Register(CC1000_CAL,0xA6); // Start calibration
  
  // Wait for calibration complete
//  for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1000Register(CC1000_CAL)&0x08)==0)&&(TimeOutCounter>0); TimeOutCounter--);

  // Wait for lock
//  for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(TimeOutCounter>0); TimeOutCounter--);
  for (i=0;i<0x50000;i++);
  
  WriteToCC1000Register(CC1000_CAL,0x26); /* End calibration */
  
  WriteToCC1000Register(CC1000_PA_PDW,0x00); // Turn off PA to avoid spurs
                                             // during calibration in TX mode  
  WriteToCC1000Register(CC1000_MAIN,0xE1);
  WriteToCC1000Register(CC1000_CAL,0xA6); // Start calibration
  
  for (i=0;i<0x50000;i++);
  // Wait for calibration complete
//  for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1000Register(CC1000_CAL)&0x08)==0)&&(TimeOutCounter>0); TimeOutCounter--);

  // Wait for lock
//  for(TimeOutCounter=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(TimeOutCounter>0); TimeOutCounter--);
  
  WriteToCC1000Register(CC1000_CAL,0x26); /* End calibration */
  
  WriteToCC1000Register(CC1000_MAIN,0xFB); 
  
  for (i=0;i<0x50000;i++);

//  return ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==1);
}

/****************************************************************************/
/*  This routine resets the CC1000 frequency synthesizer                    */
/****************************************************************************/
void ResetFreqSynth()
{
  unsigned char modem1_value;
  modem1_value = ReadFromCC1000Register(CC1000_MODEM1)&~0x01;
  WriteToCC1000Register(CC1000_MODEM1,modem1_value);
  WriteToCC1000Register(CC1000_MODEM1,modem1_value|0x01);
}

/****************************************************************************/
/*  This routine puts the CC1000 into RX mode (from TX). When switching to  */
/*  RX from PD, use WakeupC1000ToRX first                                   */
/****************************************************************************/


void SetupCC1000ToRX()
{
  unsigned int i;
  unsigned char lock_status;

  WriteToCC1000Register(CC1000_MAIN,0x11);    // Switch into RX, switch to freq. reg A
  WriteToCC1000Register(CC1000_PLL,RXPLL);   // Use RX refdiv setting
  WriteToCC1000Register(CC1000_CURRENT,RXCurrent); // Program VCO current for RX

  // Wait 250us before monitoring LOCK
  for (i=0;i<0x1000;i++);

  // Wait for lock
//  for(i=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0)&&(i>0); i--);

  // If PLL in lock
//  if ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0x01){
    // Indicate PLL in LOCK
 //   lock_status = LOCK_OK;
  // Else (PLL out of LOCK)
 // }else{
    // If recalibration ok
 //   if(CalibrateCC1000()){
      // Indicate PLL in LOCK
 //     lock_status = LOCK_RECAL_OK;
    // Else (recalibration failed)
 //   }else{
      // Reset frequency syncthesizer (ref.: Errata Note 01)
  //    ResetFreqSynth();
      // Indicate PLL out of LOCK
  //    lock_status = LOCK_NOK;
 //   }
//  }

  // Return LOCK status to application
//  return (lock_status);
}

void StopCC1000RX()
{
   WriteToCC1000Register(CC1000_MAIN,0x3B);
}

/****************************************************************************/
/*  This routine puts the CC1000 into TX mode (from RX). When switching to  */
/*  TX from PD, use WakeupCC1000ToTX first                                  */
/****************************************************************************/

void SetupCC1000ToTX()
{
  unsigned int i;
  unsigned char lock_status;

  WriteToCC1000Register(CC1000_PA_PDW,0x00);   // Turn off PA to avoid frequency splatter

  WriteToCC1000Register(CC1000_MAIN,0xE1);    // Switch into TX, switch to freq. reg B
  WriteToCC1000Register(CC1000_PLL,TXPLL);   // Use TX refdiv setting
  WriteToCC1000Register(CC1000_CURRENT,TXCurrent); // Program VCO current for TX

  // Wait 250us before monitoring LOCK
  for (i=0;i<0x1000;i++);
  
  // Wait for lock
 // for(i=LOCK_TIMEOUT; ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0x00)&&(i>0); i--);

  // If PLL in lock
 // if ((ReadFromCC1000Register(CC1000_LOCK)&0x01)==0x01){
    // Indicate PLL in LOCK
 //   lock_status = LOCK_OK;
  // Else (PLL out of LOCK)
 // }else{
    // If recalibration ok
 //   if(CalibrateCC1000()){
      // Indicate PLL in LOCK
 //     lock_status = LOCK_RECAL_OK;
    // Else (recalibration failed)
 //   }else{
      // Reset frequency syncthesizer (ref.: Errata Note 01)
 //     ResetFreqSynth();
      // Indicate PLL out of LOCK
 //     lock_status = LOCK_NOK;
 //   }
//  }

  // Increase output power
  WriteToCC1000Register(CC1000_PA_PDW,PA_VALUE); // Restore PA setting
  
  for (i=0;i<0x100;i++);

  // Return LOCK status to application
 // return (lock_status);
}

void StopCC1000TX()
{
   WriteToCC1000Register(CC1000_MAIN,0x3B);
   WriteToCC1000Register(CC1000_PA_PDW,0x00);
}


/****************************************************************************/
/*  This routine locks the averaging filter of the CC1000                   */
/****************************************************************************/

void AverageManualLockCC1000()
{
  WriteToCC1000Register(CC1000_MODEM1,0x19);
}

/****************************************************************************/
/*  This routine unlocks the averaging filter of the CC1000                 */
/****************************************************************************/

void AverageFreeRunCC1000()
{
  WriteToCC1000Register(CC1000_MODEM1,0x09);
}



/****************************************************************************/
/*  This routine sets up the averaging filter of the CC1000 for automatic   */
/*  lock. This can be used in polled receivers.                             */
/****************************************************************************/

void AverageAutoLockCC1000()
{
  WriteToCC1000Register(CC1000_MODEM1,0x01);
}

/****************************************************************************/
/*  This routine reads the current calibration values from the CC1000       */
/****************************************************************************/

void ReadCurrentCalibration(unsigned char *val1, unsigned char *val2)
{
  *val1=ReadFromCC1000Register(CC1000_TEST0);
  *val2=ReadFromCC1000Register(CC1000_TEST2);
}


/****************************************************************************/
/*  This routine overrides the current calibration of the CC1000            */
/****************************************************************************/

void OverrideCurrentCalibration(unsigned char val1, unsigned char val2)
{
  WriteToCC1000Register(CC1000_TEST5,(val1&0x0F)|0x10);
  WriteToCC1000Register(CC1000_TEST6,(val2&0x1F)|0x20);
}

/****************************************************************************/
/*  This routine stops override of the CC1000 calibration values            */
/****************************************************************************/

void StopOverridingCalibration()
{
  WriteToCC1000Register(CC1000_TEST5,0x00);
  WriteToCC1000Register(CC1000_TEST6,0x00);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -