📄 cc1000main.c
字号:
{
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 + -