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

📄 nrf24l01.c

📁 C51驱动nrf24l01无线发送
💻 C
字号:
#include <intrins.h>
#include "define.h"
#include "nrf24l01.h"


/***************************************************************************************/
/*	  NRF24L01 的管脚定义,以及在本程序中的应用,VCC接3.3V电源,可以通过5V用电压转换芯片
/*得到,NC 管脚可以接可以不接,暂时没用途。本程序应用于51或者52单片机,是两个模块进行通讯
/*成功的简单指示,现象是:模块1的 KEY1 对应模块1的LED1 和模块2的LED3 ,模块1的 KEY2 对应模
/*块1的LED2 和模块2的LED4,发过来也对应。
/***************************************************************************************/

/*****************************************长延时*****************************************/
void Delay(unsigned int s)
{
	unsigned int i;
	for(i=0; i<s; i++);
	for(i=0; i<s; i++);
}
/******************************************************************************************/
/*延时函数
/******************************************************************************************/
void inerDelay_us(unsigned char n)	//延时,us 级
{
	for(;n>0;n--)
		_nop_();
}
/****************************************************************************************/
/*NRF24L01初始化
/***************************************************************************************/
void init_NRF24L01(void)
{
  inerDelay_us(100);
 	CE=0;    // 芯片使能
 	CSN=1;   // 禁止 SPI 
 	SCK=0;   // SPI时钟置低
	SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址	
	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
	SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动	ACK应答允许	
	SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21  
	SPI_RW_Reg(WRITE_REG + RF_CH, 0x02);        //   设置信道工作为2.4GHZ,收发必须一致
	SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   		//设置发射速率为1MHZ,发射功率为最大值0dB
}
/****************************************************************************************************/
/*函数:unsigned int SPI_RW(unsigned int unsigned char)
/*功能:NRF24L01的SPI写时序-----根据SPI协议,写一字节数据到nRF24L01,同时从nRF24L01 读出一字节
/****************************************************************************************************/
unsigned int SPI_RW(unsigned int dat)
{
	unsigned int i;
   	for(i=0;i<8;i++) // 循环8次
   	{
		MOSI = (dat & 0x80);  // dat的最高位输出到MOSI   MSB to MOSI
		inerDelay_us(DELAY);
		dat = (dat << 1);     // 从右向左进一位          shift next bit into MSB..
		SCK = 1;              // 拉高SCK,nRF24L01从MOSI读入1位数据,同时从MISO输出1位数据  Set SCK high..
		inerDelay_us(DELAY);
		dat |= MISO;          //读MISO到 dat 最低位       capture current MISO bit
		inerDelay_us(DELAY);
		SCK = 0;              // SCK置低                  ..then set SCK low again
		inerDelay_us(DELAY);
   	}
    return(dat);          	  //返回读出的一字节           return read dat
}
/****************************************************************************************************
/*函数:unsigned char SPI_Read(unsigned char reg)
/*功能:NRF24L01的SPI时序-----------从reg寄存器读一字节
/****************************************************************************************************/
unsigned char SPI_Read(unsigned char reg)
{
	unsigned char reg_val;
	
	CSN = 0;             //CSN置低,开始传输数据  CSN low, initialize SPI communication...
	inerDelay_us(DELAY);
	SPI_RW(reg);         //选择寄存器             Select register to read from..
	reg_val = SPI_RW(0); //然后从该寄存器读数据   ..then read registervalue
	CSN = 1;             //CSN拉高,结束数据传输  CSN high, terminate SPI communication
	inerDelay_us(DELAY);
	
	return(reg_val);     //返回寄存器数据         return register value
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/*描述:写数据value到reg寄存器
/****************************************************************************************************/
unsigned int SPI_RW_Reg(unsigned char reg, unsigned char value)
{
	unsigned char status;
	
	CSN = 0;               // CSN置低,开始传输数据      CSN low, init SPI transaction
	inerDelay_us(DELAY);
	status = SPI_RW(reg);  // 选择寄存器,同时返回状态字 select register
	SPI_RW(value);         // 然后写数据到该寄存器       ..and write value to it..
	CSN = 1;               // CSN拉高,结束数据传输      CSN high again
	inerDelay_us(DELAY);
	
	return(status);        // 返回状态寄存器             return nRF24L01 status unsigned char
}
/****************************************************************************************************/
/*函数:unsigned int SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char unsigned chars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,unsigned chars:读出数据的个数
/*描述: 从reg寄存器读出bytes个字节,通常用来读取接收通道数据或接收/发送地址
/****************************************************************************************************/
unsigned int SPI_Read_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars)
{
	unsigned int status,i;
	
	CSN = 0;                 //CSN置低,开始传输数据   Set CSN low, init SPI tranaction
	inerDelay_us(DELAY);
	status = SPI_RW(reg);    //选择寄存器,同时返回状态字 Select register to write to and read status unsigned char
	
	for(i=0;i<uchars;i++)
		pBuf[i] = SPI_RW(0); //逐个字节从nRF24L01读出 
	
	CSN = 1;                 //CSN拉高,结束数据传输
	inerDelay_us(DELAY);          
	
	return(status);          //返回状态寄存器      return nRF24L01 status unsigned char
}
/*********************************************************************************************************
/*函数:unsigned int SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char unsigned chars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,unsigned chars:写入数据的个数
/*描述:把pBuf缓存中的数据写入到nRF24L01,通常用来写入发射通道数据或接收/发送地址
/*********************************************************************************************************/
unsigned int SPI_Write_Buf(unsigned char reg, unsigned char *pBuf, unsigned char uchars)
{
	unsigned int status,i;
	
	CSN = 0;               //CSN置低,开始传输数据
	inerDelay_us(DELAY);       
	status = SPI_RW(reg);  //选择寄存器,同时返回状态字
	inerDelay_us(DELAY);   
	for(i=0; i<uchars; i++) 
		SPI_RW(*pBuf++);	//逐个字节写入nRF24L01
	CSN = 1;           //CSN拉高,结束数据传输
	inerDelay_us(DELAY);
	return(status);    //返回状态寄存器 
}
/****************************************************************************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置 
/****************************************************************************************************/
void SetRX_Mode(void)
{
	CE=0;
	inerDelay_us(DELAY);
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);//CRC使能,16位CRC校验,上电,接收模式 
	CE = 1;    // 拉高CE启动接收设备
	inerDelay_us(DELAY);
	inerDelay_us(130);
}
/******************************************************************************************************/
/*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
/*功能:数据读取后放入rx_buf接收缓冲区中
/******************************************************************************************************/
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
{
    unsigned char revale=0;
	sta=SPI_Read(STATUS);	// 读取状态寄存其来判断数据接收状况
	if(RX_DR)				// 判断是否接收到数据
	{
    CE = 0; 			//SPI使能
		inerDelay_us(DELAY);
		SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
		revale =1;			//读取数据完成标志
	}
	SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
	return revale;
}
/***********************************************************************************************************
/*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
/*功能:发送 tx_buf中数据
/**********************************************************************************************************/
void nRF24L01_TxPacket(unsigned char * tx_buf)
{
	CE=0;			//StandBy I模式	
	inerDelay_us(DELAY);
	SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
	SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); 			 // 装载数据	
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);   		 // IRQ收发完成中断响应,16位CRC,主发送
	CE=1;		 //置高CE,激发数据发送
	inerDelay_us(130);
}

void nRF24L01_Initial(void)
{
	CE=0;// chip enable
	CSN=1;// Spi disable
	SCK=0;// Spi clock line init high
	MOSI = 1;//mosi input
	IRQ = 1;//IRQ input
	
}
/**************************************************
Function: RX_Mode();

Description:
  This function initializes one nRF24L01 device to
  RX Mode, set RX address, writes RX payload width,
  select RF channel, datarate & LNA HCURR.
  After init, CE is toggled high, which means that
  this device is now ready to receive a datapacket. */
/**************************************************/
/*
void RX_Mode(void)
{
	CE=0;
	inerDelay_us(10);
//	DI();
  SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // Use the same address on the RX device as the TX device

  	//SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
	SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);      // disable Auto.Ack:Pipe0
  SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
	SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x03);//5byte的地址
	SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00);//禁止重发
	SPI_RW_Reg(WRITE_REG + RF_CH, 20);        // Select RF channel 2440M
  SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width
  SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled..
//	EI();
  CE=1;
	inerDelay_us(500);
	//IE0 = 0;
	//  This device is now ready to receive one packet of 16 bytes payload from a TX device sending to address
  //  '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.

}*/
void RX_Mode(void)
{
	CE=0;  
	SPI_Write_Buf(WRITE_REG  +  RX_ADDR_P0,  TX_ADDRESS,  TX_ADR_WIDTH);  
	SPI_RW_Reg(WRITE_REG  +  EN_AA,  0x01);           //  Enable  Auto.Ack:Pipe0   
	SPI_RW_Reg(WRITE_REG  +  EN_RXADDR,  0x01);    //  Enable  Pipe0   
	SPI_RW_Reg(WRITE_REG  +  RF_CH,  40);               //  Select  RF  channel  40 
	SPI_RW_Reg(WRITE_REG  +  RX_PW_P0,  TX_PLOAD_WIDTH); 	//&  Prim:RX.  RX_DR  enabled..    
	SPI_RW_Reg(WRITE_REG  +  RF_SETUP,  0x07);   
	SPI_RW_Reg(WRITE_REG  +  CONFIG,  0x0f); 
	CE  =  1;  
}
/**************************************************/

/**************************************************
Function: TX_Mode();

Description:
  This function initializes one nRF24L01 device to
  TX mode, set TX address, set RX address for auto.ack,
  fill TX payload, select RF channel, datarate & TX pwr.
  PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.

  ToDo: One high pulse(>10us) on CE will now send this
  packet and expext an acknowledgment from the RX device. */
/**************************************************/
/*
void TX_Mode(unsigned char *Rf_Send_Buf)
{
	CE=0;
	inerDelay_us(10);
  SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01
  SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
  	//SPI_Write_Buf(WR_TX_PLOAD, Buffer, TX_PLOAD_WIDTH); // Writes data to TX payload
	SPI_Write_Buf(WR_TX_PLOAD, Rf_Send_Buf, TX_PLOAD_WIDTH); // Writes data to TX payload
  	//SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
	SPI_RW_Reg(WRITE_REG + EN_AA, 0x00);      // disable Auto.Ack:Pipe0
  SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  SPI_RW_Reg(WRITE_REG + SETUP_AW, 0x03);//5byte的地址
   	//SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
	SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x00);//禁止重发
  SPI_RW_Reg(WRITE_REG + RF_CH, 20);        // Select RF channel 2440M
  SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR	
	SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); //设置发送数据长度,本次设置为32字节
  	//SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x3e);//
	CE=1;
	inerDelay_us(500);
	SPI_RW_Reg(FLUSH_TX, 0x00); 
	SPI_RW_Reg(WRITE_REG + STATUS, 0x70);//RESET INTTERUPT
	//IE0 = 0;
}
*/
void TX_Mode(unsigned char *Rf_Send_Buf)
{   
	CE=0;  
	 
	SPI_Write_Buf(WRITE_REG  +  TX_ADDR,  TX_ADDRESS,  TX_ADR_WIDTH);  
	SPI_Write_Buf(WRITE_REG  +  RX_ADDR_P0,  TX_ADDRESS,  TX_ADR_WIDTH);  
	SPI_Write_Buf(WR_TX_PLOAD,  Rf_Send_Buf,  TX_PLOAD_WIDTH);  //  Writes  data  to  TX  payload  
	 
	SPI_RW_Reg(WRITE_REG  +  EN_AA,  0x01);           //  Enable  Auto.Ack:Pipe0   
	SPI_RW_Reg(WRITE_REG  +  EN_RXADDR,  0x01);    //  Enable  Pipe0   
	SPI_RW_Reg(WRITE_REG  +  SETUP_RETR,  0x1a);  //  500us  +  86us,  10  retrans...  
	SPI_RW_Reg(WRITE_REG  +  RF_CH,  40);               //  Select  RF  channel  40   
	SPI_RW_Reg(WRITE_REG  +  RF_SETUP,  0x07);     //  TX_PWR:0dBm,  Datarate:2Mbps,  LNA:HCURR  
	SPI_RW_Reg(WRITE_REG  +  CONFIG,  0x0e);  
	CE=1;  	 
	inerDelay_us(130);
} 
void rec_rf_data(unsigned char *Rf_Rec_Buf)
{
	SPI_Read_Buf(RD_RX_PLOAD,Rf_Rec_Buf,TX_PLOAD_WIDTH);
	RX_Mode();
	SPI_RW_Reg(WRITE_REG + STATUS, 0x70);//RESET INTTERUPT
}

⌨️ 快捷键说明

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