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

📄 无线发射端.c

📁 单片机的无线通讯程序
💻 C
字号:
//================================================================================
//编制:忻琦     2007.12.9		   串口通讯速率:Baud:9600  fosc=11.0592MHz
//================================================================================


//1号装置		    //发射端端		     at89c2051

//#pragma SRC
//#pragma SMALL

#include <REG51.H>

#define INBUF_LEN 32     //数据长度

//(以下操作全部从对应寄存器的字节0开始) 
#define WC  0x00  // 写配置寄存器(RF-Configuration Register) 
#define RC  0x10   // 读配置寄存器(RF-Configuration Register) 
#define WTP  0x20   // 向TX-Payload寄存器写入发送有效数据 
#define RTP  0x21  // 从TX-Payload寄存器读取发送有效数据 
#define WTA  0x22  // 向TX-Address寄存器写入发送地址 
#define RTA  0x23  // 从TX-Address寄存器读取发送地址 
#define RRP  0x24  // 从RX-Payload寄存器读取接收到的有效数据 

#define adss 0xcb  //本机地址

/*nRF905寄存器配置参数*/ 
struct RFConfig 
{ 
 unsigned char n; 
 unsigned char buf[10]; 
}  RxTxConf;

char temp_buff[9]; //存储读取的字节,read scratchpad为9字节
char *p;

char bdata char_buf;

unsigned char TxBuf[4]; 
unsigned char RxBuf[INBUF_LEN]; 
unsigned char CHARcount,RD_FLAG;
unsigned char DATA_STR[16];      //放置接收的命令

bit  read_flag=0;


sbit AM=P1^3;	
sbit DR=P3^2;	
sbit TX_EN=P1^7;	
sbit TRX_CE=P1^6;	
sbit MOSI=P1^0;	
sbit MISO=P1^1;	
sbit SCK=P3^7;	
sbit CSN=P3^3;
sbit PWR=P1^5;			   //芯片上电
sbit CD=P1^4;
sbit uCLK=P1^2;
sbit Led1=P3^4;		      //指示灯
sbit Led2=P3^5;		
sbit flag= char_buf^7;
sbit flag1= char_buf^0;

sbit DQ = P3^1;	   //温度读口

char uuch;
unsigned long t_num=0;


//=============================================================================
void qdelay(unsigned int i)
{
  while(i--);
}



//初始化函数
char Init_DS18B20(void)
{
       unsigned char x=0;
       DQ = 1;    //DQ复位
       qdelay(8);  //稍做延时
       DQ = 0;    //单片机将DQ拉低
       qdelay(80); //精确延时 大于 480us
       DQ = 1;    //拉高总线
       qdelay(14);
       x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
	   //if (x==0)
       	//ledb=0;   //成功初始化
	   //else
	    //ledb=1;
	   qdelay(20);
	   return (x);
}

//读一个字节
char ReadOneChar(void)
{
      unsigned char i=0;
      unsigned char dat=0;
      for (i=8;i>0;i--)
       {
        DQ = 0; // 给脉冲信号
        dat>>=1;
        DQ = 1; // 给脉冲信号
        if(DQ)
         dat|=0x80;
        qdelay(4);
       }
       return(dat);
}


//写一个字节
void WriteOneChar(unsigned char dat)
{
       unsigned char i=0;
       for (i=8; i>0; i--)
       {
        DQ = 0;
        DQ = dat&0x01;
        qdelay(5);
        DQ = 1;
        dat>>=1;
       }
       qdelay(4);
}
      
//读取温度
int ReadTemperature(void)
{
      unsigned char i;
      unsigned int t=0;
      float tt=0;
	  p=temp_buff;
      Init_DS18B20();
      WriteOneChar(0xCC); // 跳过读序号列号的操作
      WriteOneChar(0x44); // 启动温度转换
      Init_DS18B20();
      WriteOneChar(0xCC); //跳过读序号列号的操作
      WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
      for(i=0;i<9;i++)
      {
         *p = ReadOneChar();
          p++;
       }
	  
	   
	  t=temp_buff[1];
      t=t*0x100+temp_buff[0];
	  t /=16;
      //tt=t*0.0625;
      //t= tt*10+0.5; //放大10倍输出并四舍五入---此行没用
      return(t);
}



//============================================================
void Delay (unsigned char t)	//t=1延迟650um
{
	unsigned int i,j;
    for (i=0;i<t;i++)
	{
	   for(j=0;j<=650;j++);
	}

}


//<SPI写操作 代码> 
void SpiWrite(unsigned char  ch_byte) 
{ 
 unsigned char i;  
 char_buf=ch_byte;    // 将需要发送的数据写入缓存 
 for (i=0;i<8;i++)    // 循环8次发送一个字节的数据 
 { 
  if (flag)           // flag = char_buf^7; 			    
   MOSI=1; 
  else 
   MOSI=0;  
  SCK=1;              // SCK 高电平 
  char_buf=char_buf<<1; // 左移一位,为下一位的发送做准备 
  SCK=0;              // SCK 低电平  
 }  
} 

//<SPI读操作 代码> 
unsigned char SpiRead(void) 
{ 
 unsigned char i;  
 for (i=0;i<8;i++)      //循环8次发送一个字节的数据 
 {  
  char_buf=char_buf<<1; //左移一位,准备接收下一位数据 
  SCK=1;                // SCK 高电平 
  if (MISO)
      flag1=1;          // flag1 = char_buf^0; 
  else 
      flag1=0;
 
  SCK=0;                // SCK低电平 
 } 
 return char_buf;       // char_buf 为接收到的完整数据 
} 

 
//意:数据的传输时,高位在前,低位在后。 
 
 
 
//<主机通过SPI接口向905配置寄存器写入信息> 
void Config905(void) 
{ 
 unsigned char i;      
 CSN=0;      // CSN片选信号,SPI使能 
 SpiWrite(WC);    // 向905芯片写配置命令 
 for (i=0;i<RxTxConf.n;i++)  // 循环写入配置信息 
 { 
  SpiWrite(RxTxConf.buf[i]); //RxTxConf保存预先设置好的配置信息 
 } 
 CSN=1;      // 结束SPI数据传输 
} 


void TXready(char adr)
{

    TxBuf[0]=adr;
    TxBuf[1]=adr;
	TxBuf[2]=adr;
	TxBuf[3]=adr;

}  
 
 
//使用nRF905发送数据 
void TxPacket(void) 
{ 
 unsigned char i;
 TX_EN=1; 
 TRX_CE=0; 
 Delay(1);     // delay for mode change(>=650us) 

 CSN=0; 
 SpiWrite(WTP);    // 先写数据,Write payload command 
 for (i=0;i<32;i++) 
 { 
  SpiWrite(RxBuf[i]);  // 写入32直接发送数据 
 } 
 CSN=1;      // 关闭SPI,保存写入的数据 
 Delay(1); 
 CSN=0;      // SPI使能,准备写入地址信息 
 SpiWrite(WTA);    // 再写地址,写数据至地址寄存器 
 for (i=0;i<4;i++)   // 写入4字节地址 
 { 
  SpiWrite(TxBuf[i]); 
 }  

 CSN=1;      // 关闭SPI 
 TRX_CE=1;     // 进入发送模式,启动射频发送 
 Delay(1);     // 进入ShockBurst发送模式后,芯片保证数据发送完成后返回STANDBY模式 
 TRX_CE=0;
 
} 

void RxPacket(void)  
{ 
 unsigned char i; 

 TRX_CE=0;     // 设置905进入待机模式  
 CSN=0;      // 使能SPI 
 SpiWrite(RRP);    // 准备读取接收到的数据  
 for (i=0;i<32;i++) 
 { 
  RxBuf[i]=SpiRead();  // 通过SPI接口从905芯片读取数据   
 } 
 
 CSN=1;      // 禁用SPI 
 while(DR||AM);
 TRX_CE=1; 

} 


//<设置器件为接收模式> 
void SetRxMode(void) 
{ 
 TX_EN=0; 
 TRX_CE=1; 
 Delay(1);     // delay for mode change(>=650us)     
} 


void setConf(void)
{
    RxTxConf.n = 10;		//配置寄存器内容
	RxTxConf.buf[0]=0x4c;
	RxTxConf.buf[1]=0x0c;	//RxTxConf={ 10,
	                        //           0x4c,0x0c,0x44,0x20,0x20,0xcc,0xcc,0xcc,0xcc,0x58}; 

	RxTxConf.buf[2]=0x44;   //4字节的地址宽度
	RxTxConf.buf[3]=0x20;
    RxTxConf.buf[4]=0x20;
    RxTxConf.buf[5]=adss;   //接收地址为0x19
    RxTxConf.buf[6]=adss;
    RxTxConf.buf[7]=adss;
	RxTxConf.buf[8]=adss;
	RxTxConf.buf[9]=0x58;

	Config905();			//写入配置
}

void ChComd(void)	//解释命令
{
   unsigned char ch;
   ch=DATA_STR[0];
   switch (ch)
   {
   
   case 'g':
   
   while (DR==1);
   PWR=0;
   Delay(10);
   PWR=1;
   Delay(10);
   setConf();
   Delay(10);
   SetRxMode();		//设置接收模式
   
   
   break;


      
   }

}

void PowUp(void)
{
                
        PWR=0;
        Delay(10);
        PWR=1;
        Delay(10);
        setConf();
        Delay(10);
        SetRxMode();		//设置接收模式
    	Delay(2);

}




main()			   //程序入口
{
    
	CHARcount=0;
	
	Led1=0;             //打开指示灯
	
	
	PowUp();
	PowUp();

	while(1)
    {
          
		 if (t_num<50000)    
  	     {
		     t_num++;
			 if ( DR )
			 {
				
			    RxPacket();	      //接收并存在RxBuf中
				while (DR || AM );
				


				if (RxBuf[2]==adss && RxBuf[3]!=0 && RxBuf[0]==1) //如果是中继就继续发射
				{


				       uuch=RxBuf[3];
				       
			    }
					 
				if (RxBuf[2]==adss && RxBuf[3]==0 && RxBuf[0]==1) //如果不是就测温返回
				{
					   RxBuf[0]=2;						  //返回信息
			    	   RxBuf[10]=ReadTemperature();	      //检测温度并返回
				       RxBuf[11]=temp_buff[0];
				       RxBuf[12]=temp_buff[1];
				       RxBuf[13]=temp_buff[2];
				       RxBuf[14]=temp_buff[3];
				       RxBuf[15]=temp_buff[4];
				       RxBuf[16]=temp_buff[5];
				       RxBuf[17]=temp_buff[6];
				       RxBuf[18]=temp_buff[7];
				       RxBuf[19]=temp_buff[8];
				       
				       
					   uuch=RxBuf[1];
				       
			    }

				if (RxBuf[2]==adss && RxBuf[3]!=0 && RxBuf[0]==2) //如果中继是就测温返回
				{
					   
					   uuch=RxBuf[1];
				       
			    }

				if (RxBuf[3]==adss && RxBuf[0]==1) //如果不是中继就测温返回
				{
					   RxBuf[0]=2;						  //返回信息
			    	   RxBuf[10]=ReadTemperature();	      //检测温度并返回
				       RxBuf[11]=temp_buff[0];
				       RxBuf[12]=temp_buff[1];
				       RxBuf[13]=temp_buff[2];
				       RxBuf[14]=temp_buff[3];
				       RxBuf[15]=temp_buff[4];
				       RxBuf[16]=temp_buff[5];
				       RxBuf[17]=temp_buff[6];
				       RxBuf[18]=temp_buff[7];
				       RxBuf[19]=temp_buff[8];
				       
				       
					   uuch=RxBuf[2];
				       
			    }

				
				TXready(uuch);	  //发射地址
				TxPacket();	      //发射
				
				SetRxMode();	  //设置为接收

				if(Led2)
				Led2=0;
				else
				Led2=1;

			 }
			 
		 }
		 else
		 {
				t_num=0;
				

		 }
		 

		  if(read_flag)  //如果取数标志已置位,就将读到的数从串口发出 
          {
               read_flag=0; //取数标志清0 
			   ChComd();	//解释命令
               
          }
		  
     }

}


⌨️ 快捷键说明

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