这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 综合技术 » 通讯及无线技术 » 基于STM8L052的NRF24L01无线收发

共7条 1/1 1 跳转至

基于STM8L052的NRF24L01无线收发

专家
2015-09-18 21:29:33     打赏

最近在做一个STM8L+NRF24L01的小项目,现把部分代码跟大家分享一下(其实里面大部分代码也是别人的),NRF24L01的资料,网上随便一扫荡就是大把的,这里就不上传了。

上代码:

#include <stdio.h>
#include "rf24l01.h"

const uint8_t TX_ADDRESS[TX_ADR_WIDTH]={0x68,0x86,0x66,0x88,0x28}; //发送地址
const uint8_t RX_ADDRESS[RX_ADR_WIDTH]={0x68,0x86,0x66,0x88,0x28}; //发送地址
/*******************************************************************************
* Function Name  : SPI_RF_Init
* Description    : Initializes the peripherals used by the SPI FLASH driver.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void NRF24L01_Init(void)
{
   SPI_DeInit(SPI1);
   /* Set the MOSI and SCK at high level */
   GPIO_ExternalPullUpConfig(GPIOB, GPIO_Pin_6 | GPIO_Pin_5, ENABLE);
  
   CLK_PeripheralClockConfig(CLK_Peripheral_SPI1, ENABLE);
   SPI_Init(SPI1,SPI_FirstBit_MSB, SPI_BaudRatePrescaler_4, SPI_Mode_Master,\
            SPI_CPOL_Low, SPI_CPHA_1Edge,\
            SPI_Direction_2Lines_FullDuplex, SPI_NSS_Soft, 0x07);
   
   SPI_Cmd(SPI1,ENABLE);
   
   GPIO_Init(SPI_PORT , SPI_Pin_CS, GPIO_Mode_Out_PP_High_Fast);
   SPI_RF_CS_HIGH();
	
   GPIO_Init(SPI_PORT,SPI_Pin_CE, GPIO_Mode_Out_PP_High_Fast);	/* CE引脚初始化为输出 */
   
   GPIO_Init(GPIOD,GPIO_Pin_5,GPIO_Mode_In_PU_IT );
   EXTI_SetPinSensitivity(EXTI_Pin_5, EXTI_Trigger_Falling);
   ITC_SetSoftwarePriority(EXTI5_IRQn, ITC_PriorityLevel_1);
  

}


/*********************************************/
/* 函数功能:给24L01的寄存器写值(一个字节) */
/* 入口参数:reg   要写的寄存器地址          */
/*           value 给寄存器写的值            */
/* 出口参数:status 状态值                   */
/*********************************************/
uint8_t NRF24L01_Write_Reg(uint8_t reg,uint8_t value)
{
	uint8_t status;

	SPI_RF_CS_LOW() ;	 //CSN=0;   
        status = SPI_RF_SendByte(reg);//发送寄存器地址,并读取状态值
	SPI_RF_SendByte(value);
	SPI_RF_CS_HIGH();   //CSN=1;
	return status;
}

/*************************************************/
/* 函数功能:读24L01的寄存器值 (一个字节)      */
/* 入口参数:reg  要读的寄存器地址               */
/* 出口参数:value 读出寄存器的值                */
/*************************************************/
uint8_t NRF24L01_Read_Reg(uint8_t reg)
{
    uint8_t value;

    SPI_RF_CS_LOW() ; //CSN=0;   
    SPI_RF_SendByte(reg);//发送寄存器值(位置),并读取状态值
    value = SPI_RF_SendByte(NOP);
    SPI_RF_CS_HIGH();  //CSN=1;
    return value;
}

/*********************************************/
/* 函数功能:读24L01的寄存器值(多个字节)   */
/* 入口参数:reg   寄存器地址                */
/*           *pBuf 读出寄存器值的存放数组    */
/*           len   数组字节长度              */
/* 出口参数:status 状态值                   */
/*********************************************/
uint8_t NRF24L01_Read_Buf(uint8_t reg,uint8_t *pBuf,uint8_t len)
{
    uint8_t status,u8_ctr;
    SPI_RF_CS_LOW() ;//CSN=0       
    status=SPI_RF_SendByte(reg);//发送寄存器地址,并读取状态值   	   
    for(u8_ctr=0;u8_ctr<len;u8_ctr++)
    pBuf[u8_ctr]=SPI_RF_SendByte(0XFF);//读出数据
    SPI_RF_CS_HIGH(); //CSN=1
  return status;        //返回读到的状态值
}
/**********************************************/
/* 函数功能:给24L01的寄存器写值(多个字节)  */
/* 入口参数:reg  要写的寄存器地址            */
/*           *pBuf 值的存放数组               */
/*           len   数组字节长度               */
/**********************************************/
uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len)
{
    uint8_t status,u8_ctr;
    SPI_RF_CS_LOW() ;	    
    status = SPI_RF_SendByte(reg);//发送寄存器值(位置),并读取状态值
    for(u8_ctr=0; u8_ctr<len; u8_ctr++)
        SPI_RF_SendByte(*pBuf++); //写入数据
    SPI_RF_CS_HIGH(); 
    return status;          //返回读到的状态值
}
/********************************************/
/* 函数功能:检测24L01是否存在              */
/* 返回值;  0  存在                        */
/*           1  不存在                      */
/********************************************/	
uint8_t NRF24L01_Check(void)
{
    uint8_t check_in_buf[5]={0x11,0x22,0x33,0x44,0x55};
    uint8_t check_out_buf[5]={0x00};

    NRF24L01_Write_Buf(WRITE_REG+TX_ADDR, check_in_buf, 5);

    NRF24L01_Read_Buf(READ_REG+TX_ADDR, check_out_buf, 5);

    if((check_out_buf[0] == 0x11)&&\
        (check_out_buf[1] == 0x22)&&\
        (check_out_buf[2] == 0x33)&&\
        (check_out_buf[3] == 0x44)&&\
        (check_out_buf[4] == 0x55))return 0;
    else return 1;
}
/*********************************************/
/* 函数功能:设置24L01为接收模式             */
/*********************************************/
void NRF24L01_RX_Mode(void)
{

	SPI_RF_CE_LOW() ;	//CE拉低,使能24L01配置
	//1、写RX接收地址
	NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0, (uint8_t*)RX_ADDRESS, RX_ADR_WIDTH);
	//2、开启通道0自动应答   
  	NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);  
        //3、通道0接收允许 
  	NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); 
        //4、设置RF工作通道频率 
  	NRF24L01_Write_Reg(WRITE_REG+RF_CH,40);
        //5、选择通道0的有效数据宽度
  	NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);
        //6、设置TX发射参数,0db增益,2Mbps,低噪声增益开启 
	NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f);
        //7、配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式
  	NRF24L01_Write_Reg(WRITE_REG+CONFIG, 0x0f);
        //8、清除RX FIFO寄存器 
	NRF24L01_Write_Reg(FLUSH_RX,0xff);
	SPI_RF_CE_HIGH();	//CE置高,使能接收
}
/*********************************************/
/* 函数功能:设置24L01为发送模式             */
/*********************************************/
void NRF24L01_TX_Mode(void)
{
	SPI_RF_CE_LOW() ;	//CE拉低,使能24L01配置	    
        //1、写TX节点地址 
  	NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(uint8_t*)TX_ADDRESS,TX_ADR_WIDTH);
        //2、设置TX节点地址,主要为了使能ACK	  
  	NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uint8_t*)RX_ADDRESS,RX_ADR_WIDTH); 
        //3、使能通道0的自动应答  
  	NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);      
        //4、使能通道0的接收地址  
  	NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); 
        //5、设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
  	NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);
        //6、设置RF通道为40
  	NRF24L01_Write_Reg(WRITE_REG+RF_CH,40);     
        //7、设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
  	NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f);  
         //8、配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
  	NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0e);   
	SPI_RF_CE_HIGH();	//CE置高,使能发送
}

void NRF24L01_RT_Mode(void)
{
	SPI_RF_CE_LOW() ;	//CE拉低,使能24L01配置	    
  	NRF24L01_Write_Reg(WRITE_REG+RX_PW_P0,RX_PLOAD_WIDTH);//选择通道0的有效数据宽度
	NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器    
  	NRF24L01_Write_Buf(WRITE_REG+TX_ADDR,(uchar*)TX_ADDRESS,TX_ADR_WIDTH);//写TX节点地址 
  	NRF24L01_Write_Buf(WRITE_REG+RX_ADDR_P0,(uchar*)RX_ADDRESS,RX_ADR_WIDTH); //设置TX节点地址,主要为了使能ACK	  
  	NRF24L01_Write_Reg(WRITE_REG+EN_AA,0x01);     //使能通道0的自动应答    
  	NRF24L01_Write_Reg(WRITE_REG+EN_RXADDR,0x01); //使能通道0的接收地址  
  	NRF24L01_Write_Reg(WRITE_REG+SETUP_RETR,0x1a);//设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
  	NRF24L01_Write_Reg(WRITE_REG+RF_CH,40);       //设置RF通道为40
  	NRF24L01_Write_Reg(WRITE_REG+RF_SETUP,0x0f);  //设置TX发射参数,0db增益,2Mbps,低噪声增益开启   
  	NRF24L01_Write_Reg(WRITE_REG+CONFIG,0x0f);    //配置基本工作模式的参数;PWR_UP,EN_CRC,16BIT_CRC,接收模式,开启所有中断
        SPI_RF_CE_HIGH();	//CE置高,使能发送
}
/*********************************************/
/* 函数功能:24L01接收数据                   */
/* 入口参数:rxbuf 接收数据数组              */
/* 返回值: 0   成功收到数据                 */
/*          1   没有收到数据                 */
/*********************************************/
uint8_t NRF24L01_RxPacket(uint8_t *rxbuf)
{
	uint8_t state;

	state=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值    	 
	NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志
	if(state&RX_OK)//接收到数据
	{
		NRF24L01_Read_Buf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
		NRF24L01_Write_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器 
		return 0; 
	}	   
	return 1;//没收到任何数据
}
/**********************************************/
/* 函数功能:设置24L01为发送模式              */
/* 入口参数:txbuf  发送数据数组              */
/* 返回值; 0x10    达到最大重发次数,发送失败*/
/*          0x20    成功发送完成              */
/*          0xff    发送失败                  */
/**********************************************/
uint8_t NRF24L01_TxPacket(uint8_t *txbuf)
{
	uint8_t state;
   
	SPI_RF_CE_LOW() ;	//CE拉低,使能24L01配置
        NRF24L01_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);//写数据到TX BUF  32个字节
 	SPI_RF_CE_HIGH();	//CE置高,使能发送
	while (SPI_RF_IRQ()!=0);//等待发送完成 
	state=NRF24L01_Read_Reg(STATUS);  //读取状态寄存器的值	   
	NRF24L01_Write_Reg(WRITE_REG+STATUS,state); //清除TX_DS或MAX_RT中断标志
	NRF24L01_Write_Reg(FLUSH_TX,0xff);//清除TX FIFO寄存器 
	if(state&MAX_TX)//达到最大重发次数
	{
		
		return MAX_TX; 
	}
	if(state&TX_OK)//发送完成
	{
		return TX_OK;
	}
	return 0xff;//发送失败
}					    


/*******************************************************************************
* Function Name  : SPI_FLASH_SendByte
* Description    : Sends a byte through the SPI interface and return the byte
*                  received from the SPI bus.
* Input          : byte : byte to send.
* Output         : None
* Return         : The value of the received byte.
*******************************************************************************/
uint8_t SPI_RF_SendByte(uint8_t byte)
{
  while(SPI_GetFlagStatus(SPI1,SPI_FLAG_TXE) == RESET)
  {
  }
  
  /*!< Send the byte */
  SPI_SendData(SPI1,byte);
  
  /*!< Wait to receive a byte*/
  while(SPI_GetFlagStatus(SPI1,SPI_FLAG_RXNE) == RESET)
  {
  }
  
  /*!< Return the byte read from the SPI bus */ 
  return SPI_ReceiveData(SPI1);
}

 




关键词: STM8L052     NRF24L01     无线    

专家
2015-09-18 21:30:20     打赏
2楼
#ifndef _RF24L01_H
#define _RF24L01_H

#include "stm8l15x.h"
#include "stm8l15x_spi.h"
#include "stm8l15x_gpio.h"
#include "stm8l15x_clk.h"

#define uchar unsigned char
#define uint  unsigned int

/**********  NRF24L01寄存器操作命令  ***********/
#define READ_REG        0x00  //读配置寄存器,低5位为寄存器地址
#define WRITE_REG       0x20  //写配置寄存器,低5位为寄存器地址
#define RD_RX_PLOAD     0x61  //读RX有效数据,1~32字节
#define WR_TX_PLOAD     0xA0  //写TX有效数据,1~32字节
#define FLUSH_TX        0xE1  //清除TX FIFO寄存器.发射模式下用
#define FLUSH_RX        0xE2  //清除RX FIFO寄存器.接收模式下用
#define REUSE_TX_PL     0xE3  //重新使用上一包数据,CE为高,数据包被不断发送.
#define NOP             0xFF  //空操作,可以用来读状态寄存器	 
/**********  NRF24L01寄存器地址   *************/
#define CONFIG          0x00  //配置寄存器地址                             
#define EN_AA           0x01  //使能自动应答功能 
#define EN_RXADDR       0x02  //接收地址允许
#define SETUP_AW        0x03  //设置地址宽度(所有数据通道)
#define SETUP_RETR      0x04  //建立自动重发
#define RF_CH           0x05  //RF通道
#define RF_SETUP        0x06  //RF寄存器
#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有效数据宽度(1~32字节) 
#define RX_PW_P1        0x12  // 接收数据通道1有效数据宽度(1~32字节) 
#define RX_PW_P2        0x13  // 接收数据通道2有效数据宽度(1~32字节) 
#define RX_PW_P3        0x14  // 接收数据通道3有效数据宽度(1~32字节) 
#define RX_PW_P4        0x15  // 接收数据通道4有效数据宽度(1~32字节)
#define RX_PW_P5        0x16  // 接收数据通道5有效数据宽度(1~32字节)
#define FIFO_STATUS     0x17  // FIFO状态寄存器
/*————————————————————————————————————————————————————————————————————*/

#define SPI_PORT                 GPIOB
#define SPI_Pin_CS               GPIO_Pin_4
#define SPI_Pin_CE               GPIO_Pin_3
/* Select SPI FLASH: Chip Select pin low  */
#define SPI_RF_CS_LOW()          GPIO_ResetBits(SPI_PORT, SPI_Pin_CS)
/* Deselect SPI FLASH: Chip Select pin high */
#define SPI_RF_CS_HIGH()         GPIO_SetBits(SPI_PORT, SPI_Pin_CS)


#define SPI_RF_CE_LOW()          GPIO_ResetBits(SPI_PORT, SPI_Pin_CE)
#define SPI_RF_CE_HIGH()         GPIO_SetBits(SPI_PORT, SPI_Pin_CE)

#define SPI_RF_IRQ()		 GPIO_ReadInputDataBit ( GPIOD, GPIO_Pin_5) //中断引脚

/******   STATUS寄存器bit位定义      *******/
#define MAX_TX  	0x10  //达到最大发送次数中断
#define TX_OK   	0x20  //TX发送完成中断
#define RX_OK   	0x40  //接收到数据中断
/*——————————————————————————————————————————————————*/

/*********     24L01发送接收数据宽度定义	  ***********/
#define TX_ADR_WIDTH    5   //5字节地址宽度
#define RX_ADR_WIDTH    5   //5字节地址宽度
#define TX_PLOAD_WIDTH  32  //32字节有效数据宽度
#define RX_PLOAD_WIDTH  32  //32字节有效数据宽度
/*———————————————————————————————————————————————————————*/

extern void NRF24L01_Init(void);
extern uint8_t NRF24L01_Write_Reg(uint8_t reg,uint8_t value);
extern uint8_t NRF24L01_Read_Reg(uint8_t reg);
extern uint8_t NRF24L01_Write_Buf(uint8_t reg, uint8_t *pBuf, uint8_t len);
extern uint8_t NRF24L01_Read_Buf(uint8_t reg,uint8_t *pBuf,uint8_t len);
extern uint8_t NRF24L01_Check(void);
extern void  NRF24L01_RX_Mode(void);
extern void  NRF24L01_TX_Mode(void);
extern void  NRF24L01_RT_Mode(void);
extern uint8_t NRF24L01_RxPacket(uint8_t *rxbuf);
extern uint8_t NRF24L01_TxPacket(uint8_t *txbuf);
extern uint8_t SPI_RF_SendByte(uint8_t byte);
#endif

 


专家
2015-09-18 21:32:11     打赏
3楼
有需要STM8L052 及NRF24L01资料的网友,请回帖告知需求。

专家
2015-09-20 13:25:04     打赏
4楼
XF,你太霸气了。谢谢分享。来研究下

院士
2015-09-20 19:20:47     打赏
5楼

这个的确是干货啊~~

让管理员给楼主加分去~~


菜鸟
2019-01-17 19:10:31     打赏
6楼

nrf905 lz有相关资料吗?


菜鸟
2019-01-20 15:51:07     打赏
7楼

啸风 你好,我使用STM8L调试NRF24L01,每次发生都重发最大次数,接收端也接收不成功,用的是软件SPI,你认为是什么原因引起的? 我增大了重发间隔,也不行


共7条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]