📄 cc1000.c
字号:
/****************************************************************************/
/ */
/* DATE: 1st september 2005 */
/****************************************************************************/
// Includes
//--------------------------------------------------------
#include <c8051f310.h> // SFR declarations
//---------------------------------------------------------
// CC1000 Registers
//---------------------------------------------------------
#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_POW 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 0x1C111//?
#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
//------------------------------------------------------------
// RF Transceiver Register Routines
//------------------------------------------------------------
void WriteToCC1000Register(char addr, char Ddata);
char ReadFromCC1000Register(char addr);
void SetupCC1000RX(void);
void SetupCC1000TX(void);
//----------------------------------------------------------------
// RF CONTROL BIT Global Variables
//----------------------------------------------------------------
sbit PALE=P1^0;
sbit DIO_PIN=P0^4;
sbit DCLK_PIN=P0^5;
sbit key_test=P0^6;
//---------------------------------------------------------------
// 系统函数
//---------------------------------------------------------------
unsigned char count = 0;
unsigned char tx_count = 0;
unsigned char transfer=0x69;
unsigned char receive=0;
unsigned char tag=0;
unsigned char system_mode;
unsigned char tx_statemachine;
#define TX_MODE 0x01
#define RX_MODE 0x02
void initfunc(void); // Init Function
void INT1_ISR(void);
void waitus(unsigned char count); // delay Function
//---------------------------------------------------------------
// MAIN Routine
//---------------------------------------------------------------
void main (void)
{
char buffer[4];
char i=0;
char j=1;
bit x;
initfunc(); //初始化
while(1)
{
key_test = 1;
waitus(250);
waitus(250);
x=key_test;
if(x==0){ //-------------------------发送数据
IT01CF=0X55; //中断低电平有效,即下降沿有效
SetupCC1000TX();
system_mode=TX_MODE;
tx_statemachine=0xaa;
if(tx_count==3)
{ system_mode=RX_MODE;
IT01CF=0Xdd; //中断高电平有效,即上升沿有效
SetupCC1000RX();
tx_count=0; }
}
else
{ system_mode=RX_MODE; //------------------------- 接收状态
if(tag==1)
{if(receive==0xaa)
{ receive=0; i++; tag=0;
if(i<15) buffer[0]=0; }
else
{ if(i>=15)
{
if(i==15&&receive==0x33)
{ buffer[0]=0x33; tag=0; receive=0;}
else
{if(buffer[0]==0x33)
{ buffer[j++]=receive;
tag=0; receive=0;
if(j==4)
{j=1; i=0; tag=0; receive=0; buffer[0]=0;}
}
else {i=0; tag=0; receive=0; buffer[0]=0;}
}
}
else {i=0; tag=0; receive=0; buffer[0]=0;}
}
}
}
}
}
//------------------------------------------------------------
// INT1_ISR 中断服务程序
//-------------------------------------------------------------
void INT1_ISR(void) interrupt 2
{
bit DCLK_image;
DCLK_image = DCLK_PIN; // 低电平中断
if(system_mode==TX_MODE){
if(DCLK_image==1)
return;
if(tx_statemachine==0xaa){ //传输导波信号
if((0xaa<<(count%8))&0x80==0)
DIO_PIN=0;
else
DIO_PIN=1;
count ++;
if(count==120){
tx_statemachine = 0x33;
count = 0;
}
}
else if(tx_statemachine==0x33){ //传输同步信号
if((0x33<<(count%8))&0x80==0)
DIO_PIN=0;
else
DIO_PIN=1;
count ++;
if(count==8){
tx_statemachine = 1;
count =0;
}
}
else if(tx_statemachine==1){ //传输数据
if((transfer<<1)&0x80==0)
DIO_PIN=0;
else
DIO_PIN=1;
count ++;
if(count==8){
count = 0;
tx_count++;
}
}
}
else{
if(DCLK_image==0)
return;
receive=receive<<1;
if(DIO_PIN==1)
receive|=0x01;
count++;
if(count==8)
{ count=0; tag=1;}
}
}
//------------------------------------------------------------------------------
// 执行接收到的命令
//------------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Initialization Functions
//-----------------------------------------------------------------------------
void initfunc(void)
{ unsigned char cal_complete;
//--------------------系统初始化
OSCICL = 0X00;
OSCICN = 0xC3; // 设置内部振荡器频率为 24.5 MHz
CLKSEL = 0x00; // 选择系统时钟为内部振荡器
// OSCXCN = 0x67; // 设置外部振荡器方式为晶体振荡器方式, 晶体振荡器频率为10MHz<f<33MHz
// waitus(120); */ // 等待外部寄存器稳定,至少1ms
RSTSRC = 0x04; // RSTSRC = 00000100, 允许时钟丢失复位源,禁止其他复位源
//--------------------端口初始化
P0MDIN = 0xff;
P0MDOUT = 0xff;
P0SKIP = 0xff;
P0=0X00;
P1MDIN = 0xff;
P1MDOUT = 0xff;
P1SKIP = 0xf1;
P1=0X00;
P2MDIN = 0xff;
P2MDOUT = 0xff;
P2SKIP = 0xff;
P2=0X00;
P3MDIN = 0x1f;
P3MDOUT = 0x1f;
P3=0X00;
XBR0 = 0x02;
XBR1 = 0x40;
//----------------------SPI初始化
SPI0CFG = 0x51; // Master enable, CKPOL = 1
SPI0CKR = 11; // sets SPI clock to 1 MHz
SPI0CN = 0; // clear all flags
//----------------------外部中断1初始化
IE=0X84;
IT01CF=0Xdd; //中断高电平有效,即上升沿有效
IP=0X04;
EIE1=0X00;
EIP1=0X00;
//----------------------定时器0初始化,用作延时
TCON=0X04;
CKCON=0X02;
TMOD=0X22;
TL0=251;
TH0=251;
//--------------------cc1000初始化,活动模式,接进入接收或发送模式----------------
// MAIN:
WriteToCC1000Register(CC1000_MAIN,0x3a); // Turn on xtal oscillator core
WriteToCC1000Register(CC1000_MAIN,0x3b);
waitus(200); // wait for xtal oscillator to stabilize, typically takes 2ms.
// writes 24-bit frequency value used for TX to 914.9916 MHz.
// Check CC1000 data sheet for equations used to find
// 0x6c8000.
WriteToCC1000Register(CC1000_FREQ_2A, 0xba);
WriteToCC1000Register(CC1000_FREQ_1A, 0x00);
WriteToCC1000Register(CC1000_FREQ_0A, 0x00);
// writes 24-bit frequency value used for RX to 914.9916 MHz.
WriteToCC1000Register(CC1000_FREQ_2B, 0x5c);
WriteToCC1000Register(CC1000_FREQ_1B, 0xf3);
WriteToCC1000Register(CC1000_FREQ_0B, 0x13);
// sets frequency separation between 0 value and 1 value
WriteToCC1000Register(CC1000_FSEP1, 0x01);
WriteToCC1000Register(CC1000_FSEP0, 0xab);
// sets some internal current levels, and enables RSSI output to pin
WriteToCC1000Register(CC1000_CURRENT,0x8c); // Program VCO current for RX
WriteToCC1000Register(CC1000_FRONT_END,0x32);
WriteToCC1000Register(CC1000_PA_POW,0xff);
// sets the PLL reference divider to divide by 6
WriteToCC1000Register(CC1000_PLL,0x30);
// sets continuous lock indicator to output on the CHP_OUT pin
//SETREG(LOCK,0x10);
WriteToCC1000Register(CC1000_LOCK,0x20);
WriteToCC1000Register(CC1000_CAL,0x26);
// sets threshold level for peak detector (not used in this design)
WriteToCC1000Register(CC1000_MODEM2, 0x91);
// sets the averaging filter to free-running and controlled by writes
// to bit 4 of this register.
// Sets averaging filter sensitivity to .6dB worst-case loss of sensitivity
WriteToCC1000Register(CC1000_MODEM1, 0x6f);
// baud rate to 76.8, Transparent Asyn. UART, and crystal freq. to 14 MHz
WriteToCC1000Register(CC1000_MODEM0, 0x25);
// sets capacitor array values for RX and TX
WriteToCC1000Register(CC1000_MATCH, 0x10);
// disables dithering and data shaping
WriteToCC1000Register(CC1000_FSCTRL, 0x01);
// sets prescaling to nominal values
WriteToCC1000Register(CC1000_PRESCALER,0);
// sets charge pump current scaling factor, which determines the bandwidth of the PLL.
WriteToCC1000Register(CC1000_TEST4,0x25);
// Calibration Process RX,set transceiver to RX mode 开始校验
WriteToCC1000Register(CC1000_MAIN,0x11);
WriteToCC1000Register(CC1000_CURRENT,0x8c); // RX mode current
WriteToCC1000Register(CC1000_PLL,0x30);
WriteToCC1000Register(CC1000_CAL,0xA6); // begin calibration
cal_complete = 0;
do
{
cal_complete = ReadFromCC1000Register(CC1000_CAL);
} while (!(cal_complete & 0x08)); // spin until calibration is complete
WriteToCC1000Register(CC1000_CAL,0x26);
// TX Calibration
WriteToCC1000Register(CC1000_MAIN,0xE1); // set to TX mode
WriteToCC1000Register(CC1000_CURRENT,0xF3); // TX mode current
WriteToCC1000Register(CC1000_PLL,0x18);
WriteToCC1000Register(CC1000_PA_POW,0x00); // set output power to 0 during calibration
WriteToCC1000Register(CC1000_CAL,0xA6); // begin calibration
cal_complete = 0;
do
{
cal_complete = ReadFromCC1000Register(CC1000_CAL);
} while (!(cal_complete & 0x08)); // spin until finished
WriteToCC1000Register(CC1000_CAL,0x26);
WriteToCC1000Register(CC1000_MAIN,0x3b);
waitus(200); // wait for xtal oscillator to stabilize, 2ms.
WriteToCC1000Register(CC1000_MAIN,0x39);
waitus(20);
SetupCC1000RX(); // wait for 200us.
}
/*****************************以下为C1000 配置函数***************************/
/* This routine writes to a single CC1000 register */
/****************************************************************************/
void WriteToCC1000Register(char addr, char Ddata)
{ SPIEN = 1;
PALE = 0;
SPIF = 0;
SPI0DAT = (addr<<1) + 1;
while(!SPIF);
SPIF = 0;
PALE = 1;
SPI0DAT = Ddata;
while(!SPIF);
SPIEN = 0;
}
/****************************************************************************/
/* This routine reads from a single CC1000 register */
/****************************************************************************/
char ReadFromCC1000Register(char addr)
{
unsigned char ad;
SPIEN = 1;
PALE = 0;
SPIF = 0;
ad = addr;
SPI0DAT = ad << 1;
while(!SPIF);
SPI0DAT = 0xFF;
PALE = 1;
SPIF = 0;
while(!SPIF);
ad = SPI0DAT;
SPIEN = 0;
return ad;
}
/****************************************************************************/
/* This routine puts the CC1000 into RX mode (from TX). When switching to */
/* RX from PD, use WakeupC1000ToRX first */
/****************************************************************************/
void SetupCC1000RX(void)
{
WriteToCC1000Register(CC1000_MAIN,0x11); // Switch into RX, switch to freq. reg A
WriteToCC1000Register(CC1000_PLL,0X30); // Use RX refdiv setting
WriteToCC1000Register(CC1000_CURRENT,0x8c); // Program VCO current for RX
waitus(26); // wait for 260us.
}
/****************************************************************************/
/* This routine puts the CC1000 into TX mode (from RX). When switching to */
/* TX from PD, use WakeupCC1000ToTX first */
/****************************************************************************/
void SetupCC1000TX(void)
{
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,0X18); // Use TX refdiv setting
WriteToCC1000Register(CC1000_CURRENT,0xf3); // Program VCO current for TX
waitus(26); // wait for 260us.
WriteToCC1000Register(CC1000_PA_POW,0Xff); // Increase output power, Restore PA setting
waitus(2); // wait for 20us.
}
/****************************************************************************/
/* 延时子函数,each iteration of the for loop lasts approximately 10 us */
/****************************************************************************/
void waitus(unsigned char count)
{
unsigned char x;
TR0 = 1;
for(x = 0; x < count; x++)
{
TF0 = 0;
while(!TF0);
}
TF0 = 0;
TR0 = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -