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

📄 tag.c

📁 用C语言开发环境编写的nRF2401无线通信程序
💻 C
字号:
/*---------------------------------------------------------
标签的防碰撞的初步程序
---------------------------------------------------------*/
#include<stdio.h>
#include<c8051f020.h>

#define BYTE_BIT0  0X01
#define BYTE_BIT1  0X02
#define BYTE_BIT2  0X04
#define BYTE_BIT3  0X08
#define BYTE_BIT4  0X10
#define BYTE_BIT5  0X20
#define BYTE_BIT6  0X40
#define BYTE_BIT7  0X80
sbit CLK1  =P0^2;
sbit DATA=P0^3;   

#define LED_ON 0xE3   
#define LED_OFF 0X1c
#define PWR_UP1	0X10
#define PWR_UP0 0XEF
#define CS0 0XF7
#define CS1 0X08
#define CE1 0X04
#define CE0 0XFB
#define DR1 0X02    //0000 0010
#define DR0 0XFD	//1111 1101

#define TEST_2 0x8E //MSB D143~D136
#define TEST_1 0x08 // D135~D128
#define TEST_0 0x1C // D127~D120
#define DATA2_W 0x10 //0x10=2 字节 //频道2 发送/接收数据长度(单位:Bit)
#define DATA1_W 0x80 //0x80=16字节 //频道1 发送/接收数据长度(单位:Bit)
#define ADDR2_4 0x00
#define ADDR2_3 0x1c
#define ADDR2_2 0xcc
#define ADDR2_1 0xcc
#define ADDR2_0 0xcc
//频道1 接收地址 (当前模块地址) <- 只使用到频道1
#define ADDR1_4 0x00
#define ADDR1_3 0xcc
#define ADDR1_2 0xcc
#define ADDR1_1 0xcc
#define ADDR1_0 0xcc
#define ADDR_W 0x10  //0x10=2字节 //发送/接收地址宽度(单位:Bit)
#define CRC_L 0x1 //CRC模式 0:8位 1:16位
#define CRC_EN 0x1 //CRC校验 0:禁用 1:启用
#define RX2_EN 0x0  //双频道功能 0:禁用 1:启用
#define CM 0x1 //0:Direct mode 1:ShockBurst mode
#define RFDR_SB 0x0 //传输速率 0:250kbps 1:1Mbps (250kbps比1Mbps传输距离更远)
#define XO_F 0x3 //16M //nRF2401晶振频率
#define RF_PWR 0x3 //信号发射功率
#define RF_CH 0x2  //Channel RF 频率设置
//Channel = 2400MHz + RF_CH * 1.0MHz
#define RXEN 0x1 //0:Tx 1:Rx   阅读器最先处于发送状态;
//<将设置信息组合成每个字节的数据信息,此区域无需修改>
#define RFConfig_Bit0 TEST_2
#define RFConfig_Bit1 TEST_1
#define RFConfig_Bit2 TEST_0
#define RFConfig_Bit3 DATA2_W
#define RFConfig_Bit4 DATA1_W
#define RFConfig_Bit5 ADDR2_4
#define RFConfig_Bit6 ADDR2_3
#define RFConfig_Bit7 ADDR2_2
#define RFConfig_Bit8 ADDR2_1
#define RFConfig_Bit9 ADDR2_0
#define RFConfig_Bit10 ADDR1_4
#define RFConfig_Bit11 ADDR1_3
#define RFConfig_Bit12 ADDR1_2
#define RFConfig_Bit13 ADDR1_1
#define RFConfig_Bit14 ADDR1_0
#define RFConfig_Bit15 (ADDR_W<<2 | CRC_L<<1 | CRC_EN)
#define RFConfig_Bit16 (RX2_EN<<7 | CM<<6 | RFDR_SB<<5 | XO_F <<2 | RF_PWR)
#define RFConfig_Bit17 (RF_CH<<1 | RXEN)
//通过宏定义将18字节的寄存器参数按照各个功能分解,以便于参数的调整
unsigned char code nRF2401_Conf[18] ={
										RFConfig_Bit0, RFConfig_Bit1, RFConfig_Bit2, RFConfig_Bit3, RFConfig_Bit4,
										RFConfig_Bit5, RFConfig_Bit6, RFConfig_Bit7, RFConfig_Bit8, RFConfig_Bit9,
										RFConfig_Bit10, RFConfig_Bit11, RFConfig_Bit12, RFConfig_Bit13, RFConfig_Bit14,
										RFConfig_Bit15, RFConfig_Bit16, RFConfig_Bit17
									 };
bdata unsigned char DATA_BUF;      //用于ByteRead 和 ByteWrite函数
unsigned char Manchesterbuf[16];
#define DATA7 ((DATA_BUF&BYTE_BIT7) != 0)  //判断数据的最高位是否为1
#define DATA0 ((DATA_BUF&BYTE_BIT0) != 0)  //判断数据的最低位是否为1
#define SYSCLK  11059200		           //系统时钟  
#define BAUDRATE  9600					   //系统波特率
//??¨?3?¨?¨???o?¨?y
void Delay100(void)
{
	unsigned int i;
	for(i=0;i<100;i++);
}

void Delay(void)
{
	unsigned int i;
	for(i=0;i<10;i++);
}

//系统设置
void SYSCLK_Init(void)
{
  int i;
 OSCXCN=0x67;             	//设置系统时钟
 for(i=0;i<256;i++);
 while(!(OSCXCN&0x80));    //等待外部时钟稳定
 OSCICN=0x88;  
 XBR0=0X04;            	   //设置串口引脚
 XBR2=0X40;  			  //交叉IO口使能
 P6=P6&LED_ON;              //LED灯亮
 Delay100();
 Delay100();
 P6=P6|LED_OFF;             //LED灯灭
}
//串口初始化函数
void UART0_Init(void)
{
  SCON0=0X50;                   //方式1,8位UART,允许接收					
  TMOD=0X20;	                //定时器1,模式2,8位重装载			       
  TH1=-(SYSCLK/BAUDRATE/16);    //根据波特率设置定时器1的重载值;
  TR1=1;						//启动定时器1; 
  CKCON|=0X10;				    //定时器1使用SYSCLK为时基;
  PCON|=0X80;					//SMOD00=1; 
}

//写每一位的数据。
void ByteWrite(unsigned char send)
{
	unsigned char i;
	DATA_BUF=send;
	for (i=0;i<8;i++)
		{
		    CLK1=0;
			if (DATA7) //总是发送最高位
			{
				 DATA=1;
			 }
			else
			{
			     DATA=0;
			}
			Delay();
			CLK1=1;//	CLK1=1; 0000 0001 P4^0;
			Delay();
            CLK1=0;	
			DATA_BUF=DATA_BUF<<1;
		}
}
// <2401配置寄存器的写入方式>
void Config2401(void)
{
  unsigned int i;
  unsigned char variablel;
  P4=P4&CS0;       // P4=P4&0XF7;//CS=0;  1111 0111 P4.3;
  P4=P4&CE0;       //P4=P4&0XFB;//CE=0;  1111 1101 P4.2
  CLK1=0;

  P4=P4|PWR_UP1;   //P4=P4|0X10;//PWR_UP=1; P4.4 0001 0000
	for(i=0;i<10;i++)
	  Delay100();
 //从上电到进入配置模式需要3ms的延时	  	 
  P4=P4|CS1;	      //使RF2401进入配置方式
     Delay100();
	for(i=3;i<18;i++)
	{
		variablel=nRF2401_Conf[i];
		ByteWrite(variablel);
	}
    Delay100();
    P4=P4&CS0;      //CS置低使配置有效
    Delay100();
}

//读每一位的数据;
unsigned char ByteRead(void)
{
 unsigned char i;
	for (i=0;i<8;i++)
	{
		DATA_BUF=DATA_BUF<<1;
		CLK1=1;   //P4=P4|0X01;  //	CLK1=1;	 0000 0001
		DATA=1; //设置为输入状态
		if (DATA)  //读取最高位,保存至最末尾,通过左移位完成整个字节 
			{
			DATA_BUF|=BYTE_BIT0;
			}
		else
			{
			DATA_BUF&=~BYTE_BIT0;
			}
		CLK1=0;//P4=P4&0XFE;  //		 1111 1110
		  Delay100();
	}
return DATA_BUF;
}

//将读出的数据存储在RxBuf;
void nrf2401_Rxpack(unsigned char *RxBuf,unsigned int *x)
{
  unsigned int i;
  *x=0;
  for(i=0;i<DATA1_W/8;i++)
    {
	  *RxBuf=ByteRead();
	  RxBuf++;
	  *x=*x+1;
	}
}

void SetTxMode(void)
{
	P4=P4|PWR_UP1;    //PWR_UP=1; 4.4  0001 0000
	P4=P4&CE0;        //CE=0; 4.2	    1111 1011
	P4=P4|CS1;        //CS=1;4.3 0000 1000;

	CLK1=0;
	DATA =0;	
	Delay();	
	CLK1=1;            //	CLK1=1;
    Delay();
	CLK1=0;            //CLK1=0;

	P4=P4&CS0;         //CS=0; 4.3 1111 0111; ????¨?DD?ì
	P4=P4|CE1;         //CE=1; 4.2 0000 0100   ??¨¨??¤??¨???¨??
	Delay100();
}
 void SetRxMode(void)
{
  unsigned int i;
  P4=P4&CS0;       
  P4=P4&CE0;       
  CLK1=0;
  DATA=0;

  P4=P4|PWR_UP1;          //????????????
  for(i=0;i<10;i++)
	Delay100();

  P4=P4|CS1;	       //????????????
  Delay100();

    CLK1=0;	
	DATA =1;
	Delay();

	CLK1=1;           // CLK1=1;
	Delay();

	CLK1=0;//P4=P4&0XFE;   //CLK1=0;
	P4=P4&CS0;         //CS=0; 4.3 1111 0111; 
	P4=P4|CE1;         //CE=1; 4.2 0000 0100   ??¨¨??¤??¨???¨??
	Delay100();
	Delay100();

}
//进行Manchester编码
void Manchester_fun(unsigned char *TxBuf)
{
  unsigned char i,k=0;
  for (i=0;i<8;i++)
    {
	   if(TxBuf[i]==1)
	      {
		   Manchesterbuf[k]=1;
		   k++;
		    Manchesterbuf[k]=0;
		   k++;
		  }
	   else
	      {
		   Manchesterbuf[k]=0;
		   k++;
		    Manchesterbuf[k]=1;
		   k++;
		  }	
	}
}
//接收方通道硬件地址
unsigned char TxAddress[]={0xcc,0xcc,0xcc,0xcc};
//nRF2401数据发送函数
void nRF2401_TxPacket(unsigned char TxBuf[])
{
 int i;
 unsigned char variable2;
 Manchester_fun(TxBuf);
 P4=P4|PWR_UP1;  
 P4=P4&CS0; 
 P4=P4&CE0;	  	//进入空闲模式
 CLK1=0;
 DATA=0;
 Delay();

 P4=P4|CE1;  //进入收发模式
 Delay100();

 for(i=0;i< (ADDR_W/8);i++)    //写入接收地址(按字节对齐)
	{
		variable2=TxAddress[i];
		ByteWrite(variable2);
	} 
 for(i=0;i<(DATA1_W/8);i++)    //写入需要发送的数据(按字节对齐)
	{
		variable2=Manchesterbuf[i];
		ByteWrite(variable2);
	}
	P4=P4&CE0;       //CE置低使发送有效
	Delay100();
	Delay100();
}

 

unsigned int comparative_fun(unsigned char Readdatabuf[8],unsigned char  Txbuf[8])
{
  unsigned  int i,flag=0;
  for(i=0;i<8;i++)
     {
	      if(Readdatabuf[i]>Txbuf[i])
			  {  
			     flag=1;          //判断到接收的数据比自己的标签号大
			     break;
			   }
		  if(Readdatabuf[i]<Txbuf[i])  //判断到接收的数据比自己的标签号小
			  {  
			     flag=2;
			     break;
			   }
	 }  
  if(flag==1) 
   { return 1; }        //标签号小于接受的数据返回标志1                 
  else if (flag==2)
   { return 2;	}	    //标签号大于接受的数据返回标志2	    
  else if (flag==0)         
   { return 0;  }       //标签号相同返回标志0				
    						

}

void Redadata_fun(unsigned char *Rxbuf,unsigned char *Readdatabuf)
{		
  unsigned char i=0,k=0;
   for(i=0;i<16;i=i+2)
    {
		 if((Rxbuf[i]==1)&&(Rxbuf[i+1]==0))
	        {
				Readdatabuf[k]=1;  //收到的数据是下降沿,即为数据1;
			 }
		 else 
		 	{	
		  		Readdatabuf[k]=0;	//收到的数据是上降沿,即为数据0;
			 }
	     k++;
	}
}


void main(void)
{
 unsigned char Txbuf1[8]={1,0,1,0,1,0,1,1,},Rxbuf[16]; 
 unsigned char Txbuf2[8]={0,0,0,0,0,0,0,0,};
 unsigned char Txbuf3[8]={0,1,1,0,0,1,0,0,};
 unsigned char send_flag=0,recive_flag=0,LED=0X1C;
 unsigned int  countbit; 
 unsigned int *p=&countbit;
 unsigned int over_flag=1,comparative_flag; 
 unsigned char Readdatabuf[8];
 
 unsigned long int  i,k;	   
 WDTCN=0xde;          // 禁止看门狗定时器
 WDTCN=0xad;		  
 SYSCLK_Init();   	  //初始化CPU;
 UART0_Init();		   //配置串口
 Config2401();	  	   //配置nRF2401; 
 
 P6=P6&LED_ON;  
 while(1)
   { 
   	   
    while(over_flag==1)
    { 	 
	      SetRxMode();	     //处于接收模式
	      P4=P4|CE1;         // 接收使能
		  for(i=0;i<250;i++) //延时等待接收数据    
			 	{
				   for(k=0;k<50;k++)
				   {
				   		Delay100();
			        }	
				
				}
		     while((P4&DR1)!=0)	       //判断是否接收到数据 
			  {
					nrf2401_Rxpack(Rxbuf,p);          //读取数据;
				    Redadata_fun(Rxbuf,Readdatabuf);  //把数据转换为没有编码的原始数据
					comparative_flag=comparative_fun(Readdatabuf,Txbuf3);	//接收到的数据与自己的数据进行比较
					 for(k=0;k<50;k++)
				        {
				   		  Delay100();
			             }
					 if(comparative_flag==1)        //再回应范围以内,发送数据
						 {	  i=0;
							  while(i<500)
							 {	
								   SetTxMode( ); 
								   i++;
								   P4=P4|CE1;
								   nRF2401_TxPacket(Txbuf3);    //发送数据
								   P6=P6|LED;	
								   LED=LED+2;	 
								   P6=P6&LED; 
								   for(k=0;k<6;k++)
								   {
								   		Delay100();
							        }	
							 }
					   	}
					  if(comparative_flag==0)
				        {  
						   over_flag=0;   //收到确认信息,over_flag=0; 失去活性
						}
			    P6=P6|LED_OFF; //0001 1100;¨¨?2??e	 
		    }	   
	  }		
     
   }
}

⌨️ 快捷键说明

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