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

📄 cc1000main.c

📁 CC1000为RF芯片
💻 C
📖 第 1 页 / 共 2 页
字号:
	    {
	        if (++Optctr > 100)
	        {
	            if (Optbuf == 0B00001000) {b_Mcode=YES;b_NRZ=NO;b_UART=NO;b_Tstbase=NO;}      		  
	            else if (Optbuf == 0B00000100) {b_Mcode=NO;b_NRZ=YES;b_UART=NO;b_Tstbase=NO;} 		  
	            else if (Optbuf == 0B00001100) {b_Mcode=NO;b_NRZ=NO;b_UART=YES;b_Tstbase=YES;} 
	            else {b_Mcode=NO;b_NRZ=NO;b_UART=YES;b_Tstbase=NO;} 					  	  
	            break;
	        }
	    }
    }

    CC1000Init();
    
    o_led1 = LOW;
    for(Temp1=8; ; )
    {
        CLRWDT();
        Dly1000(100);
    	if(--Temp1==0) break;
    }
    o_led1 = HIGH;
    PIR1   = 0;
}


//===========================================================
//=                                                         =
//===========================================================
void Dly5(INT8U i) 
{
    for( ; --i!=0 ; );
}

void Dly1000(INT8U i) 
{
    while(1)
    {
		NOP();
        Dly5(198);
        if (--i == 0) break;
    }
}


//===========================================================
//= Library in C language for configuring CC1000 RF Module  =
//= MCU: Picmicro family									=
//= Ver: 1.0												=
//= Designed by: Figo										=
//= Start Date:  2005-1-12									=
//=---------------------------------------------------------=
//= Revision History										=
//= V1.0: Orginal Version                                   =
//===========================================================


//===========================================================================
//= This routine writes to a single CC1000 register                         =
//===========================================================================
void WriteToCC1000Register(INT8U addr, INT8U data)
{
    INT16U val;
    
    val=((INT16U)(addr&0x7F)) << 9 | (INT16U)data & 0x00FF;
    WriteToCC1000RegisterWord(val);
}


//===========================================================================
//= This routine writes to a single CC1000 register, with address and data  =
//= given in the same variable                                              =
//===========================================================================
void WriteToCC1000RegisterWord(INT16U addranddata)
{
    INT8U  BitCounter;
    
    union 
    {     // This union is used to easily access the most significant
                // bit of the configuration data
              
              // Note : This assumes that the C compiler stores bit-fields
              // with the first field going into the LSB. If this is not the
              // case, move the MSB definition to the first bit
        INT16U Data;
        struct
        {
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U :1;
            INT16U MSB :1;
        } W;
    } wdun;
  
    o_pale=1;

    wdun.Data=addranddata;
    o_pale=0;
    
    // Send address bits 
    for (BitCounter=0;BitCounter<7;BitCounter++)
    {
        o_pclk    = 1;
        o_pdata   = wdun.W.MSB;
        wdun.Data = wdun.Data<<1;
        o_pclk    = 0;
    }
  
    // Send read/write bit, Ignore bit in data, always use 1 
    o_pclk  = 1;
    o_pdata = 1;
    o_pclk  = 0;
    wdun.Data = wdun.Data<<1;
    o_pclk  = 1;
    o_pale  = 1;
    
    // Send data bits 
    for (BitCounter=0;BitCounter<8;BitCounter++)
    {
        o_pclk  = 1;
        o_pdata = wdun.W.MSB;
        wdun.Data = wdun.Data<<1;
        o_pclk  = 0;
    }
    o_pclk = 1;
}


//===========================================================================
//= This routine reads from a single CC1000 register                        =
//===========================================================================
INT8U ReadFromCC1000Register(INT8U addr)
{
    INT8U BitCounter;
 
    union 
    {     // This unit is used to easily access the most significant 
              // bit of the configuration data 

              // Note : This assumes that the C compiler stores bit-fields 
              // with the first field going into the LSB. If this is not the 
              // case, switch the MSB and LSB definitions 
        INT8U Data;
        struct
        {
            INT8U LSB :1;
            INT8U :1;
            INT8U :1;
            INT8U :1;
            INT8U :1;
            INT8U :1;
            INT8U :1;
            INT8U MSB :1;
        } B;
    } byun;
  
    o_pale=1;
  
    byun.Data=addr<<1;
    o_pale=0;
    
    // Send address bits
    for (BitCounter=0;BitCounter<7;BitCounter++)
    {
        o_pclk=1;
        o_pdata=byun.B.MSB;
        byun.Data=byun.Data<<1;
        o_pclk=0;
    }
    
    // Send read/write bit , Ignore bit in data, always use 0 
    o_pclk=1;
    o_pdata=0;
    o_pclk=0;
 
    o_pclk=1;
    o_pale=1;
    
    // Receive data bits 
    o_pdata=1;
   
    TRISA |= 0B00000100; // Set up o_pdata(RA2) as an input
    
    for (BitCounter=0;BitCounter<8;BitCounter++)
    {
        o_pclk=0;
        byun.Data=byun.Data<<1;
        byun.B.LSB=o_pdata;
        o_pclk=1;
    }
  
    TRISA &= 0B11111011; // Set up o_pdata(RA2) as an output again
  
    return byun.Data;
}


  
//===========================================================================
//= This routine resets the CC1000, clearing all registers.                 =
//===========================================================================
void ResetCC1000(void)
{
  INT8U MainValue;
  
  MainValue=ReadFromCC1000Register(CC1000_MAIN);
  WriteToCC1000Register(CC1000_MAIN, MainValue&0xFE); // Reset CC1000
  WriteToCC1000Register(CC1000_MAIN, MainValue|0x01); // Bring CC1000 out of reset
}


//===========================================================================
//= This routine calibrates the CC1000                                      =
//= Returns 0 if calibration fails, non-zero otherwise. Checks the LOCK     =
//= to check for success.                                                   =
//===========================================================================

INT8U CalibrateCC1000(void)
{
    INT8U TimeOutCounter;

    WriteToCC1000Register(CC1000_PA_POW,0x00);  // Turn off PA to avoid spurs
                                                // during calibration in TX mode
    WriteToCC1000Register(CC1000_CAL,0xA6);     // Start calibration
  
    // Wait for calibration complete
    for(TimeOutCounter=CAL_TIMEOUT; ((ReadFromCC1000Register(CC1000_CAL)&0x08)==0)&&(TimeOutCounter>0); TimeOutCounter--);

    WriteToCC1000Register(CC1000_CAL,0x26); /* End calibration */
    WriteToCC1000Register(CC1000_PA_POW,PA_VALUE); /* Restore PA setting */

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

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


//===========================================================================
//= This routine puts the CC1000 into RX mode (from TX). When switching to  =
//= RX from PD, use WakeupC1000ToRX first                                   =
//===========================================================================
INT8U SetupCC1000RX(INT8U RXCurrent)
{
    INT16U i;
    INT8U  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 for 250us before monitoring LOCK
    for (i=0;i<25;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
    {   // Else (PLL out of LOCK)
        
        if(CalibrateCC1000())
        {   // If recalibration ok
            lock_status = LOCK_RECAL_OK; // Indicate PLL in LOCK
        }
        else
        {   // Else (recalibration failed)
            // 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);
}



//===========================================================================
//= This routine puts the CC1000 into TX mode (from RX). When switching to  =
//= TX from PD, use WakeupCC1000ToTX first                                  =
//===========================================================================
INT8U SetupCC1000TX(INT8U TXCurrent)
{
    INT16U i;
    INT8U lock_status;

    WriteToCC1000Register(CC1000_PA_POW,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 for 250us before monitoring LOCK
    for (i=0;i<25;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
    {   // Else (PLL out of LOCK)
        // If recalibration ok
        if(CalibrateCC1000())
        {
            // Indicate PLL in LOCK
            lock_status = LOCK_RECAL_OK;
        }
        else
        {   // Else (recalibration failed)
            // Reset frequency syncthesizer (ref.: Errata Note 01)
            ResetFreqSynth();
            // Indicate PLL out of LOCK
            lock_status = LOCK_NOK;
        }
    }

    // Increase output power
    WriteToCC1000Register(CC1000_PA_POW,PA_VALUE); // Restore PA setting

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



//===========================================================================
//= This routine puts the CC1000 into power down mode. Use WakeUpCC1000ToRX =
//= followed by SetupCC1000RX or WakeupCC1000ToTX followed by SetupCC1000TX =
//= to wake up from power down                                              =
//===========================================================================
void SetupCC1000PD(void)
{
    WriteToCC1000Register(CC1000_MAIN,0x3F);    // Put CC1000 into power-down
    WriteToCC1000Register(CC1000_PA_POW,0x00);  // Turn off PA to minimise current draw
}


//===========================================================================
//= This routine wakes the CC1000 up from PD mode to RX mode, call          =
//= SetupCC1000RX after this routine is finished.                           =
//===========================================================================
void WakeUpCC1000ToRX(INT8U RXCurrent)
{
    INT16U i;
  
    WriteToCC1000Register(CC1000_MAIN,0x3B);  // Turn on xtal oscillator core
    WriteToCC1000Register(CC1000_CURRENT,RXCurrent); // Program VCO current for RX 
    WriteToCC1000Register(CC1000_PLL,RXPLL); // Use RX refdiv setting
  
    // Insert wait routine here, must wait for xtal oscillator to stabilise, 
    // typically takes 2-5ms.
    for (i=0;i<450;i++);
  
    WriteToCC1000Register(CC1000_MAIN,0x39);  // Turn on bias generator
    // Wait for 250us, insert wait loop here
    for (i=0;i<25;i++);
    WriteToCC1000Register(CC1000_MAIN,0x31);  // Turn on frequency synthesiser
}



//===========================================================================
//= This routine wakes the CC1000 up from PD mode to TX mode, call          =
//= SetupCC1000TX after this routine is finished.                           =
//===========================================================================
void WakeUpCC1000ToTX(INT8U TXCurrent)
{
    INT16U i;

    WriteToCC1000Register(CC1000_MAIN,0xFB);  // Turn on xtal oscillator core
    WriteToCC1000Register(CC1000_CURRENT,TXCurrent); // Program VCO current for TX
    WriteToCC1000Register(CC1000_PLL,TXPLL); // Use TX refdiv setting
  
    // Insert wait routine here, must wait for xtal oscillator to stabilise, 
    // typically takes 2-5ms. 
    for (i=0;i<450;i++);
  
    WriteToCC1000Register(CC1000_MAIN,0xF9);  // Turn on bias generator
    // Wait for 250us, insert wait loop here
    for (i=0;i<25;i++);
    WriteToCC1000Register(CC1000_PA_POW,PA_VALUE); // Turn on PA
    WriteToCC1000Register(CC1000_MAIN,0xF1);  // Turn on frequency synthesiser
}

/****************************************************************************/
/*  This routine locks the averaging filter of the CC1000                   */
/****************************************************************************/
void AverageManualLockCC1000(void)
{
    WriteToCC1000Register(CC1000_MODEM1,0x79); //0x19
}

/****************************************************************************/
/*  This routine unlocks the averaging filter of the CC1000                 */
/****************************************************************************/
void AverageFreeRunCC1000(void)
{
    WriteToCC1000Register(CC1000_MODEM1,0x69); //0x09
}

/****************************************************************************/
/*  This routine sets up the averaging filter of the CC1000 for automatic   */
/*  lock. This can be used in polled receivers.                             */
/****************************************************************************/
void AverageAutoLockCC1000(void)
{
    WriteToCC1000Register(CC1000_MODEM1,0x01);
}


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



//===========================================================================
//= CC1000初始化            	  			                                =
//===========================================================================
void CC1000Init(void)
{
    SetupCC1000PD();
    ResetCC1000();
    SetupCC1000All();
    WakeUpCC1000ToRX(RXDL);
    SetupCC1000TX(TXDL);  
    CalibrateCC1000();              	
    SetupCC1000RX(RXDL);
    CalibrateCC1000();
 
    //现在CC1000接收和发送均已被校准,我们不再需要重新
    //校准,除非频率改变或温度改变超过40度或电源电压改变超过0.5V
}



/**************************************************************************/
/*  设置所有的CC1000寄存器         					                      */
/*************************************************************************/
void SetupCC1000All(void)
{ 
    INT8U counter;
    INT8U value;
  
    for (counter=CC1000_FREQ_2A; counter <= CC1000_PRESCALER; counter++) 
    {
        if (counter == CC1000_MODEM0)
        {
            if (b_Mcode == YES) value = 0x27;	// 2.4kBaud Mcode
            if (b_NRZ   == YES) value = 0x23;	// 2.4kBaud NRZ
            if (b_UART  == YES) value = 0x2B; 	// 2.4kBaud UART
        }
        else
        {
            value=DefaultConfig[counter-1];
        }
        WriteToCC1000Register(counter,value);
    }
    
    for (counter = CC1000_TEST6; counter <= CC1000_TEST0; counter++)
    {
        value=DefaultConfig[counter - CC1000_TEST6 + CC1000_PRESCALER];
        WriteToCC1000Register(counter,value);
    }
}

⌨️ 快捷键说明

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