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

📄 main.c

📁 通过PIC单片机控制CC00通信
💻 C
字号:
/******************************************************************
//	PROJECT:chipcon RF DEMO
//	RF:	 CC1100 or cc2500 or cc1000(Chipcon) 
//	CC1100:433。92MHZ
//	CC2500:2433MHZ
//	CC1000:433。92MHZ
//  MCU: PIC16F877A(Microchip)
//	Designed : Ben xie(Infortech)
//	Date :	2006-1
//	Checksum: 0xce9e
//				
******************************************************************/
#include <pic.h>
#include "pic_setting.h"
#include "CCxxx0.h"
#include "cc1000.h"
#include "CCxxx0LIB.C"
#include "cc1000pic.c"

BYTE paTable_CC1100[] = {0xc0, 0xc8, 0x85, 0x51, 0x3a, 0x06, 0x1c, 0x6c };	//CC1100发射功率表
BYTE paTable_CC2500[] = {0xFF, 0xFE, 0xBB, 0xA9, 0x7F, 0x6E, 0x97, 0xC5 };	//CC2500发射功率表
BYTE txBuffer_CCxx00[] = {2, 1, 1};	//发射缓冲
BYTE rxBuffer_CCxx00[2];		//接收缓冲
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;						//0x06
	TRISB=RBCNF;						//0x3D
	TRISC=RCCNF;						//0x00

	CMCON=0x07; 						//COMPARATOR OFF
	ADCON1=0x06; 						//ADC OFF
	TRISE=0;
	OPTION=0x07;						//
	T1CON=0x31;

	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_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;
		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 //#define CCxxx0_FREND0       0x22
	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))
	{
		i=rxBuffer_CCxx00[0];	
		PORTC=dpybuffer[i];		//显示收到的数据
//		LED2=0;
//		LED1=1;
		return 1;
			
	}
	else	return 0;
	
}

void TestingCCxx00(void);
void TestingCC1000(void);
/////////////////////////////////////////////////////////////
//
//main program 主程序
//
//===========================================================
void main() 
{
	InitPIC16F877A();			//端口初始。
	CheckState();				//判断使用的chipcon芯片型号。判断当前模式,数值给Current_Mode。
	switch(Current_Mode)
	{
		case   CC2500_Mode:		//CC2500测试模式		1
			SetupCCxx00();
			TestingCCxx00();	
			break;
		case   CC1100_Mode:		//CC1100测试模式		0
			SetupCCxx00();
			TestingCCxx00();
			break;
		case   CC1000_Mode:		//CC1000测试模式		2
			SetupCC1000();
			TestingCC1000();
			break;
	}	
}	

//===============================================================
//CC1100,CC2500测试模式
//===============================================================
void TestingCCxx00(void)
{
	unsigned char rfstate; 
	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
		{	
			if(RxCCxx00())				//是否收到数据?
			{
				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;
			}		
		}
	}
}

//=================================================================
// END
//=================================================================

⌨️ 快捷键说明

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