NRF24L01无线模块

    最近在准备9月份的电子设计大赛,这几天没什么事,就写了一些模块的驱动。今天学习了一下无线模块NRF24L01,由于手上有好几块原子的STM32的板子,于是首先参考了一下原子的程序,然后又看了一下NRF24L01的资料,现在把心得和体会记录下来。

 

一、模块介绍

(1) 2.4Ghz 全球开放ISM 频段免许可证使用
(2) 最高工作速率2Mbps,高效GFSK调制,抗干扰能力强,特别适合工业控制场合
(3) 126 频道,满足多点通信和跳频通信需要
(4) 内置硬件CRC 检错和点对多点通信地址控制
(5) 低功耗1.9 - 3.6V 工作,待机模式下状态为22uA;掉电模式下为900nA
(6) 内置2.4Ghz 天线,体积种类多样
(7) 模块可软件设地址,只有收到本机地址时才会输出数据(提供中断指示),可直接接各种单片机使用,软件编程非常方便
(8) 内置专门稳压电路,使用各种电源包括DC/DC 开关电源均有很好的通信效果
(9) 2.54MM间距接口,DIP封装
(10)工作于Enhanced ShockBurst 具有Automatic packethandling, Auto packet transaction handling,具有可选的内置包应答机制,极大的降低丢包率。
(11)与51系列单片机P0口连接时候,需要加10K的上拉电阻,与其余口连接不需要。
(12)其他系列的单片机,如果是5V的,请参考该系列单片机IO口输出电流大小,如果超过10mA,需要串联电阻分压,否则容易烧毁模块! 如果是3.3V的,可以直接和RF24l01模块的IO口线连接。比如AVR系列单片机如果是5V 的,一般串接2K 的电阻。

二、驱动编写

    NRF24L01是通过SPI总线跟单片机进行通信的,所以首先需要先编写SPI的驱动。

    根据SPI协议可以采用IO口模拟,由于我使用的STM32F103带有SPI外设,结合库函数设置SPI,起初始化函数如下:

void SPIx_Init(void)
{
    u8 SPIx_ReadWriteByte(u8 TxData);

	GPIO_InitTypeDef GPIO_InitStructure;
  
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );	

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //¸´ÓÃÍÆÍìÊä³ö
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);

	SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;  //ÉèÖÃSPIµ¥Ïò»òÕßË«ÏòµÄÊý¾Ýģʽ:SPIÉèÖÃΪ˫ÏßË«ÏòÈ«Ë«¹¤
	SPI_InitStructure.SPI_Mode = SPI_Mode_Master;		//ÉèÖÃSPI¹¤×÷ģʽ:ÉèÖÃΪÖ÷SPI
	SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//ÉèÖÃSPIµÄÊý¾Ý´óС:SPI·¢ËͽÓÊÕ8λ֡½á¹¹
	SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;		//Ñ¡ÔñÁË´®ÐÐʱÖÓµÄÎÈ̬:ʱÖÓÐü¿ÕµÍµçƽ
	SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;	//Êý¾Ý²¶»ñÓÚµÚÒ»¸öʱÖÓÑØ
	SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;		//NSSÐźÅÓÉÓ²¼þ£¨NSS¹Ü½Å£©»¹ÊÇÈí¼þ£¨Ê¹ÓÃSSI룩¹ÜÀí:ÄÚ²¿NSSÐźÅÓÐSSIλ¿ØÖÆ
	SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;		//¶¨Ò岨ÌØÂÊÔ¤·ÖƵµÄÖµ:²¨ÌØÂÊÔ¤·ÖƵֵΪ256
	SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;	//Ö¸¶¨Êý¾Ý´«Êä´ÓMSBλ»¹ÊÇLSBλ¿ªÊ¼:Êý¾Ý´«Êä´ÓMSBλ¿ªÊ¼
	SPI_InitStructure.SPI_CRCPolynomial = 7;	//CRCÖµ¼ÆËãµÄ¶àÏîʽ
	SPI_Init(SPI1, &SPI_InitStructure);  //¸ù¾ÝSPI_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèSPIx¼Ä´æÆ÷

	SPI_Cmd(SPI1, ENABLE); //ʹÄÜSPIÍâÉè
	
	SPIx_ReadWriteByte(0xff);//Æô¶¯´«Êä	
}  

    这里是对SPI的IO口进行初始化,以及SPI的初始设置,包括SPI数据传输模式,主从模式,SPI数据大小等。

 

下面要实现SPI的读/写函数,注意,这个函数是在一次操作中先发送一个字节数据,然后再读取一字节数组。

u8 SPIx_ReadWriteByte(u8 TxData)
{		
	u8 retry=0;				 
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) //¼ì²éÖ¸¶¨µÄSPI±ê־λÉèÖÃÓë·ñ:·¢ËÍ»º´æ¿Õ±ê־λ
		{
		retry++;
		if(retry>200)return 0;
		}			  
	SPI_I2S_SendData(SPI1, TxData); //ͨ¹ýÍâÉèSPIx·¢ËÍÒ»¸öÊý¾Ý
	retry=0;
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); //¼ì²éÖ¸¶¨µÄSPI±ê־λÉèÖÃÓë·ñ:½ÓÊÜ»º´æ·Ç¿Õ±ê־λ
		{
		retry++;
		if(retry>200)return 0;
		}	  						    
	return SPI_I2S_ReceiveData(SPI1); //·µ»Øͨ¹ýSPIx×î½ü½ÓÊÕµÄÊý¾Ý					    
}

    这是最基本的函数,完成GPIO 模拟SPI 的功能。将输出字节(MOSI)从MSB 循环输出,同时将输入字节(MISO)从LSB 循环移入。上升沿读入,下降沿输出。(从SCK 被初始化为低电平可以判断出)。

 

    SPI基本接口函数完成了,下面就可以编写NRF24L01的驱动了,首先写 写寄存器函数

u8 NRF24L01_Write_Reg(u8 reg,u8 value)
{
	u8 status;	
	Clr_NRF24L01_CSN;                 //ʹÄÜSPI´«Êä
	status =SPIx_ReadWriteByte(reg);//·¢ËͼĴæÆ÷ºÅ 
	SPIx_ReadWriteByte(value);      //дÈë¼Ä´æÆ÷µÄÖµ
	Set_NRF24L01_CSN;                 //½ûÖ¹SPI´«Êä	   
	return(status);       			//·µ»Ø״ֵ̬
}

这里CSN为使用端,每次对NRF24L01操作前都得先使能,即拉低,操作完成后,再失能。

然后发送要写入的寄存器地址,注意,这里寄存器地址的规则为:0x20+寄存器地址  0x20表示该寄存器地址是要写入的。

写入地址后,读取返回值,然后再将需要写入的数据写入。

 

    下面是读寄存器函数

u8 NRF24L01_Read_Reg(u8 reg)
{
	u8 reg_val;	    
	Clr_NRF24L01_CSN;          //ʹÄÜSPI´«Êä		
	SPIx_ReadWriteByte(reg);   //·¢ËͼĴæÆ÷ºÅ
	reg_val=SPIx_ReadWriteByte(0XFF);//¶ÁÈ¡¼Ä´æÆ÷ÄÚÈÝ
	Set_NRF24L01_CSN;          //½ûÖ¹SPI´«Êä		    
	return(reg_val);           //·µ»Ø״ֵ̬
}	

其基本思路和写寄存器差不多,也需要先写入要读取的寄存器地址,读寄存器地址的命名规则为:0x00+要读取的寄存器地址。

写入地址后,不读取返回值,然后再调用SPI读/写函数,其中写入的数据随便写,因为根本就不会被写入对应寄存器,我们需要的只是其返回值,这个就是我们要读取的寄存器数据。

 

    NRF24L01支持写入一次寄存器地址,连续多次写入或读取数据,所以我们可以写出如下一次写入或读取多字节数据的函数

u8 NRF24L01_Read_Buf(u8 reg,u8 *pBuf,u8 len)
{
	u8 status,u8_ctr;	       
	Clr_NRF24L01_CSN;           //ʹÄÜSPI´«Êä
	status=SPIx_ReadWriteByte(reg);//·¢ËͼĴæÆ÷Öµ(λÖÃ),²¢¶Áȡ״ֵ̬   	   
	for(u8_ctr=0;u8_ctr<len;u8_ctr++)pBuf[u8_ctr]=SPIx_ReadWriteByte(0XFF);//¶Á³öÊý¾Ý
	Set_NRF24L01_CSN;       //¹Ø±ÕSPI´«Êä
	return status;        //·µ»Ø¶Áµ½µÄ״ֵ̬
}

 

u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 len)
{
	u8 status,u8_ctr;	    
	Clr_NRF24L01_CSN;          //ʹÄÜSPI´«Êä
	status = SPIx_ReadWriteByte(reg);//·¢ËͼĴæÆ÷Öµ(λÖÃ),²¢¶Áȡ״ֵ̬
	for(u8_ctr=0; u8_ctr<len; u8_ctr++)SPIx_ReadWriteByte(*pBuf++); //дÈëÊý¾Ý	 
	Set_NRF24L01_CSN;       //¹Ø±ÕSPI´«Êä
	return status;          //·µ»Ø¶Áµ½µÄ״ֵ̬
}

这两个函数主要用于连续向Tx_FIFO发送数据或者从RX_FIFO读取数据。

 

下面编写发送一次数据的函数

u8 NRF24L01_TxPacket(u8 *txbuf)
{
	u8 sta;
	SPIx_SetSpeed(SPI_BaudRatePrescaler_8);//spiËÙ¶ÈΪ9Mhz£¨24L01µÄ×î´óSPIʱÖÓΪ10Mhz£©   
	Clr_NRF24L01_CE;
	NRF24L01_Write_Buf(NRF24L01_WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//дÊý¾Ýµ½TX BUF  32¸ö×Ö½Ú
	Set_NRF24L01_CE;//Æô¶¯·¢ËÍ	   
	while(NRF24L01_IRQ!=0);//µÈ´ý·¢ËÍÍê³É
	sta=NRF24L01_Read_Reg(STATUS);  //¶Áȡ״̬¼Ä´æÆ÷µÄÖµ	   
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+STATUS,sta); //Çå³ýTX_DS»òMAX_RTÖжϱêÖ¾
	if(sta&MAX_TX)//´ïµ½×î´óÖØ·¢´ÎÊý
		{
		NRF24L01_Write_Reg(NRF24L01_FLUSH_TX,0xff);//Çå³ýTX FIFO¼Ä´æÆ÷ 
		return MAX_TX; 
		}
	if(sta&TX_OK)//·¢ËÍÍê³É
		{
		return TX_OK;
		}
	return 0xff;//ÆäËûÔ­Òò·¢ËÍʧ°Ü
}

首先将CE拉低,然后将要发送的数据送入Tx_FIFO中,再将CE拉高,启动发送。然后通过读取状态寄存器,获取发送结果。

 

接受一次数据的函数

u8 NRF24L01_RxPacket(u8 *rxbuf)
{
	u8 sta;		    							   
	SPIx_SetSpeed(SPI_BaudRatePrescaler_8); //spiËÙ¶ÈΪ9Mhz£¨24L01µÄ×î´óSPIʱÖÓΪ10Mhz£©   
	sta=NRF24L01_Read_Reg(STATUS);  //¶Áȡ״̬¼Ä´æÆ÷µÄÖµ    	 
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+STATUS,sta); //Çå³ýTX_DS»òMAX_RTÖжϱêÖ¾
	if(sta&RX_OK)//½ÓÊÕµ½Êý¾Ý
		{
		NRF24L01_Read_Buf(NRF24L01_RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//¶ÁÈ¡Êý¾Ý
		NRF24L01_Write_Reg(NRF24L01_FLUSH_RX,0xff);//Çå³ýRX FIFO¼Ä´æÆ÷ 
		return 0; 
		}	   
	return 1;//ûÊÕµ½ÈκÎÊý¾Ý
}	

首先通过读取状态寄存器数据,看是否收到数据,若收到数据,则将其从Rx_FIFO中读出存入数组中,然后再清楚Rx_FIFO缓存。

 

最后的两个函数就是设置NRF24L01的模式,是接收模式还是发送模式。NRF24L01的模式不止这两张,其他的模式暂时没有用到,不做介绍

void RX_Mode(void)
{
	Clr_NRF24L01_CE;	  
	NRF24L01_Write_Buf(NRF24L01_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH);//дRX½ÚµãµØÖ·
	
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_AA,0x01);    //ʹÄÜͨµÀ0µÄ×Ô¶¯Ó¦´ð    
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_RXADDR,0x01);//ʹÄÜͨµÀ0µÄ½ÓÊÕµØÖ·  	 
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_CH,40);	     //ÉèÖÃRFͨÐÅƵÂÊ		  
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//Ñ¡ÔñͨµÀ0µÄÓÐЧÊý¾Ý¿í¶È 	    
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_SETUP,0x0f);//ÉèÖÃTX·¢Éä²ÎÊý,0dbÔöÒæ,2Mbps,µÍÔëÉùÔöÒ濪Æô   
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+CONFIG, 0x0f);//ÅäÖûù±¾¹¤×÷ģʽµÄ²ÎÊý;PWR_UP,EN_CRC,16BIT_CRC,½ÓÊÕģʽ 
	Set_NRF24L01_CE; //CEΪ¸ß,½øÈë½ÓÊÕģʽ 
}
void TX_Mode(void)
{														 
	Clr_NRF24L01_CE;	    
	NRF24L01_Write_Buf(NRF24L01_WRITE_REG+TX_ADDR,(u8*)TX_ADDRESS,TX_ADR_WIDTH);//дTX½ÚµãµØÖ· 
	NRF24L01_Write_Buf(NRF24L01_WRITE_REG+RX_ADDR_P0,(u8*)RX_ADDRESS,RX_ADR_WIDTH); //ÉèÖÃTX½ÚµãµØÖ·,Ö÷ҪΪÁËʹÄÜACK	  
	
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_AA,0x01);     //ʹÄÜͨµÀ0µÄ×Ô¶¯Ó¦´ð    
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+EN_RXADDR,0x01); //ʹÄÜͨµÀ0µÄ½ÓÊÕµØÖ·  
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+SETUP_RETR,0x1a);//ÉèÖÃ×Ô¶¯ÖØ·¢¼ä¸ôʱ¼ä:500us + 86us;×î´ó×Ô¶¯ÖØ·¢´ÎÊý:10´Î
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_CH,40);       //ÉèÖÃRFͨµÀΪ40
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+RF_SETUP,0x0f);  //ÉèÖÃTX·¢Éä²ÎÊý,0dbÔöÒæ,2Mbps,µÍÔëÉùÔöÒ濪Æô   
	NRF24L01_Write_Reg(NRF24L01_WRITE_REG+CONFIG,0x0e);    //ÅäÖûù±¾¹¤×÷ģʽµÄ²ÎÊý;PWR_UP,EN_CRC,16BIT_CRC,½ÓÊÕģʽ,¿ªÆôËùÓÐÖжÏ
	Set_NRF24L01_CE;//CEΪ¸ß,10usºóÆô¶¯·¢ËÍ
}


 

到这里,NRF24L01驱动就完成了,只要先进行模式设置(Tx_Mode或者Rx_Mode),然后调用发送或者接收函数就可以了,注意一次发送和接收的数据最多不能超过32字节。

 

下面是头文件中一些寄存器地址和命令的定义

//
//NRF24L01¼Ä´æÆ÷²Ù×÷ÃüÁî
#define NRF24L01_READ_REG        0x00  //¶ÁÅäÖüĴæÆ÷,µÍ5λΪ¼Ä´æÆ÷µØÖ·
#define NRF24L01_WRITE_REG       0x20  //дÅäÖüĴæÆ÷,µÍ5λΪ¼Ä´æÆ÷µØÖ·
#define NRF24L01_RD_RX_PLOAD     0x61  //¶ÁRXÓÐЧÊý¾Ý,1~32×Ö½Ú
#define NRF24L01_WR_TX_PLOAD     0xA0  //дTXÓÐЧÊý¾Ý,1~32×Ö½Ú
#define NRF24L01_FLUSH_TX        0xE1  //Çå³ýTX FIFO¼Ä´æÆ÷.·¢ÉäģʽÏÂÓÃ
#define NRF24L01_FLUSH_RX        0xE2  //Çå³ýRX FIFO¼Ä´æÆ÷.½ÓÊÕģʽÏÂÓÃ
#define NRF24L01_REUSE_TX_PL     0xE3  //ÖØÐÂʹÓÃÉÏÒ»°üÊý¾Ý,CEΪ¸ß,Êý¾Ý°ü±»²»¶Ï·¢ËÍ.
#define NRF24L01_NOP             0xFF  //¿Õ²Ù×÷,¿ÉÒÔÓÃÀ´¶Á״̬¼Ä´æÆ÷
//SPI(NRF24L01)¼Ä´æÆ÷µØÖ·
#define CONFIG          0x00  //ÅäÖüĴæÆ÷µØÖ·;bit0:1½ÓÊÕģʽ,0·¢Éäģʽ;bit1:µçÑ¡Ôñ;bit2:CRCģʽ;bit3:CRCʹÄÜ;
                              //bit4:ÖжÏMAX_RT(´ïµ½×î´óÖØ·¢´ÎÊýÖжÏ)ʹÄÜ;bit5:ÖжÏTX_DSʹÄÜ;bit6:ÖжÏRX_DRʹÄÜ
#define EN_AA           0x01  //ʹÄÜ×Ô¶¯Ó¦´ð¹¦ÄÜ  bit0~5,¶ÔӦͨµÀ0~5
#define EN_RXADDR       0x02  //½ÓÊÕµØÖ·ÔÊÐí,bit0~5,¶ÔӦͨµÀ0~5
#define SETUP_AW        0x03  //ÉèÖõØÖ·¿í¶È(ËùÓÐÊý¾ÝͨµÀ):bit1,0:00,3×Ö½Ú;01,4×Ö½Ú;02,5×Ö½Ú;
#define SETUP_RETR      0x04  //½¨Á¢×Ô¶¯ÖØ·¢;bit3:0,×Ô¶¯ÖØ·¢¼ÆÊýÆ÷;bit7:4,×Ô¶¯ÖØ·¢ÑÓʱ 250*x+86us
#define RF_CH           0x05  //RFͨµÀ,bit6:0,¹¤×÷ͨµÀƵÂÊ;
#define RF_SETUP        0x06  //RF¼Ä´æÆ÷;bit3:´«ÊäËÙÂÊ(0:1Mbps,1:2Mbps);bit2:1,·¢É书ÂÊ;bit0:µÍÔëÉù·Å´óÆ÷ÔöÒæ
#define STATUS          0x07  //״̬¼Ä´æÆ÷;bit0:TX FIFOÂú±êÖ¾;bit3:1,½ÓÊÕÊý¾ÝͨµÀºÅ(×î´ó:6);bit4,´ïµ½×î¶à´ÎÖØ·¢
                              //bit5:Êý¾Ý·¢ËÍÍê³ÉÖжÏ;bit6:½ÓÊÕÊý¾ÝÖжÏ;
#define MAX_TX  		0x10  //´ïµ½×î´ó·¢ËÍ´ÎÊýÖжÏ
#define TX_OK   		0x20  //TX·¢ËÍÍê³ÉÖжÏ
#define RX_OK   		0x40  //½ÓÊÕµ½Êý¾ÝÖжÏ

#define OBSERVE_TX      0x08  //·¢Ëͼì²â¼Ä´æÆ÷,bit7:4,Êý¾Ý°ü¶ªÊ§¼ÆÊýÆ÷;bit3:0,ÖØ·¢¼ÆÊýÆ÷
#define CD              0x09  //Ôز¨¼ì²â¼Ä´æÆ÷,bit0,Ôز¨¼ì²â;
#define RX_ADDR_P0      0x0A  //Êý¾ÝͨµÀ0½ÓÊÕµØÖ·,×î´ó³¤¶È5¸ö×Ö½Ú,µÍ×Ö½ÚÔÚÇ°
#define RX_ADDR_P1      0x0B  //Êý¾ÝͨµÀ1½ÓÊÕµØÖ·,×î´ó³¤¶È5¸ö×Ö½Ú,µÍ×Ö½ÚÔÚÇ°
#define RX_ADDR_P2      0x0C  //Êý¾ÝͨµÀ2½ÓÊÕµØÖ·,×îµÍ×Ö½Ú¿ÉÉèÖÃ,¸ß×Ö½Ú,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;
#define RX_ADDR_P3      0x0D  //Êý¾ÝͨµÀ3½ÓÊÕµØÖ·,×îµÍ×Ö½Ú¿ÉÉèÖÃ,¸ß×Ö½Ú,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;
#define RX_ADDR_P4      0x0E  //Êý¾ÝͨµÀ4½ÓÊÕµØÖ·,×îµÍ×Ö½Ú¿ÉÉèÖÃ,¸ß×Ö½Ú,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;
#define RX_ADDR_P5      0x0F  //Êý¾ÝͨµÀ5½ÓÊÕµØÖ·,×îµÍ×Ö½Ú¿ÉÉèÖÃ,¸ß×Ö½Ú,±ØÐëͬRX_ADDR_P1[39:8]ÏàµÈ;
#define TX_ADDR         0x10  //·¢Ë͵ØÖ·(µÍ×Ö½ÚÔÚÇ°),ShockBurstTMģʽÏÂ,RX_ADDR_P0Óë´ËµØÖ·ÏàµÈ
#define RX_PW_P0        0x11  //½ÓÊÕÊý¾ÝͨµÀ0ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P1        0x12  //½ÓÊÕÊý¾ÝͨµÀ1ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P2        0x13  //½ÓÊÕÊý¾ÝͨµÀ2ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P3        0x14  //½ÓÊÕÊý¾ÝͨµÀ3ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P4        0x15  //½ÓÊÕÊý¾ÝͨµÀ4ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define RX_PW_P5        0x16  //½ÓÊÕÊý¾ÝͨµÀ5ÓÐЧÊý¾Ý¿í¶È(1~32×Ö½Ú),ÉèÖÃΪ0Ôò·Ç·¨
#define FIFO_STATUS     0x17  //FIFO״̬¼Ä´æÆ÷;bit0,RX FIFO¼Ä´æÆ÷¿Õ±êÖ¾;bit1,RX FIFOÂú±êÖ¾;bit2,3,±£Áô
                              //bit4,TX FIFO¿Õ±êÖ¾;bit5,TX FIFOÂú±êÖ¾;bit6,1,Ñ­»··¢ËÍÉÏÒ»Êý¾Ý°ü.0,²»Ñ­»·;
//
//24L01²Ù×÷Ïß
	   
#define NRF24L01_IRQ  (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_5))

#define Set_NRF24L01_CE  {GPIO_SetBits(GPIOA,GPIO_Pin_4);}
#define Clr_NRF24L01_CE  {GPIO_ResetBits(GPIOA,GPIO_Pin_4);}

#define Set_NRF24L01_CSN  {GPIO_SetBits(GPIOC,GPIO_Pin_4);}
#define Clr_NRF24L01_CSN  {GPIO_ResetBits(GPIOC,GPIO_Pin_4);}


 
//24L01·¢ËͽÓÊÕÊý¾Ý¿í¶È¶¨Òå
#define TX_ADR_WIDTH    5   //5×ֽڵĵØÖ·¿í¶È
#define RX_ADR_WIDTH    5   //5×ֽڵĵØÖ·¿í¶È
#define TX_PLOAD_WIDTH  32  //20×Ö½ÚµÄÓû§Êý¾Ý¿í¶È
#define RX_PLOAD_WIDTH  32  //20×Ö½ÚµÄÓû§Êý¾Ý¿í¶È

void NRF24L01_SPI_Init(void);
void NRF24L01_Init(void);//³õʼ»¯
void RX_Mode(void);//ÅäÖÃΪ½ÓÊÕģʽ
void TX_Mode(void);//ÅäÖÃΪ·¢ËÍģʽ
u8 NRF24L01_Write_Buf(u8 reg, u8 *pBuf, u8 u8s);//дÊý¾ÝÇø
u8 NRF24L01_Read_Buf(u8 reg, u8 *pBuf, u8 u8s);//¶ÁÊý¾ÝÇø		  
u8 NRF24L01_Read_Reg(u8 reg);			//¶Á¼Ä´æÆ÷
u8 NRF24L01_Write_Reg(u8 reg, u8 value);//д¼Ä´æÆ÷
u8 NRF24L01_Check(void);//¼ì²é24L01ÊÇ·ñ´æÔÚ
u8 NRF24L01_TxPacket(u8 *txbuf);//·¢ËÍÒ»¸ö°üµÄÊý¾Ý
u8 NRF24L01_RxPacket(u8 *rxbuf);//½ÓÊÕÒ»¸ö°üµÄÊý¾Ý


 



 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值