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

📄 w78ie54无线接收端.c

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


//1号装置		    //接受端

//#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寄存器读取接收到的有效数据 

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




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

bit  read_flag=0;


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

sbit flag= char_buf^7;
sbit flag1= char_buf^0;



char uuch;
unsigned long t_num=0;


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 Read905(void) 
{ 
 unsigned char i;
     
 CSN=0;      // CSN片选信号,SPI使能 
 SpiWrite(RC);    // 向905芯片写配置命令 
 for (i=0;i<RxTxConf.n;i++)  // 循环写入配置信息 
 { 
  DATA_STR[i]=SpiRead(); //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);
  
 
} 


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



void init_serialcomm(void)     //初始化串口
{
    SCON  = 0x50;       //SCON: serail mode 1, 8-bit UART, enable ucvr 
    TMOD |= 0x20;       //TMOD: timer 1, mode 2, 8-bit reload 
    TH1   = 0xFD;       //Baud:9600  fosc=11.0592MHz 
    IE   |= 0x90;       //Enable Serial Interrupt 
    TR1   = 1;          //timer 1 run 
    
}

//向串口发送一个字符,非中断方式 
void send_char_com(unsigned char ch)  
{
    SBUF=ch;
    while(TI==0);
    TI=0;
}

//向串口发送一个字符串,strlen为该字符串长度 
void send_string_com(unsigned char *str,unsigned int strlen)
{
    unsigned int k=0;
    
	do 
    {
        send_char_com(*(str + k));
        k++;
    } while(k < strlen);
	CHARcount=0;
	
}


//串口接收中断函数 
void serial () interrupt 4 using 3 
{
    if(RI)
    {
        unsigned char ch;
        
		RI = 0;
        ch = SBUF;
        DATA_STR[CHARcount]=ch;
		if (CHARcount<INBUF_LEN)
		CHARcount++;
		if (ch==0xaa)
        read_flag=1;  //如果串口接收的数据 
                      //就置位取数标志 
         
    }
}


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]=0xcc;   //接收地址为0x19
    RxTxConf.buf[6]=0xcc;
    RxTxConf.buf[7]=0xcc;
	RxTxConf.buf[8]=0xcc;
	RxTxConf.buf[9]=0x58;

	Config905();			//写入配置
}

void ChComd(void)	//解释命令
{
   unsigned char ch;
   ch=DATA_STR[0];
   switch (ch)
   {
   case 'h':
   DATA_STR[0]='H';
   DATA_STR[1]='e';
   DATA_STR[2]='l';
   DATA_STR[3]='l';
   DATA_STR[4]='o';
   send_string_com(DATA_STR,5);
   break;
   case 'r':
   Read905();
   send_string_com(DATA_STR,10);
   break;
   case 'g':
   
   while (DR==1);
   PWR=0;
   Delay(10);
   PWR=1;
   Delay(10);
   setConf();
   Delay(10);
   SetRxMode();		//设置接收模式
   DATA_STR[0]='S';
   DATA_STR[1]='E';
   DATA_STR[2]='T';
   DATA_STR[3]='U';
   DATA_STR[4]='P';
   
   send_string_com(DATA_STR,5);
   
   break;

   case 'd':
				
				uuch=0xcd;
                RxBuf[0]=1;
				RxBuf[1]=0xcc;
				RxBuf[2]=uuch;
				RxBuf[3]=0x00;
				
				TXready(uuch);
				
	            TxPacket();	      //发射
				
				SetRxMode();	  //设置为接收
				
		 
   break;
   case 'b':
				
				uuch=0xcb;
				RxBuf[0]=1;
				RxBuf[1]=0xcc;
				RxBuf[2]=uuch;
				RxBuf[3]=0x00;
				
				TXready(uuch);
				
	            TxPacket();	      //发射
				
				SetRxMode();	  //设置为接收
				
		 
   break;
   case 'e':
				
				uuch=0xce;
				RxBuf[0]=1;
				RxBuf[1]=0xcc;
				RxBuf[2]=uuch;
				RxBuf[3]=0x00;
				
				TXready(uuch);
				
	            TxPacket();	      //发射
				
				SetRxMode();	  //设置为接收
				
		 
   break;
   case 'x':
				
				uuch=0xcb;
				RxBuf[0]=1;
				RxBuf[1]=0xcc;
				RxBuf[2]=uuch;
				RxBuf[3]=0xcd;
				
				TXready(uuch);
				
	            TxPacket();	      //发射
				
				SetRxMode();	  //设置为接收
				
		 
   break;
   case 'y':
				
				uuch=0xcd;
				RxBuf[0]=1;
				RxBuf[1]=0xcc;
				RxBuf[2]=uuch;
				RxBuf[3]=0xcb;
				
				TXready(uuch);
				
	            TxPacket();	      //发射
				
				SetRxMode();	  //设置为接收
				
		 
   break;   
   
   case 'z':
              
			     RxBuf[0]=DATA_STR[1];
			     RxBuf[1]=DATA_STR[2];
			     RxBuf[2]=DATA_STR[3];
				 RxBuf[3]=DATA_STR[4];
			   
				 uuch=RxBuf[2];
			   
			     TXready(uuch);
				
	             TxPacket();	      //发射
				
				 SetRxMode();	  //设置为接收
			   
   break;   
   }

}

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

}




main()			   //程序入口
{
    	    //配置寄存器内容
    init_serialcomm();  //初始化串口
	CHARcount=0;
	
	Led1=0;             //打开指示灯
	
	PowUp();
	PowUp();
	while(1)
    {
          
		 if (t_num<100000)    
  	     t_num++;
		 else
		 t_num=0;

		 if (t_num==40000||t_num==90000)
		 {

		   //DATA_STR[0]='s';
		   //read_flag=1;
		 
		   if (Led1)
		   Led1=0;
		   else
		   Led1=1;


		 }

			 if ( DR )
			 {
				
			    RxPacket();	      //接收
				
				
				send_string_com(RxBuf,32);
				SetRxMode();	  //设置为接收
				

			 }
			 
		 	 

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

}


⌨️ 快捷键说明

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