2.4G无线数据模块(CC2500芯片)
频率范围:2400-2483.5Mhz (90信道)
最大速率:500K
调制方式:MSK,QPSK在500Kbps, GFSK ,OOK在250kbps
RF输出功率:0dBm
灵敏度: -101dBm在10Kbps 1%
编程接口:SPI数字接口
电压:1.8-3.6V
最大功耗:20mA
封装形式:COB
模块尺寸:11 X 15 X 8mm (长X宽X高)
天线形式:PCB天线
最大距离:100米
应用范围:工业数据传输,无线遥控,无线鼠标,无线键盘,无线电子标签,遥控玩具,自动化数据采集系统;工业无线控制;水、气、热、电等居民计量表具无线远传自动抄表程序:
bank1 BYTE paTable_CC1100[] = {0xc0, 0xc8, 0x85, 0x51, 0x3a, 0x06, 0x1c, 0x6c }; //CC1100发射功率表
bank1 BYTE paTable_CC2500[] = {0xFF, 0xFE, 0xBB, 0xA9, 0x7F, 0x6E, 0x97, 0xC5 }; //CC2500发射功率表
BYTE txBuffer_CCxx00[] = {0x0c, 1, 1,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}; //发射缓冲
BYTE rxBuffer_CCxx00[0x0c]; //接收缓冲
BYTE dpybuffer[10]={0x11,0xF9,0x23,0x61,0xC9,0x45,0x05,0xF1,0x01,0x41};//数码管显示的数据:0,1,2,3,4,5,6,7,8,9
unsigned char TXBuffer[]={0x55,0x55,0x55,0x55,0x55,0xCA,0x01,0x00}; //cc1000
unsigned char RXBuffer[3]; //cc1000
//////////////////////////////////////////////////////////////////////
//
// 中断子程序,用于CC1000的RX和TX
// IN:NONE
// OUT:NONE
//====================================================================
static void interrupt
isr(void)
{
if(INTF)
{
switch (State)
{
case 2: //TX_STATE:发送数据状态
if(ShiftReg&0x80) DIO="1";
else DIO=0;
ShiftReg=ShiftReg<<1;
BitCounter++;
if(BitCounter==8)
{
BitCounter=0;
ShiftReg=TXBuffer[TXBufferIndex1++];//从BUFFER里取数据
if(TXBufferIndex1>8)//判断是否发完
{ //完成
flag.TX_End=1;
TXBufferIndex1=0;
BitCounter = 0;
ShiftReg = 0x00;
RXBufferWriteIndex=0;
State=IDLE_STATE;
while(!DCLK) ;
while(DCLK) ;
DIO=0;
}
}
break;
case 1: //RX_STATE:接收数据状态
if(flag.PreambleEnd) //前导码接收完了吗?
{ //是
l_start_rec:
ShiftReg=ShiftReg<<1;
if(DIO) ShiftReg="ShiftReg|0x01";
else ShiftReg="ShiftReg"&0xFE;
BitCounter++;
if(BitCounter==8)
{
BitCounter=0;
RXBuffer[RXBufferWriteIndex]=ShiftReg;//保存到BUFFER
RXBufferWriteIndex++;
if(RXBufferWriteIndex>BytesToReceive) //判断是否接收完成
{ //接收完成
flag.RX_OK=1;
BitCounter=0;
RXBufferWriteIndex=0;
State=IDLE_STATE;
GIE = 0;
}
}
}
else
{
flag.PreambleFound=0;
if(flag.PreambleNextbit)
{
if(DIO) flag.PreambleNextbit=0;
else
{
flag.PreambleFound=0; //error
State=IDLE_STATE;
}
}
else
{
if(!DIO) flag.PreambleNextbit=1;
else
{
flag.PreambleEnd=1;
BitCounter=0;
goto l_start_rec; //前导码接收完成,跳到接收同步字和数据
}
}
}
break;
case 0: //IDLE_STATE:空闲状态,等待前导码
if(flag.PreambleNextbit)
{
if(DIO)
{
flag.PreambleNextbit=0;
BitCounter++;
if(BitCounter==24)
flag.PreambleFound=1;
}
else
{
flag.PreambleNextbit=0; //error
BitCounter=0;
}
}
else
{
if(!DIO)
{
flag.PreambleNextbit=1;
BitCounter++;
}
else
{
flag.PreambleNextbit=0; //error
BitCounter=0;
}
}
if(flag.PreambleFound)
{
BitCounter=0;
ByteCounter=0;
RXBufferWriteIndex=0;
flag.PreambleEnd=0;
State = RX_STATE;
}
break;
default:
State=IDLE_STATE;
break;
}
INTF=0;
}
}
/////////////////////////////////////////////////////////////
//
//initialize PIC16F877A
//
/////////////////////////////////////////////////////////////
void InitPIC16F877A() {
// TRISA=RACNF;
TRISB=RBCNF;
TRISC=RCCNF;
CMCON=0x07; //COMPARATOR OFF
ADCON1=0x06; //ADC OFF
TRISE=0;
OPTION=0x07;
T1CON=0x31;
INTCON=0;
TMR1ON=1;
// UART initialize
SPBRG=0x19;
TXSTA=0xa4;
RCSTA=0x90;
// RCIE=1;
PORTC=0X00; //数码管 On
Dly1mS(100);
}
//=============================================================
//初始化CC1100或CC2500,并切换到接收状态
//=============================================================
void SetupCCxx00(void)
{
TRISA=RACNF_RF4;
P_SCLK=0;
P_CSn=1;
P_SI=0;
POWER_UP_RESET_CCxxx0();
if(Current_Mode==CC1100_Mode)
{
halRfWriteRfSettings_CC1100();
halSpiWriteBurstReg(CCxxx0_PATABLE, paTable_CC1100, sizeof(paTable_CC1100));
}
else
{
halRfWriteRfSettings_CC2500();
halSpiWriteBurstReg(CCxxx0_PATABLE, paTable_CC2500, sizeof(paTable_CC2500));
}
halSpiStrobe(CCxxx0_SCAL);
Dly1mS(2);
halSpiStrobe(CCxxx0_SRX);
}
///////////////////////////////////////////////////////////////
//初始化CC1000,并切换到接收状态,允许外部中断
///////////////////////////////////////////////////////////////
void SetupCC1000(void)
{
TRISA=RACNF_RF2;
PCLK=1;
PDATA=1;
PALE=1;
SetupCC1000PD();
ResetCC1000();
ConfigureCC1000();
WakeUpCC1000ToTX(0x81,0x48);
TRISB&=~(0x02); // Set DIO as output
while(!CalibrateCC1000());
WakeUpCC1000ToRX(0x44,0x60);
TRISB|=0x02; // Set DIO as input
while(!CalibrateCC1000());
SetupCC1000RX(0x44,0x60);
State=IDLE_STATE;
INTEDG = 1; // rising edge trigger the interrupt
INTE = 1; // enable the external interrupt
PEIE=1;
GIE = 1; // Global interrupt enable
}
//=============================================================
//上电时检测按键,来辨别要工作在哪种模式
//=============================================================
void CheckState(void)
{
Current_key=PORTB|0xc3;
switch(Current_key)
{
case SW1_KEY:
Current_Mode=CC2500_Mode;
break;
case SW2_KEY:
Current_Mode=CC1000_Mode;
break;
case SW3_KEY:
Current_Mode=CC1100_PA_Mode;
break;
default:
Current_Mode=CC1100_Mode;
break;
}
while((PORTB|0xc3)!=0xff) ; //等待按键释放
PORTC=0Xff; //数码管 Off
OPTION=0x07;
}
//=============================================================
// scan key扫描按键
// IN:NONE
// OUT:Keyflag:1有键按下;0:无新的按键
//=============================================================
BYTE KeyScan(void)
{
OPTION=0x07;
TMR0=0; T0IF=0;
while(1)
{
if(T0IF) goto l_exit_key;
Dly1mS(2);
Current_key=PORTB|0xc3;
if(Current_key!=Old_key)
{
Dly1mS(20);
Current_key=PORTB|0xc3;
if(Current_key!=Old_key)
{
Old_key=Current_key;
if(Old_key!=0xff)
{
Keyflag=1;
goto l_exit_key;
}
else
Keyflag=0;
}
else
Keyflag="0";
}
else
Keyflag=0;
}
l_exit_key:
OPTION=0x87;
return(Keyflag);
}
//------------------------------------------------------------
// TX OPTION CC1100,CC2500发射数据
//
//-------------------------------------------------------------
void TxCCxx00()
{
unsigned char i;
// halSpiWriteReg(0x3E,0xC0);
halSpiWriteReg(CCxxx0_FREND0, 0x10);//CC1100:POWER=10DBM;CC2500:1DBM
Dly1mS(50);
for(i=0;i<4;i++) //发四次
{
halRfSendPacket(txBuffer_CCxx00, sizeof(txBuffer_CCxx00));
Dly1mS(50);
}
// halSpiWriteReg(0x3E,0x7f); //POWER=0DBM
if(Current_Mode==CC1100_Mode)
halSpiWriteReg(CCxxx0_FREND0, 0x15);//CC1100太近会收不到,将发射功率降低到-10DBM
Dly1mS(50);
halRfSendPacket(txBuffer_CCxx00, sizeof(txBuffer_CCxx00));
Dly1mS(100);
PORTC=0xFF;
}
//------------------------------------------------------------
// TX OPTION 判断CC1100,CC2500是否接收到数据,如果有,在数码管显示出来
//
//-------------------------------------------------------------
unsigned char RxCCxx00(void)
{
unsigned char length,i;
length = sizeof(rxBuffer_CCxx00);
if (halRfReceivePacket(rxBuffer_CCxx00, length))
{
for(i=0;i<10;i++)
if(rxBuffer_CCxx00[i+2]!=i) return 0; //判断数据是否正确
i=rxBuffer_CCxx00[0];
if(i>9) return 0;
PORTC=dpybuffer; //显示收到的数据
// LED2=0;
// LED1=1;
return 1;
}
else return 0;
}
void TestingCCxx00(void);
void TestingCC1000(void);
/////////////////////////////////////////////////////////////
//
//main program 主程序
//
//===========================================================
void main()
{
InitPIC16F877A();
CheckState();
switch(Current_Mode)
{
case CC1100_Mode: //CC1100测试模式
flag.CC1100_PA=0;
SetupCCxx00();
TestingCCxx00();
break;
case CC2500_Mode: //CC2500测试模式
SetupCCxx00();
TestingCCxx00();
break;
case CC1000_Mode: //CC1000测试模式
SetupCC1000();
TestingCC1000();
break;
case CC1100_PA_Mode: //CC1100+PA测试模式
flag.CC1100_PA=1;
SetupCCxx00();
TestingCCxx00();
break;
}
}
//===============================================================
//CC1100,CC2500测试模式
//===============================================================
void TestingCCxx00(void)
{
unsigned char rfstate,j;
while(1)
{
rfstate=halSpiReadStatus(CCxxx0_MARCSTATE); //读RF状态
if((rfstate& 0x1f)==0x00) //如果出错
{
// LED1=0;
// LED2=0;
POWER_UP_RESET_CCxxx0();
if(Current_Mode==CC1100_Mode) halRfWriteRfSettings_CC1100();
else halRfWriteRfSettings_CC2500();
}
KeyScan(); //键扫描
if(Keyflag) //判断是否有键按下
{
txBuffer_CCxx00[1]=0;
if(Old_key==SW1_KEY)
txBuffer_CCxx00[1]=1;
if(Old_key==SW2_KEY)
txBuffer_CCxx00[1]=2;
if(Old_key==SW3_KEY)
txBuffer_CCxx00[1]=3;
if(Old_key==SW4_KEY)
txBuffer_CCxx00[1]=4;
txBuffer_CCxx00[2]=0x01; //MAIN FALG
TxCCxx00(); //发射信息
}
else
{
P_PA=0;
if(RxCCxx00()) //是否收到数据?
{
for(j=0;j<sizeof(rxBuffer_CCxx00);j++)
{
while(!TXIF);
TXREG=rxBuffer_CCxx00[j];
}
if(rxBuffer_CCxx00[1]==0x01) //有,判断FLAG
{ //是对方发来的信息
//返回收到的信息
txBuffer_CCxx00[2]=0x07; //SLAVE FLAG
txBuffer_CCxx00[1]=rxBuffer_CCxx00[0];
halSpiStrobe(CCxxx0_SIDLE);
Dly1mS(500);
TxCCxx00();
}
else
if(rxBuffer_CCxx00[1]==0x07) Dly1mS(500);//是对方返回的信息
}
}
}
}
//============================================================================
//CC1000测试模式
//===========================================================================
void TestingCC1000(void)
{
unsigned char i;
while(1)
{
KeyScan(); //键扫描
if(Keyflag) //判断是否有键按下
{
GIE = 0;
TXBuffer[7]=0;
if(Old_key==SW1_KEY)
TXBuffer[7]=1;
if(Old_key==SW2_KEY)
TXBuffer[7]=2;
if(Old_key==SW3_KEY)
TXBuffer[7]=3;
if(Old_key==SW4_KEY)
TXBuffer[7]=4;
// LED1=LED_ON;
SetupCC1000TX(0x81,0x48); //切换到发射状态
TRISB&=~(0x02); // Set DIO as output
DIO=0;
INTEDG = 0; // falling edge trigger the interrupt
GIE = 1;
for(i=0;i<3;i++) //发三次
{
State=TX_STATE;
TXBuffer[6]=1;
ShiftReg=TXBuffer[0];
BitCounter=0;
TXBufferIndex1=0;
flag.TX_End=0;
while(!flag.TX_End) ; //等待发射完成
Dly1mS(50);
DIO=0;
}
GIE = 0;
Dly1mS(50);
SetupCC1000RX(0x44,0x60); //切换到接收状态
flag.PreambleNextbit=1;
TRISB|=0x02; // Set DIO as input
INTEDG = 1; // rising edge trigger the interrupt
GIE = 1;
}
else
{ //没有按键
if(flag.RX_OK) //收到数据吗?
{
// GIE = 0;
// LED2=LED_ON;
if(RXBuffer[0]==0xCA) //同步字信息对吗?
{
if(RXBuffer[1]==0x01) //是对方发过来还是返回来的数据?
{ //发过来的
PORTC=dpybuffer[RXBuffer[2]];
TXBuffer[6]=0;
TXBuffer[7]=RXBuffer[2];
Dly1mS(150);
SetupCC1000TX(0x81,0x48);
TRISB&=~(0x02); // Set DIO as output
DIO=0;
INTEDG = 0; // falling edge trigger the interrupt
GIE = 1;
// LED2=LED_OFF;
// LED1=LED_ON;
for(i=0;i<3;i++) //返回数据
{
State=TX_STATE;
ShiftReg=TXBuffer[0];
BitCounter=0;
TXBufferIndex1=0;
flag.TX_End=0;
while(!flag.TX_End) ;////等待发射完成
Dly1mS(50);
}
GIE = 0;
Dly1mS(50);
SetupCC1000RX(0x44,0x60);
flag.PreambleNextbit=1;
TRISB|=0x02; // Set DIO as input
INTEDG = 1; // rising edge trigger the interrupt
GIE = 1;
}
else
PORTC=dpybuffer[RXBuffer[2]];//是返回来的数据,显示出来
}
flag.RX_OK=0;
}
}
}
}
用户951650 2011-9-8 09:55
用户365227 2011-8-22 09:43