树莓派使用NRF24L01与单片机通信,原创代码

NRF24L01

具体怎么使用,看百度文库的技术文档,本人写的代码全是使用io口模拟spi通信,模拟的spi通信,模拟的spi通信。
转载请注明出处

51单片机使用NRF24L01


#include <reg52.h>
#include <intrins.h>

typedef unsigned char uchar;
typedef unsigned char uint;

//****************************************IO端口定义***************************************
//****************************************NRF24L01端口定义***************************************
sbit	CE	    =P1^5;
sbit	CSN		=P1^6;
sbit	SCK	    =P1^7;
sbit 	MOSI	=P3^7;
sbit 	MISO	=P3^6;
sbit	IRQ		=P3^5;

//sbit	IRQ		=P1^4;
//sbit 	MOSI	=P1^3;
//sbit	CSN		=P1^2;
//sbit 	MISO	=P1^5;
//sbit	SCK	    =P1^6;
//sbit	CE	    =P1^7;

sbit 	LED=P0^0;      //定义LED
sbit    SW=P2^6;
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH    5   	// 5 uints TX address width
#define RX_ADR_WIDTH    5   	// 5 uints RX address width
#define TX_PLOAD_WIDTH  32  	// 20 uints TX payload
#define RX_PLOAD_WIDTH  32  	// 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//接收地址
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG        0x00  	// 读寄存器指令
#define WRITE_REG       0x20 	// 写寄存器指令
#define RD_RX_PLOAD     0x61  	// 读取接收数据指令
#define WR_TX_PLOAD     0xA0  	// 写待发数据指令
#define FLUSH_TX        0xE1 	// 冲洗发送 FIFO指令
#define FLUSH_RX        0xE2  	// 冲洗接收 FIFO指令
#define REUSE_TX_PL     0xE3  	// 定义重复装载数据指令
#define NOP             0xFF  	// 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
#define EN_RXADDR       0x02  // 可用信道设置
#define SETUP_AW        0x03  // 收发地址宽度设置
#define SETUP_RETR      0x04  // 自动重发功能设置
#define RF_CH           0x05  // 工作频率设置
#define RF_SETUP        0x06  // 发射速率、功耗功能设置
#define STATUS          0x07  // 状态寄存器
#define OBSERVE_TX      0x08  // 发送监测功能
#define CD              0x09  // 地址检测           
#define RX_ADDR_P0      0x0A  // 频道0接收数据地址
#define RX_ADDR_P1      0x0B  // 频道1接收数据地址
#define RX_ADDR_P2      0x0C  // 频道2接收数据地址
#define RX_ADDR_P3      0x0D  // 频道3接收数据地址
#define RX_ADDR_P4      0x0E  // 频道4接收数据地址
#define RX_ADDR_P5      0x0F  // 频道5接收数据地址
#define TX_ADDR         0x10  // 发送地址寄存器
#define RX_PW_P0        0x11  // 接收频道0接收数据长度
#define RX_PW_P1        0x12  // 接收频道0接收数据长度
#define RX_PW_P2        0x13  // 接收频道0接收数据长度
#define RX_PW_P3        0x14  // 接收频道0接收数据长度
#define RX_PW_P4        0x15  // 接收频道0接收数据长度
#define RX_PW_P5        0x16  // 接收频道0接收数据长度
#define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置

#define TX_OK   		0x20  //TX发送完成中断
#define MAX_TX  		0x10  //达到最大发送次数中断
//**************************************************************************************
void Delay(unsigned int s);
void inerDelay_us(unsigned char n);
void init_NRF24L01(void);
uint SPI_RW(uint uchar);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
uchar nRF24L01_TxPacket(unsigned char * tx_buf);
//*****************************************长延时*****************************************


//**************************************************************************************************
//大函数
//**************************************************************************************************
void delay(uint time)         //int型数据为16位,所以最大值为65535            
 {
  uint  i,j;             //定义变量i,j,用于循环语句 
  for(i=0;i<time;i++)    //for循环,循环50*time次
     for(j=0;j<50;j++); //for循环,循环50次
 }
//******************************************************************************************
uint 	bdata sta;   //状态标志
sbit	RX_DR	=sta^6;
sbit	TX_DS	=sta^5;
sbit	MAX_RT	=sta^4;
/******************************************************************************************
/*延时函数
/******************************************************************************************/
void inerDelay_us(unsigned char n)
{
	for(;n>0;n--)
		_nop_();
}
//****************************************************************************************
/*NRF24L01初始化
//***************************************************************************************/
void init_NRF24L01(void)
{
    inerDelay_us(100);
 	CE=0;    // chip enable
 	CSN=1;   // Spi disable 
 	SCK=0;   // Spi clock line init high
	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, 40);        //   设置信道工作为2.4GHZ,收发必须一致
	SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f);   		//设置发射速率为1MHZ,发射功率为最大值0dB
}
/****************************************************************************************************
/*函数:uint SPI_RW(uint uchar)
/*功能:NRF24L01的SPI写时序
/****************************************************************************************************/
uint SPI_RW(uint uchar)
{
	uint bit_ctr;
   	for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
   	{
		MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
		uchar = (uchar << 1);           // shift next bit into MSB..
		SCK = 1;                      // Set SCK high..
		uchar |= MISO;       		  // capture current MISO bit
		SCK = 0;            		  // ..then set SCK low again
   	}
    return(uchar);           		  // return read uchar
}
/****************************************************************************************************
/*函数:uchar SPI_Read(uchar reg)
/*功能:NRF24L01的SPI时序
/****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
	uchar reg_val;
	
	CSN = 0;                // CSN low, initialize SPI communication...
	SPI_RW(reg);            // Select register to read from..
	reg_val = SPI_RW(0);    // ..then read registervalue
	CSN = 1;                // CSN high, terminate SPI communication
	
	return(reg_val);        // return register value
}
/****************************************************************************************************/
/*功能:NRF24L01读写寄存器函数
/****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
	uint status;
	
	CSN = 0;                   // CSN low, init SPI transaction
	status = SPI_RW(reg);      // select register
	SPI_RW(value);             // ..and write value to it..
	CSN = 1;                   // CSN high again
	
	return(status);            // return nRF24L01 status uchar
}
/****************************************************************************************************/
/*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
/****************************************************************************************************/
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
	uint status,uchar_ctr;
	
	CSN = 0;                    		// Set CSN low, init SPI tranaction
	status = SPI_RW(reg);       		// Select register to write to and read status uchar
	
	for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
		pBuf[uchar_ctr] = SPI_RW(0);    // 
	
	CSN = 1;                           
	
	return(status);                    // return nRF24L01 status uchar
}
/*********************************************************************************************************
/*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
/*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
/*********************************************************************************************************/
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
	uint status,uchar_ctr;
	
	CSN = 0;            //SPI使能       
	status = SPI_RW(reg);   
	for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
		SPI_RW(*pBuf++);
	CSN = 1;           //关闭SPI
	return(status);    // 
}
/****************************************************************************************************/
/*函数:void SetRX_Mode(void)
/*功能:数据接收配置 
/****************************************************************************************************/
void SetRX_Mode(void)
{
	CE=0;
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);   		// IRQ收发完成中断响应,16位CRC	,主接收
	CE = 1; 
	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使能
		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中数据
/**********************************************************************************************************/
uchar nRF24L01_TxPacket(unsigned char * tx_buf)
{
	uchar sta;
	CE=0;
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
	CE=1;
	inerDelay_us(130);
	CE=0;			//StandBy I模式	
	SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); 			 // 装载数据	
	CE=1;		 //置高CE,激发数据发送
	while(IRQ!=0);                 //等待发送完成
	sta=SPI_Read(STATUS);		   
	if(sta&MAX_TX)                          //达到最大重发次数
	{
		SPI_RW_Reg(FLUSH_TX,0xff);  //清除TX FIFO寄存器 
		return MAX_TX; 
	}
	if(sta&TX_OK)                           //发送完成
	{
		return 0;
	}
	return 0xff;//其他原因发送失败
}
//************************************主函数************************************************************
void main(void)
{
	unsigned char TxBuf[32]={1};	  
	unsigned char RxBuf[32]={0};	
  init_NRF24L01() ;
	Delay(6000);
	while(1)
	{
		if(nRF24L01_TxPacket(TxBuf))
		{
			SPI_RW_Reg(FLUSH_TX,0x00);   		   //清空发送缓冲区,准备下一次发送
			SPI_RW_Reg(WRITE_REG+STATUS,0x70);     //写1清除中断
			LED = 0;
			delay(600);
		}
		else
		{
			LED = 1;
			delay(600);
		}
	}
}

如果你使用过51单片机,上面的代码一定难不倒你,直接复制改改引脚就可以用了。

#include <wiringPi.h>  
#include <stdio.h>
typedef unsigned char uchar;
typedef unsigned char uint;
//*********************************************NRF24L01*************************************
#define TX_ADR_WIDTH    5   	// 5 uints TX address width
#define RX_ADR_WIDTH    5   	// 5 uints RX address width
#define TX_PLOAD_WIDTH  32  	// 20 uints TX payload
#define RX_PLOAD_WIDTH  32  	// 20 uints TX payload
uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//本地地址
uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01};	//接收地址
//***************************************NRF24L01寄存器指令*******************************************************
#define READ_REG        0x00  	// 读寄存器指令
#define WRITE_REG       0x20 	// 写寄存器指令
#define RD_RX_PLOAD     0x61  	// 读取接收数据指令
#define WR_TX_PLOAD     0xA0  	// 写待发数据指令
#define FLUSH_TX        0xE1 	// 冲洗发送 FIFO指令
#define FLUSH_RX        0xE2  	// 冲洗接收 FIFO指令
#define REUSE_TX_PL     0xE3  	// 定义重复装载数据指令
#define NOP             0xFF  	// 保留
//*************************************SPI(nRF24L01)寄存器地址****************************************************
#define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
#define EN_AA           0x01  // 自动应答功能设置
#define EN_RXADDR       0x02  // 可用信道设置
#define SETUP_AW        0x03  // 收发地址宽度设置
#define SETUP_RETR      0x04  // 自动重发功能设置
#define RF_CH           0x05  // 工作频率设置
#define RF_SETUP        0x06  // 发射速率、功耗功能设置
#define STATUS          0x07  // 状态寄存器
#define OBSERVE_TX      0x08  // 发送监测功能
#define CD              0x09  // 地址检测           
#define RX_ADDR_P0      0x0A  // 频道0接收数据地址
#define RX_ADDR_P1      0x0B  // 频道1接收数据地址
#define RX_ADDR_P2      0x0C  // 频道2接收数据地址
#define RX_ADDR_P3      0x0D  // 频道3接收数据地址
#define RX_ADDR_P4      0x0E  // 频道4接收数据地址
#define RX_ADDR_P5      0x0F  // 频道5接收数据地址
#define TX_ADDR         0x10  // 发送地址寄存器
#define RX_PW_P0        0x11  // 接收频道0接收数据长度
#define RX_PW_P1        0x12  // 接收频道0接收数据长度
#define RX_PW_P2        0x13  // 接收频道0接收数据长度
#define RX_PW_P3        0x14  // 接收频道0接收数据长度
#define RX_PW_P4        0x15  // 接收频道0接收数据长度
#define RX_PW_P5        0x16  // 接收频道0接收数据长度
#define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置

#define TX_OK   		0x20  //TX发送完成中断
#define MAX_TX  		0x10  //达到最大发送次数中断
//**************************************************************************************
void init_NRF24L01(void);
uint SPI_RW(uint dat);
uchar SPI_Read(uchar reg);
void SetRX_Mode(void);
uint SPI_RW_Reg(uchar reg, uchar value);
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
uchar nRF24L01_TxPacket(unsigned char * tx_buf);



uint sta;
uchar RX_DR;
#define MOSI 21
#define CSN  22
#define MISO 23
#define SCK  24
#define CE   25
#define IRQ   26
#define LEDH   digitalWrite(0, HIGH)
#define LEDL   digitalWrite(0, LOW)
//****************************************************************************************************
//*函数:uint SPI_RW(uint dat)
//*功能:NRF24L01的SPI写时序
//****************************************************************************************************/
uint SPI_RW(uint dat)
{
	uint bit_ctr;
	uchar _MOSI;
   	for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
   	{
		_MOSI = (dat & 0x80);         // output 'dat', MSB to MOSI
		if(_MOSI)
			digitalWrite(MOSI, HIGH);
		else
			digitalWrite(MOSI, LOW);
		dat = (dat << 1);           // shift next bit into MSB..
		digitalWrite(SCK, HIGH);                      // Set SCK high..
		dat |= digitalRead(MISO);       		  // capture current MISO bit
		digitalWrite(SCK, LOW);            		  // ..then set SCK low again
   	}
    return(dat);           		  // return read dat
}

//****************************************************************************************************
//*函数:uchar SPI_Read(uchar reg)
//*功能:NRF24L01的SPI读时序
//****************************************************************************************************/
uchar SPI_Read(uchar reg)
{
	uchar reg_val;
	
	digitalWrite(CSN, LOW);                // CSN low, initialize SPI communication...
	SPI_RW(reg);            // Select register to read from..
	reg_val = SPI_RW(0);    // ..then read registervalue
	digitalWrite(CSN, HIGH);                // CSN high, terminate SPI communication
	return(reg_val);        // return register value
}

//****************************************************************************************************/
//*功能:NRF24L01读写寄存器函数
//****************************************************************************************************/
uint SPI_RW_Reg(uchar reg, uchar value)
{
	uint status;
	
	digitalWrite(CSN, LOW);                   // CSN low, init SPI transaction
	status = SPI_RW(reg);      // select register
	SPI_RW(value);             // ..and write value to it..
	digitalWrite(CSN, HIGH);                   // CSN high again
	
	return(status);            // return nRF24L01 status uchar
}

//****************************************************************************************************/
//*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
//*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
//****************************************************************************************************/
uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
	uint status,uchar_ctr;
	
	digitalWrite(CSN, LOW);                    		// Set CSN low, init SPI tranaction
	status = SPI_RW(reg);       		// Select register to write to and read status uchar
	
	for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
		pBuf[uchar_ctr] = SPI_RW(0);    // 
	
	digitalWrite(CSN, HIGH);                           
	
	return(status);                    // return nRF24L01 status uchar
}

//*********************************************************************************************************
//*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
//*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
//*********************************************************************************************************/
uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
{
	uint status,uchar_ctr;
	
	digitalWrite(CSN, LOW);           //SPI使能       
	status = SPI_RW(reg);   
	for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
		SPI_RW(*pBuf++);
	digitalWrite(CSN, HIGH);           //关闭SPI
	return(status);    // 
}

//****************************************************************************************************/
//*函数:void SetRX_Mode(void)
//*功能:数据接收配置 
//****************************************************************************************************/
void SetRX_Mode(void)
{
	digitalWrite(CE, LOW);
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);   		// IRQ收发完成中断响应,16位CRC	,主接收
	digitalWrite(CE, HIGH); 
	delayMicroseconds(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);	// 读取状态寄存其来判断数据接收状况
	RX_DR = sta&0x40;
	if(RX_DR)				// 判断是否接收到数据
	{
	    digitalWrite(CE, LOW); 			//SPI使能
		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中数据
//**********************************************************************************************************/
uchar nRF24L01_TxPacket(unsigned char * tx_buf)
{
	uchar sta;
	digitalWrite(CE, LOW);
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
	digitalWrite(CE, HIGH);
	delayMicroseconds(130);
	digitalWrite(CE, LOW);			//StandBy I模式	
	SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); 			 // 装载数据	
	digitalWrite(CE, HIGH);		 //置高CE,激发数据发送
//	while(digitalRead(IRQ)!=0);                 //等待发送完成
	sta=SPI_Read(STATUS);		   
	if(sta&MAX_TX)                          //达到最大重发次数
	{
		SPI_RW_Reg(FLUSH_TX,0xff);  //清除TX FIFO寄存器 
		return MAX_TX; 
	}
	if(sta&TX_OK)                           //发送完成
	{
		return 0;
	}
	return 0xff;//其他原因发送失败
}

//****************************************************************************************
//*NRF24L01初始化
//***************************************************************************************/
void init_NRF24L01(void)
{
 	digitalWrite(CE, LOW);    // chip enable
 	digitalWrite(CSN, HIGH);   // Spi disable 
 	digitalWrite(SCK, LOW);   // Spi clock line init high
	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, 40);        //   设置信道工作为2.4GHZ,收发必须一致
	SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
	SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f);   		//设置发射速率为1MHZ,发射功率为最大值0dB
}



int main()
{
	unsigned char TxBuf[32]={1};	  
	unsigned char RxBuf[32]={0};
	wiringPiSetup() ;
	pinMode (MOSI, OUTPUT) ;
	pinMode (CSN,  OUTPUT) ;
	pinMode (MISO,  INPUT) ;
	pinMode (SCK,  OUTPUT) ;
	pinMode (CE,   OUTPUT) ;
	pinMode (0,   OUTPUT) ;
	
    init_NRF24L01() ;
	SetRX_Mode();
	delay(100);
	while(1)
	{
		if(nRF24L01_RxPacket(RxBuf))
		{
			if(RxBuf[0])
			{
				LEDH;
				SetRX_Mode();
			}
			 
			delay(1000);LEDL;delay(1000);

		}
	}
}
//*
// *  MOSI GPIO21  output
//	CSN  GPIO22	 output
//	MISO GPIO23	 input
//	SCK  GPIO24	 output
//	CE   GPIO25	 output
//	IRQ  GPIO26	 input
// */

好了,你只需在树莓派上接一个2401和led灯,便可以知道是否接收成功。结束了吗?还没有呢,因项目需求本人必须使用python控制2401,但是使用python调用C语言的时候总是有错误,那么必须使用python控制引脚来驱动2401

下面贴出来树莓派上python的2401代码

# -*- coding: UTF-8 -*-
import time
import RPi.GPIO as GPIO
#一下试一下nrf24l01的C语言宏定义
TX_ADR_WIDTH = 5   	    # 5 uints TX address width
RX_ADR_WIDTH = 5   	    # 5 uints RX address width
TX_PLOAD_WIDTH = 32  	# 20 uints TX payload
RX_PLOAD_WIDTH = 32  	# 20 uints TX payload

TX_ADDRESS   = [0x34,0x43,0x10,0x10,0x01]	#本地地址
RX_ADDRESS   = [0x34,0x43,0x10,0x10,0x01]	#接收地址
READ_REG     = 0x00  	                    # 读寄存器指令
WRITE_REG    = 0x20 	                    # 写寄存器指令
RD_RX_PLOAD  = 0x61  	                    # 读取接收数据指令
WR_TX_PLOAD  = 0xA0  	                    # 写待发数据指令
FLUSH_TX     = 0xE1 	                    # 冲洗发送 FIFO指令
FLUSH_RX     = 0xE2  	                    # 冲洗接收 FIFO指令
REUSE_TX_PL  = 0xE3  	                    # 定义重复装载数据指令
NOP          = 0xFF  	                    # 保留
#*************************************SPI(nRF24L01)寄存器地址****************************************************
CONFIG       = 0x00  # 配置收发状态,CRC校验模式以及收发状态响应方式
EN_AA        = 0x01  # 自动应答功能设置
EN_RXADDR    = 0x02  # 可用信道设置
SETUP_AW     = 0x03  # 收发地址宽度设置
SETUP_RETR   = 0x04  # 自动重发功能设置
RF_CH        = 0x05  # 工作频率设置
RF_SETUP     = 0x06  # 发射速率、功耗功能设置
STATUS       = 0x07  # 状态寄存器
OBSERVE_TX   = 0x08  # 发送监测功能
CD           = 0x09  # 地址检测           
RX_ADDR_P0   = 0x0A  # 频道0接收数据地址
RX_ADDR_P1   = 0x0B  # 频道1接收数据地址
RX_ADDR_P2   = 0x0C  # 频道2接收数据地址
RX_ADDR_P3   = 0x0D  # 频道3接收数据地址
RX_ADDR_P4   = 0x0E  # 频道4接收数据地址
RX_ADDR_P5   = 0x0F  # 频道5接收数据地址
TX_ADDR      = 0x10  # 发送地址寄存器
RX_PW_P0     = 0x11  # 接收频道0接收数据长度
RX_PW_P1     = 0x12  # 接收频道0接收数据长度
RX_PW_P2     = 0x13  # 接收频道0接收数据长度
RX_PW_P3     = 0x14  # 接收频道0接收数据长度
RX_PW_P4     = 0x15  # 接收频道0接收数据长度
RX_PW_P5     = 0x16  # 接收频道0接收数据长度
FIFO_STATUS  = 0x17  # FIFO栈入栈出状态寄存器设置

TX_OK        = 0x20  #TX发送完成中断
MAX_TX       = 0x10  #达到最大发送次数中断

#sta = 0
#RX_DR = 0
#树莓派各个引脚的定义
MOSI =  29
CSN  =  31
MISO =  33
SCK  =  35
CE   =  37
IRQ  =  32
def GPIO_Init():
    GPIO.setmode(GPIO.BOARD) 
    GPIO.setwarnings(False)
    Pinlist = [29,31,35,37,11]
    GPIO.setup(Pinlist, GPIO.OUT)
    Pinlist_Input = [33,32]
    GPIO.setup(Pinlist_Input, GPIO.IN)
    return 0

def LEDH():
    GPIO.output(11, GPIO.HIGH)

def LEDL():
    GPIO.output(11, GPIO.LOW)

#****************************************************************************************************
#*函数:uint SPI_RW(uint dat)
#*功能:NRF24L01的SPI写时序
#****************************************************************************************************
def SPI_RW(dat):
    bit_ctr = 8
    _MOSI   = 0
    while(bit_ctr):

        bit_ctr = bit_ctr - 1
        _MOSI = dat & 0x80              #output 'dat', MSB to MOSI
        if(_MOSI):
            GPIO.output(MOSI, GPIO.HIGH)
        else:
            GPIO.output(MOSI, GPIO.LOW)
        dat = (dat << 1)                #shift next bit into MSB..
        GPIO.output(SCK, GPIO.HIGH)          #Set SCK GPIO.high..
        dat |= GPIO.input(MISO)        #capture current MISO bit
        GPIO.output(SCK, GPIO.LOW)           #..then set SCK GPIO.low again
    return dat           		        #return read dat

#****************************************************************************************************
#*函数:uchar SPI_Read(uchar reg)
#*功能:NRF24L01的SPI读时序
#*****************************************************************************************************
def SPI_Read(reg):
    reg_val = 0
    GPIO.output(CSN, GPIO.LOW)              #CSN GPIO.low, initialize SPI communication...
    SPI_RW(reg)                         #Select register to read from..
    reg_val = SPI_RW(0)                 #..then read registervalue
    GPIO.output(CSN, GPIO.HIGH)             #CSN GPIO.high, terminate SPI communication
    return reg_val                      #return register value

#****************************************************************************************************#
#*功能:NRF24L01读写寄存器函数
#****************************************************************************************************#
def SPI_RW_Reg(reg,value):
    status = 0
    GPIO.output(CSN, GPIO.LOW)              #CSN GPIO.low, init SPI transaction
    status = SPI_RW(reg)                #select register
    SPI_RW(value)                       #..and write value to it..
    GPIO.output(CSN, GPIO.HIGH)             #CSN GPIO.high again
    return status                       #return nRF24L01 status uchar

#****************************************************************************************************#
#*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
#*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
#****************************************************************************************************#
def SPI_Read_Buf(reg, pBuf, uchars):
    status    = 0
    uchar_ctr = 0
    GPIO.output(CSN, GPIO.LOW)                    		# Set CSN GPIO.low, init SPI tranaction
    status = SPI_RW(reg)       		    # Select register to write to and read status uchar
    while(uchar_ctr < uchars): 
        pBuf[uchar_ctr] = SPI_RW(0)     #
        uchar_ctr = uchar_ctr + 1 
    GPIO.output(CSN, GPIO.HIGH)                           
    return(status)                      #return nRF24L01 status uchar

#*********************************************************************************************************
#*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
#*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
#*********************************************************************************************************#
def SPI_Write_Buf(reg, pBuf, uchars):
    status = 0
    uchar_ctr = 0	
    GPIO.output(CSN, GPIO.LOW)           #SPI使能       
    status = SPI_RW(reg)   
    while(uchar_ctr < uchars): #
        SPI_RW(pBuf[uchar_ctr])
        uchar_ctr = uchar_ctr + 1
    GPIO.output(CSN, GPIO.HIGH)           #关闭SPI
    return(status)


#****************************************************************************************************#
#*函数:void SetRX_Mode(void)
#*功能:数据接收配置 
#****************************************************************************************************#
def SetRX_Mode():
	GPIO.output(CE, GPIO.LOW)
	SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f)   		# IRQ收发完成中断响应,16位CRC	,主接收
	GPIO.output(CE, GPIO.HIGH) 


#******************************************************************************************************#
#*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
#*功能:数据读取后放如rx_buf接收缓冲区中
#******************************************************************************************************#
def nRF24L01_RxPacket(rx_buf):

    revale = 0
    sta = 0
    RX_DR = 0
    sta = SPI_Read(STATUS)	                                # 读取状态寄存其来判断数据接收状况
    RX_DR = sta&0x40
    if(RX_DR):				                                # 判断是否接收到数据
        GPIO.output(CE, GPIO.LOW) 			                #SPI使能
        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中数据
#**********************************************************************************************************#
def nRF24L01_TxPacket(tx_buf):
    sta = 0
    GPIO.output(CE, GPIO.LOW)
    SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e)
    GPIO.output(CE, GPIO.HIGH)
    time.sleep(0.00001)
    GPIO.output(CE, GPIO.LOW)			                        #StandBy I模式	
    SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH) 			# 装载数据	
    GPIO.output(CE, GPIO.HIGH)		                            #置高CE,激发数据发送
#	while(GPIO.input(IRQ)!=0)                                   #等待发送完成
    sta=SPI_Read(STATUS)		   
    if(sta & MAX_TX):                                           #达到最大重发次数
        SPI_RW_Reg(FLUSH_TX,0xff)                               #清除TX FIFO寄存器
        return MAX_TX
        
    if(sta&TX_OK):                                              #发送完成
        return 0
	
    return 0xff                                                 #其他原因发送失败


#****************************************************************************************
#*NRF24L01初始化
#***************************************************************************************#
def Init_NRF24L01():
    GPIO.output(CE, GPIO.LOW)    # chip enable
    GPIO.output(CSN, GPIO.HIGH)   # Spi disable 
    GPIO.output(SCK, GPIO.LOW)   # Spi clock line init GPIO.high
    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, 40)        #   设置信道工作为2.4GHZ,收发必须一致
    SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH) #设置接收数据长度,本次设置为32字节
    SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f)   		#设置发射速率为1MHZ,发射功率为最大值0dB
    return 0

if __name__ == "__main__":
    TxBuf = [1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0]
    RxBuf = [0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0]
    GPIO_Init()
    Init_NRF24L01()
    SetRX_Mode()
    while True:
        if nRF24L01_RxPacket(RxBuf):
            if RxBuf[0]:
                print(RxBuf)
                LEDH()
                SetRX_Mode()
            time.sleep(1)
            LEDL()
            time.sleep(1)
  • 17
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值