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

📄 nrf24l01.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
字号:
#define NRF_GLOBALS

#include "..\App\includes.h"
#include "NRF24L01.h"
#include "demo.h"

/***************************************************/
//#define uchar unsigned char
//#define TX_ADR_WIDTH    5   // 5 bytes TX(RX) address width
//#define TX_PLOAD_WIDTH  20  // 20 bytes TX payload
//uchar TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01}; // Define a static TX address
//uchar rx_buf[TX_PLOAD_WIDTH];
//uchar tx_buf[TX_PLOAD_WIDTH]={"1234567890abcdefghij"};
//uchar flag;
//uchar rx_com_buffer[10];
//uchar tx_com_buffer[10];

GPIO_InitTypeDef GPIO_InitStructure;



/**************************************************/

void SPI_CS(uchar a){
	if(a==1) GPIO_SetBits(GPIOB, GPIO_Pin_12);	    /*开*/
	else GPIO_ResetBits(GPIOB, GPIO_Pin_12);	    /*关*/
	
}

void SPI_DOUT(uchar a){
	if(a==1) GPIO_SetBits(GPIOB, GPIO_Pin_15);	    /*开*/
	else GPIO_ResetBits(GPIOB, GPIO_Pin_15);		/*关*/
}

void SPI_CLK(uchar a){
	if(a==1) GPIO_SetBits(GPIOB, GPIO_Pin_13);	    /*开*/
	else GPIO_ResetBits(GPIOB, GPIO_Pin_13);		/*关*/
}

void MODE_CE(uchar a){					   /*NRF24L01 模式控制引脚CE*/ 
	if(a==1) GPIO_SetBits(GPIOC, GPIO_Pin_6);	    /*开*/
	else GPIO_ResetBits(GPIOC, GPIO_Pin_6);			/*关*/
}

void SPI2_NRF24L01_Init(void)
{
  SPI_InitTypeDef  SPI_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
   
  /* 使能SPI2,GPIOB时钟 */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 ,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  /* 配置SPI2接口: SCK=PB13,MISO=PB14,MOSI=PB15 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;/*复用推挽输出*/
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* 配置PB12推挽输出模式, 有于片选 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;/*推挽输出*/
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /*配置NRF24L01模式引脚CE=PC6 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;     
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;/*推挽输出*/
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
  /*配置NRF24L01 中断控制引脚IRQ=PB8  */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;	 
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;/*输入下拉*/
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_SetBits(GPIOB, GPIO_Pin_8);	    /*开*/
  NotSelect_SDR();

  /* SPI2接口参数配置 */ 
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI2, &SPI_InitStructure);
  
  /* 使能SPI2接口  */
  SPI_Cmd(SPI2, ENABLE);   
}

uchar SPI2_NRF_SendByte(u8 byte)
{
  /* 当DR寄存器不为空时循环 */
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
  //NotSelect_Flash();  while(1);
  /* 通过SPI2外设发送数据 */
  SPI_I2S_SendData(SPI2, byte);

  /* 等待接收数据 */
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);

  /* 返回从SPI总线读取的数据 */
  return SPI_I2S_ReceiveData(SPI2);
}


uchar SPI_RW_Reg(unsigned char data1,unsigned char data2) 
{ 
 unsigned int Data = 0,a; 
  
  Select_SDR();
  Data=SPI2_NRF_SendByte(data1);
  SPI2_NRF_SendByte(data2);
  NotSelect_SDR(); 
  return(Data);
 
}  

uchar SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
	uchar status,byte_ctr;

  	Select_SDR();              /* CSN置低, 初始化SPI传输*/
  	status=SPI2_NRF_SendByte(reg);
  	
  	for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) /* 将所有字节写入缓冲*/
    {
		
  		/*发送字节*/  
		SPI2_NRF_SendByte(*pBuf++);
  		//SPI_I2S_SendData(SPI2,*pBuf++); 
	}	
  	NotSelect_SDR();                /*CSN置高 */
  	return(status);          /* 返回nRF24L01 状态*/
}

/*SPI读*/
unsigned char SPI_Read(BYTE reg)
{
  unsigned char Data;
  Select_SDR();
  SPI2_NRF_SendByte(reg);
  Data=SPI2_NRF_SendByte(0);
  NotSelect_SDR(); 	
  return (Data); 
}


u8 SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
	uchar status,i;

  	Select_SDR();              /*CSN置低*/
  	status=SPI2_NRF_SendByte(reg);
  	
  	for(i=0; i<bytes; i++) /* 数据写入缓存 */
    {
		
  		/* 发送字节*/  
		pBuf[i]=SPI2_NRF_SendByte(0);
  		//SPI_I2S_SendData(SPI2,*pBuf++); 
	}	
  	NotSelect_SDR();                /*CSN置高*/ 
  	return(status);          /*返回NRF24L01状态*/
}

void  SPI_SDR_SendByte1(unsigned int  spi_add,unsigned int  spi_data)
 {
 
  unsigned char  bitcnt,a;  
  
 
  
   SPI_CS(0);	
   for(bitcnt=0;bitcnt<16;bitcnt++)
     {
             
  	   if(((spi_add<<bitcnt)&0x8000)>0) SPI_DOUT(1);
       else  SPI_DOUT(0);
          
       SPI_CLK(0);
       SPI_CLK(1);    
     
	 }
	 
   for(bitcnt=0;bitcnt<16;bitcnt++)
     {
             
  	   if(((spi_data<<bitcnt)&0x8000)>0) SPI_DOUT(1);
          
       else SPI_DOUT(0);
         
       SPI_CLK(0);
       SPI_CLK(1);    
          
     
	 }	 
    SPI_CLK(0);
    SPI_CS(1);	
    
  
 }



unsigned int SPI_SDR_ReadByte1(unsigned int spi_add)
 {
 
  unsigned int  i=0;
  unsigned int  temp8=0;
  
  
  SPI_CS(0);	
  for(i=0;i<16;i++)
   {
             
  	   if(((spi_add<<i)&0x8000)>1)
  	      SPI_DOUT(1);
        
       else
       	  SPI_DOUT(0);	
        
       SPI_CLK(0);
       SPI_CLK(1);
     
	 }
   
   //pPio1->PIO_CODR = SPI_CLK; 
   for(i=0;i<16;i++)
   {  
      SPI_CLK(1);
      SPI_CLK(0);	
      
      temp8=temp8<<1;         
      //if( (pPio1->PIO_PDSR & SPI_IN ) == SPI_IN ) temp8=temp8+1; 
   }   
   SPI_CLK(1);
   SPI_CLK(0);	
   //P_CPLD1->spi_fs=0x01; 
   SPI_CS(1);	
   
    return(temp8);
   
    
 }


/**************************************************
Function: init_io();
Description:
  flash led one time,chip enable(ready to TX or RX Mode),
  Spi disable,Spi clock line init high
/**************************************************/

void init_io(void)
{
	SPI_CS(1);			/*片选置1*/
	MODE_CE(0);			/*CE置0*/	
	//SPI_CLK(0);			// Spi clock line init high
}
/**************************************************/
/*延时函数*/
void delay_ms(unsigned int x)
{
    unsigned int i,j;
    i=0;
    for(i=0;i<x;i++)
    {
       j=108;
       while(j--);
    }
}
/**************************************************/

/**************************************************
Function: SPI_RW();

Description:
  Writes one byte to nRF24L01, and return the byte read
  from nRF24L01 during write, according to SPI protocol
/**************************************************/
/*uchar SPI_RW(uchar byte)
{
	uchar bit_ctr;
   	for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // output 8-bit
   	{
   		MOSI = (byte & 0x80);         // output 'byte', MSB to MOSI
   		byte = (byte << 1);           // shift next bit into MSB..
   		SCK = 1;                      // Set SCK high..
   		byte |= MISO;       		  // capture current MISO bit
   		SCK = 0;            		  // ..then set SCK low again
   	}
    return(byte);           		  // return read byte
} */
/**************************************************/

/**************************************************
Function: SPI_RW_Reg();

Description:
  Writes value 'value' to register 'reg'
/**************************************************/

/**************************************************/


/**************************************************/

/**************************************************
Function: SPI_Read_Buf();

Description:
  Reads 'bytes' #of bytes from register 'reg'
  Typically used to read RX payload, Rx/Tx address
/**************************************************/
/*uchar SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
	uchar status,byte_ctr;

  	CSN = 0;                    		// Set CSN low, init SPI tranaction
  	status = SPI_RW(reg);       		// Select register to write to and read status byte

  	for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
    	pBuf[byte_ctr] = SPI_RW(0);    // Perform SPI_RW to read byte from nRF24L01

  	CSN = 1;                           // Set CSN high again

  	return(status);                    // return nRF24L01 status byte
} */
/**************************************************/



/**********************************************************************
*函数名: RX_Mode()
*功能描述:初始化NRF24L01到接收模式,设置接收地址,写有效接收数据宽度
*选择射频通道,速率及低噪声放大器增益,初始化,后CE置高,NRF24L01
*接收数据包准备就绪.
**********************************************************************/
void RX_Mode(void)
{	it_msg=0;
	init_io();	
	/*TX地址*/	
	TX_ADDRESS[0]=0x34;
	TX_ADDRESS[1]=0x43;
	TX_ADDRESS[2]=0x10;
	TX_ADDRESS[3]=0x10;
	TX_ADDRESS[4]=0x01;
	MODE_CE(0);
	 /*收发使用相同的地址*/
  	SPI_Write_Buf(WRITE_REG1 + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
	/*使能自动应答通道0*/
  	SPI_RW_Reg(WRITE_REG1 + EN_AA, 0x01);      
  	SPI_RW_Reg(WRITE_REG1 + EN_RXADDR, 0x01);
	/*选择射频通道40*/
  	SPI_RW_Reg(WRITE_REG1 + RF_CH, 40); 
	/*接收/发送有效负载数据长度相等*/       
  	SPI_RW_Reg(WRITE_REG1 + RX_PW_P0, TX_PLOAD_WIDTH);
	/*发射功率:0dBm, 数据速率:2Mbps, 低噪声放大增益:HCURR */
  	if(nrf_baud==0) SPI_RW_Reg(WRITE_REG1 + RF_SETUP, 0x0f); 
	else SPI_RW_Reg(WRITE_REG1 + RF_SETUP, 0x07);
	/*设置PWR_UP位, 使能CRC(2 bytes)校验,PRIM_RX位,RX_DR位*/
  	SPI_RW_Reg(WRITE_REG1 + CONFIG, 0x0f);
	
  	MODE_CE(1);/*CE置1,使能接收模式*/ 
    
  //  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.

}

/**********************************************************************
*函数名: TX_Mode()
*功能描述:初始化NRF24L01到发送模式,设置发送地址,设置接收自动应答功能
*选择射频通道,速率及发射功率,使能PWR_UP,PRIM_TX,CRC校验=2字节初始化,
*CE置高并维持10us,NRF24L01准备发送数据包并接收应答信号.
**********************************************************************/
void TX_Mode(void)
{
	/*模式引脚CE=0*/
	MODE_CE(0);
	/*写发送地址TX_ADDR到nRF24L01*/
  	SPI_Write_Buf(WRITE_REG1 + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);
	/*使能自动应答功能时发送/接收地址须相等*/ 
  	SPI_Write_Buf(WRITE_REG1 + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);
  	//SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes data to TX payload
	/*使能通道0自动应答*/
  	SPI_RW_Reg(WRITE_REG1 + EN_AA, 0x01); 
	/*使能通道0*/     
  	SPI_RW_Reg(WRITE_REG1 + EN_RXADDR, 0x01);
	/*500us + 86us, 10次重发*/
  	SPI_RW_Reg(WRITE_REG1 + SETUP_RETR, 0x1a); 
	/*选择射频通道40*/ 
  	SPI_RW_Reg(WRITE_REG1 + RF_CH, 40);       
  	/*设置发射功率:0dBm, 数据速率:2Mbps, 低噪声放大增益:HCURR*/
	if(nrf_baud==0) SPI_RW_Reg(WRITE_REG1 + RF_SETUP, 0x0f);
	else SPI_RW_Reg(WRITE_REG1 + RF_SETUP, 0x07);
	/* 设置PWR_UP位,使能CRC校验=2字节,PRIM_TX,MAX_RT,TX_DS寄存器位使能*/
  	SPI_RW_Reg(WRITE_REG1 + CONFIG, 0x0e);
	//SPI_RW_Reg(WRITE_REG1+ CONFIG, 0x02);//0x0E);
	MODE_CE(1);

}
  
void NRF24L01_TX(unsigned char * tx_buf)
{
	MODE_CE(0);
	
  	/*自动应答时收发地址相等*/
  	SPI_Write_Buf(WRITE_REG1 + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); 
	/*写数据到TX_PLD*/
  	SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);

  	
	MODE_CE(1);

   
}
/**********************************************************************
*函数名: NRF24L01_TXBUF()
*功能描述:发送数据缓冲内容="1234567890abcdefghij ,
*配置发送地址,I/O配置等
**********************************************************************/
void NRF24L01_TXBUF(void)
{
	
	
	uchar a,i=0;  
	TX_ADDRESS[0]=0x34;
	TX_ADDRESS[1]=0x43;
	TX_ADDRESS[2]=0x10;
	TX_ADDRESS[3]=0x10;
	TX_ADDRESS[4]=0x01;

	//TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x01};
	init_io();	
	//LED1=1;
	it_msg=0;
	SPI_RW_Reg(WRITE_REG1+STATUS,0xff);
	SPI_RW_Reg(0xe1,0);	
	SPI_RW_Reg(0xe2,0);		    
	TX_Mode();		/* 发送模式* /
	delay_ms(100);
	NRF24L01_TX(tx_buf);
	while(i==0)
	{	
		if(it_msg!=0){
			it_msg=0;	 
			a=SPI_Read(READ_REG1+STATUS);
		    /*发送达到最大重发次数*/ 
			if((a&0x10)>0){					 
				/*清除发送缓冲区*/
				SPI_RW_Reg(0xe1,0);	
				/*清除07寄存器中断标志*/				 
				SPI_RW_Reg(WRITE_REG1+STATUS,0xff);	 
				 //if(led_flash==1) GPIO_SetBits(GPIOB, GPIO_Pin_5);
				 //else Led_OFF();
				 memcpy(status_buf, "Object NO ACK!      ", 20);
				 i=1;
			}
			else if((a&0x20)>0){/*发射后收到应答*/ 
				/*清除发送缓冲区*/
				SPI_RW_Reg(0xe1,0);	
				/*清除07寄存器中断标志*/				 
				SPI_RW_Reg(WRITE_REG1+STATUS,0xff);	 
				
				 //if(led_flash==1) GPIO_SetBits(GPIOB, GPIO_Pin_5);
				 //else Led_OFF();
				 memcpy(status_buf, "Send OK!            ", 20);
				 i=1;
			}

		} 


u8 NRF24L01_RxPacket()
{u8 flag=0;
 u8 status;
 	if(it_msg!=0){
		it_msg=0;	 
		 /*读取状态寄存其来判断数据接收状况*/
		status=SPI_Read(READ_REG1+STATUS);		
		if(status & 0x40)  /*判断是否接收到数据*/				   
		{	 
		     /*从接收缓冲区读有效数据*/  
			 SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);
		
			 flag =1; /*读取数据完成标志*/
			 //if(led_flash==1){ Led_ON(); }
		 	 //else if(led_flash==0){ Led_OFF();} 
			 memcpy(status_buf, "Recive OK!            ", 20);
			/*接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清楚中断标志*/
			 SPI_RW_Reg(WRITE_REG1+STATUS, status);   
		 }
	}
	
	return flag;
}


⌨️ 快捷键说明

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