RF24L01.h RF24L01.c 代码

-------------------------------------------------------.h-----------------

#ifndef __DRV_RF24L01_H__
#define __DRV_RF24L01_H__


#include "drv_spi.h"
#include "drv_uart.h"


/** 配置和选项定义 */
#define DYNAMIC_PACKET      1         //1:动态数据包, 0:固定
#define FIXED_PACKET_LEN    32        //包长度
#define REPEAT_CNT          15        //重复次数
#define INIT_ADDR           0x34,0x43,0x10,0x10,0x01


/** RF24L01硬件接口定义 */

sbit    RF24L01_CE                        =P1^2;
sbit    RF24L01_IRQ                        =P1^4;

#define RF24L01_CS                        SPI_NSS

#define RF24L01_CE_PIN_BIT                2
#define RF24L01_IRQ_PIN_BIT                4

#define RF24L01_CE_PxM0                    P1M0
#define RF24L01_CE_PxM1                    P1M1
#define RF24L01_IRQ_PxM0                P1M0
#define RF24L01_IRQ_PxM1                P1M1

/** 口线操作函数定义 */
#define RF24L01_SET_CE_HIGH( )            RF24L01_CE = 1
#define RF24L01_SET_CE_LOW( )            RF24L01_CE = 0

#define RF24L01_SET_CS_HIGH( )            spi_set_nss_high( )
#define RF24L01_SET_CS_LOW( )            spi_set_nss_low( )

#define RF24L01_GET_IRQ_STATUS( )        (( 1 != RF24L01_IRQ ) ? 0 : 1 )


typedef enum ModeType
{
    MODE_TX = 0,
    MODE_RX
}nRf24l01ModeType;

typedef enum SpeedType
{
    SPEED_250K = 0,
    SPEED_1M,
    SPEED_2M
}nRf24l01SpeedType;

typedef enum PowerType
{
    POWER_F18DBM = 0,
    POWER_F12DBM,
    POWER_F6DBM,
    POWER_0DBM
}nRf24l01PowerType;


/** NRF24L01定义 */
//
//寄存器操作命令
#define NRF_READ_REG    0x00    //读配置寄存器,低5位为寄存器地址
#define NRF_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 R_RX_PL_WID     0x60
#define NOP             0xFF    //空操作,可以用来读状态寄存器
#define W_ACK_PLOAD        0xA8
#define WR_TX_PLOAD_NACK 0xB0
//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    //设置地址宽度(所有数据通道) bit0~1: 00,3字节 01,4字节, 02,5字节
#define SETUP_RETR      0x04    //建立自动重发;bit0~3:自动重发计数器;bit4~7:自动重发延时 250*x+86us
#define RF_CH           0x05    //RF通道,bit0~6工作通道频率
#define RF_SETUP        0x06    //RF寄存器,bit3:传输速率( 0:1M 1:2M);bit1~2:发射功率;bit0:噪声放大器增益
#define STATUS          0x07    //状态寄存器;bit0:TX FIFO满标志;bit1~3:接收数据通道号(最大: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 NRF_FIFO_STATUS 0x17    //FIFO状态寄存器;bit0:RX FIFO寄存器空标志;bit1:RX FIFO满标志;bit2~3保留
                                //bit4:TX FIFO 空标志;bit5:TX FIFO满标志;bit6:1,循环发送上一数据包.0,不循环                                
#define DYNPD            0x1C
#define FEATRUE            0x1D
//

//位定义
#define MASK_RX_DR       6 
#define MASK_TX_DS       5 
#define MASK_MAX_RT      4 
#define EN_CRC           3 
#define CRCO             2 
#define PWR_UP           1 
#define PRIM_RX          0 

#define ENAA_P5          5 
#define ENAA_P4          4 
#define ENAA_P3          3 
#define ENAA_P2          2 
#define ENAA_P1          1 
#define ENAA_P0          0 

#define ERX_P5           5 
#define ERX_P4           4 
#define ERX_P3           3 
#define ERX_P2          2 
#define ERX_P1           1 
#define ERX_P0           0 

#define AW_RERSERVED     0x0 
#define AW_3BYTES        0x1
#define AW_4BYTES        0x2
#define AW_5BYTES        0x3

#define ARD_250US        (0x00<<4)
#define ARD_500US        (0x01<<4)
#define ARD_750US        (0x02<<4)
#define ARD_1000US       (0x03<<4)
#define ARD_2000US       (0x07<<4)
#define ARD_4000US       (0x0F<<4)
#define ARC_DISABLE       0x00
#define ARC_15            0x0F

#define CONT_WAVE         7 
#define RF_DR_LOW         5 
#define PLL_LOCK          4 
#define RF_DR_HIGH        3 
//bit2-bit1:
#define PWR_18DB          (0x00<<1)
#define PWR_12DB          (0x01<<1)
#define PWR_6DB           (0x02<<1)
#define PWR_0DB           (0x03<<1)

#define RX_DR             6 
#define TX_DS             5 
#define MAX_RT            4 
//for bit3-bit1, 
#define TX_FULL_0         0 

#define RPD               0 

#define TX_REUSE          6 
#define TX_FULL_1         5 
#define TX_EMPTY          4 
//bit3-bit2, reserved, only '00'
#define RX_FULL           1 
#define RX_EMPTY          0 

#define DPL_P5            5 
#define DPL_P4            4 
#define DPL_P3            3 
#define DPL_P2            2 
#define DPL_P1            1 
#define DPL_P0            0 

#define EN_DPL            2 
#define EN_ACK_PAY        1 
#define EN_DYN_ACK        0 
#define IRQ_ALL  ( (1<<RX_DR) | (1<<TX_DS) | (1<<MAX_RT) )

uint8_t NRF24L01_Read_Reg( uint8_t RegAddr );
void NRF24L01_Read_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len );
void NRF24L01_Write_Reg( uint8_t RegAddr, uint8_t Value );
void NRF24L01_Write_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len );
void NRF24L01_Flush_Tx_Fifo ( void );
void NRF24L01_Flush_Rx_Fifo( void );
void NRF24L01_Reuse_Tx_Payload( void );
void NRF24L01_Nop( void );
uint8_t NRF24L01_Read_Status_Register( void );
uint8_t NRF24L01_Clear_IRQ_Flag( uint8_t IRQ_Source );
uint8_t RF24L01_Read_IRQ_Status( void );
uint8_t NRF24L01_Read_Top_Fifo_Width( void );
uint8_t NRF24L01_Read_Rx_Payload( uint8_t *pRxBuf );
void NRF24L01_Write_Tx_Payload_Ack( uint8_t *pTxBuf, uint8_t len );
void NRF24L01_Write_Tx_Payload_NoAck( uint8_t *pTxBuf, uint8_t len );
void NRF24L01_Write_Tx_Payload_InAck( uint8_t *pData, uint8_t len );
void NRF24L01_Set_TxAddr( uint8_t *pAddr, uint8_t len );
void NRF24L01_Set_RxAddr( uint8_t PipeNum, uint8_t *pAddr, uint8_t Len );
void NRF24L01_Set_Speed( nRf24l01SpeedType Speed );
void NRF24L01_Set_Power( nRf24l01PowerType Power );
void RF24LL01_Write_Hopping_Point( uint8_t FreqPoint );
void RF24L01_Set_Mode( nRf24l01ModeType Mode );
void  NRF24L01_check( void );
uint8_t NRF24L01_TxPacket( uint8_t *txbuf, uint8_t Length );
uint8_t NRF24L01_RxPacket( uint8_t *rxbuf );
void NRF24L01_Gpio_Init( void );
void RF24L01_Init( void );    


#endif

--------------------------------------------------------.c------------------

#include "drv_RF24L01.h"
#include "drv_delay.h"


const char *g_ErrorString = "RF24L01 is not find !...";


/**
  * @brief :NRF24L01读寄存器
  * @param :
           @Addr:寄存器地址
  * @note  :地址在设备中有效
  * @retval:读取的数据
  */
uint8_t NRF24L01_Read_Reg( uint8_t RegAddr )
{
    uint8_t btmp;
    
    RF24L01_SET_CS_LOW( );            //片选
    
    drv_spi_read_write_byte( NRF_READ_REG | RegAddr );    //读命令 地址
    btmp = drv_spi_read_write_byte( 0xFF );                //读数据
    
    RF24L01_SET_CS_HIGH( );            //取消片选
    
    return btmp;
}

/**
  * @brief :NRF24L01读指定长度的数据
  * @param :
  *            @reg:地址
  *            @pBuf:数据存放地址
  *            @len:数据长度
  * @note  :数据长度不超过255,地址在设备中有效
  * @retval:读取状态
  */
void NRF24L01_Read_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len )
{
    uint8_t btmp;
    
    RF24L01_SET_CS_LOW( );            //片选
    
    drv_spi_read_write_byte( NRF_READ_REG | RegAddr );    //读命令 地址
    for( btmp = 0; btmp < len; btmp ++ )
    {
        *( pBuf + btmp ) = drv_spi_read_write_byte( 0xFF );    //读数据
    }
    RF24L01_SET_CS_HIGH( );        //取消片选
}

/**
  * @brief :NRF24L01写寄存器
  * @param :无
  * @note  :地址在设备中有效
  * @retval:读写状态
  */
void NRF24L01_Write_Reg( uint8_t RegAddr, uint8_t Value )
{
    RF24L01_SET_CS_LOW( );        //片选
    
    drv_spi_read_write_byte( NRF_WRITE_REG | RegAddr );    //写命令 地址
    drv_spi_read_write_byte( Value );            //写数据
    
    RF24L01_SET_CS_HIGH( );        //取消片选
}

/**
  * @brief :NRF24L01写指定长度的数据
  * @param :
  *            @reg:地址
  *            @pBuf:写入的数据地址
  *            @len:数据长度
  * @note  :数据长度不超过255,地址在设备中有效
  * @retval:写状态
  */
void NRF24L01_Write_Buf( uint8_t RegAddr, uint8_t *pBuf, uint8_t len )
{
    uint8_t i;
    
    RF24L01_SET_CS_LOW( );        //片选
    
    drv_spi_read_write_byte( NRF_WRITE_REG | RegAddr );    //写命令 地址
    for( i = 0; i < len; i ++ )
    {
        drv_spi_read_write_byte( *( pBuf + i ) );        //写数据
    }
    
    RF24L01_SET_CS_HIGH( );        //取消片选
}

/**
  * @brief :清空TX缓冲区
  * @param :无
  * @note  :无
  * @retval:无
  */
void NRF24L01_Flush_Tx_Fifo ( void )
{
    RF24L01_SET_CS_LOW( );        //片选
    
    drv_spi_read_write_byte( FLUSH_TX );    //清TX FIFO命令
    
    RF24L01_SET_CS_HIGH( );        //取消片选
}

/**
  * @brief :清空RX缓冲区
  * @param :无
  * @note  :无
  * @retval:无
  */
void NRF24L01_Flush_Rx_Fifo( void )
{
    RF24L01_SET_CS_LOW( );        //片选
    
    drv_spi_read_write_byte( FLUSH_RX );    //清RX FIFO命令
    
    RF24L01_SET_CS_HIGH( );        //取消片选
}

/**
  * @brief :重新使用上一包数据
  * @param :无
  * @note  :无
  * @retval:无
  */
void NRF24L01_Reuse_Tx_Payload( void )
{
    RF24L01_SET_CS_LOW( );        //片选
    
    drv_spi_read_write_byte( REUSE_TX_PL );        //重新使用上一包命令
    
    RF24L01_SET_CS_HIGH( );        //取消片选
}

/**
  * @brief :NRF24L01空操作
  * @param :无
  * @note  :无
  * @retval:无
  */
void NRF24L01_Nop( void )
{
    RF24L01_SET_CS_LOW( );        //片选
    
    drv_spi_read_write_byte( NOP );        //空操作命令
    
    RF24L01_SET_CS_HIGH( );        //取消片选
}

/**
  * @brief :NRF24L01读状态寄存器
  * @param :无
  * @note  :无
  * @retval:RF24L01状态
  */
uint8_t NRF24L01_Read_Status_Register( void )
{
    uint8_t Status;
    
    RF24L01_SET_CS_LOW( );        //片选
    
    Status = drv_spi_read_write_byte( NRF_READ_REG + STATUS );    //读状态寄存器
    
    RF24L01_SET_CS_HIGH( );        //取消片选
    
    return Status;
}

/**
  * @brief :NRF24L01清中断
  * @param :
           @IRQ_Source:中断源
  * @note  :无
  * @retval:清除后状态寄存器的值
  */
uint8_t NRF24L01_Clear_IRQ_Flag( uint8_t IRQ_Source )
{
    uint8_t btmp = 0;

    IRQ_Source &= ( 1 << RX_DR ) | ( 1 << TX_DS ) | ( 1 << MAX_RT );    //中断标志处理
    btmp = NRF24L01_Read_Status_Register( );            //读状态寄存器
            
    RF24L01_SET_CS_LOW( );            //片选
    drv_spi_read_write_byte( NRF_WRITE_REG + STATUS );    //写状态寄存器命令
    drv_spi_read_write_byte( IRQ_Source | btmp );        //清相应中断标志
    RF24L01_SET_CS_HIGH( );            //取消片选
    
    return ( NRF24L01_Read_Status_Register( ));            //返回状态寄存器状态
}

/**
  * @brief :读RF24L01中断状态
  * @param :无
  * @note  :无
  * @retval:中断状态
  */
uint8_t RF24L01_Read_IRQ_Status( void )
{
    return ( NRF24L01_Read_Status_Register( ) & (( 1 << RX_DR ) | ( 1 << TX_DS ) | ( 1 << MAX_RT )));    //返回中断状态
}
 
 /**
  * @brief :读FIFO中数据宽度
  * @param :无
  * @note  :无
  * @retval:数据宽度
  */
uint8_t NRF24L01_Read_Top_Fifo_Width( void )
{
    uint8_t btmp;
    
    RF24L01_SET_CS_LOW( );        //片选
    
    drv_spi_read_write_byte( R_RX_PL_WID );    //读FIFO中数据宽度命令
    btmp = drv_spi_read_write_byte( 0xFF );    //读数据
    
    RF24L01_SET_CS_HIGH( );        //取消片选
    
    return btmp;
}

 /**
  * @brief :读接收到的数据
  * @param :无
  * @note  :无
  * @retval:
           @pRxBuf:数据存放地址首地址
  */
uint8_t NRF24L01_Read_Rx_Payload( uint8_t *pRxBuf )
{
    uint8_t Width, PipeNum;
    
    PipeNum = ( NRF24L01_Read_Reg( STATUS ) >> 1 ) & 0x07;    //读接收状态
    Width = NRF24L01_Read_Top_Fifo_Width( );        //读接收数据个数

    RF24L01_SET_CS_LOW( );        //片选
    drv_spi_read_write_byte( RD_RX_PLOAD );            //读有效数据命令
    
    for( PipeNum = 0; PipeNum < Width; PipeNum ++ )
    {
        *( pRxBuf + PipeNum ) = drv_spi_read_write_byte( 0xFF );        //读数据
    }
    RF24L01_SET_CS_HIGH( );        //取消片选
    NRF24L01_Flush_Rx_Fifo( );    //清空RX FIFO
    
    return Width;
}

 /**
  * @brief :发送数据(带应答)
  * @param :
  *            @pTxBuf:发送数据地址
  *            @len:长度
  * @note  :一次不超过32个字节
  * @retval:无
  */
void NRF24L01_Write_Tx_Payload_Ack( uint8_t *pTxBuf, uint8_t len )
{
    uint8_t btmp;
    uint8_t length = ( len > 32 ) ? 32 : len;        //数据长达大约32 则只发送32个

    NRF24L01_Flush_Tx_Fifo( );        //清TX FIFO
    
    RF24L01_SET_CS_LOW( );            //片选
    drv_spi_read_write_byte( WR_TX_PLOAD );    //发送命令
    
    for( btmp = 0; btmp < length; btmp ++ )
    {
        drv_spi_read_write_byte( *( pTxBuf + btmp ) );    //发送数据
    }
    RF24L01_SET_CS_HIGH( );            //取消片选
}

 /**
  * @brief :发送数据(不带应答)
  * @param :
  *            @pTxBuf:发送数据地址
  *            @len:长度
  * @note  :一次不超过32个字节
  * @retval:无
  */
void NRF24L01_Write_Tx_Payload_NoAck( uint8_t *pTxBuf, uint8_t len )
{
    if( len > 32 || len == 0 )
    {
        return ;        //数据长度大于32 或者等于0 不执行
    }
    
    RF24L01_SET_CS_LOW( );    //片选
    drv_spi_read_write_byte( WR_TX_PLOAD_NACK );    //发送命令
    while( len-- )
    {
        drv_spi_read_write_byte( *pTxBuf );            //发送数据
        pTxBuf++;
    }
    RF24L01_SET_CS_HIGH( );        //取消片选
}

 /**
  * @brief :在接收模式下向TX FIFO写数据(带ACK)
  * @param :
  *            @pData:数据地址
  *            @len:长度
  * @note  :一次不超过32个字节
  * @retval:无
  */
void NRF24L01_Write_Tx_Payload_InAck( uint8_t *pData, uint8_t len )
{
    uint8_t btmp;
    
    len = ( len > 32 ) ? 32 : len;        //数据长度大于32个则只写32个字节

    RF24L01_SET_CS_LOW( );            //片选
    drv_spi_read_write_byte( W_ACK_PLOAD );        //命令
    for( btmp = 0; btmp < len; btmp ++ )
    {
        drv_spi_read_write_byte( *( pData + btmp ) );    //写数据
    }
    RF24L01_SET_CS_HIGH( );            //取消片选
}

 /**
  * @brief :设置发送地址
  * @param :
  *            @pAddr:地址存放地址
  *            @len:长度
  * @note  :无
  * @retval:无
  */
void NRF24L01_Set_TxAddr( uint8_t *pAddr, uint8_t len )
{
    len = ( len > 5 ) ? 5 : len;                    //地址不能大于5个字节
    NRF24L01_Write_Buf( TX_ADDR, pAddr, len );    //写地址
}

 /**
  * @brief :设置接收通道地址
  * @param :
  *            @PipeNum:通道
  *            @pAddr:地址存肥着地址
  *            @Len:长度
  * @note  :通道不大于5 地址长度不大于5个字节
  * @retval:无
  */
void NRF24L01_Set_RxAddr( uint8_t PipeNum, uint8_t *pAddr, uint8_t Len )
{
    Len = ( Len > 5 ) ? 5 : Len;
    PipeNum = ( PipeNum > 5 ) ? 5 : PipeNum;        //通道不大于5 地址长度不大于5个字节

    NRF24L01_Write_Buf( RX_ADDR_P0 + PipeNum, pAddr, Len );    //写入地址
}

 /**
  * @brief :设置通信速度
  * @param :
  *            @Speed:速度
  * @note  :无
  * @retval:无
  */
void NRF24L01_Set_Speed( nRf24l01SpeedType Speed )
{
    uint8_t btmp = 0;
    
    btmp = NRF24L01_Read_Reg( RF_SETUP );
    btmp &= ~( ( 1<<5 ) | ( 1<<3 ) );
    
    if( Speed == SPEED_250K )        //250K
    {
        btmp |= ( 1<<5 );
    }
    else if( Speed == SPEED_1M )   //1M
    {
           btmp &= ~( ( 1<<5 ) | ( 1<<3 ) );
    }
    else if( Speed == SPEED_2M )   //2M
    {
        btmp |= ( 1<<3 );
    }

    NRF24L01_Write_Reg( RF_SETUP, btmp );
}

 /**
  * @brief :设置功率
  * @param :
  *            @Speed:速度
  * @note  :无
  * @retval:无
  */
void NRF24L01_Set_Power( nRf24l01PowerType Power )
{
    uint8_t btmp;
    
    btmp = NRF24L01_Read_Reg( RF_SETUP ) & ~0x07;
    switch( Power )
    {
        case POWER_F18DBM:
            btmp |= PWR_18DB;
            break;
        case POWER_F12DBM:
            btmp |= PWR_12DB;
            break;
        case POWER_F6DBM:
            btmp |= PWR_6DB;
            break;
        case POWER_0DBM:
            btmp |= PWR_0DB;
            break;
        default:
            break;
    }
    NRF24L01_Write_Reg( RF_SETUP, btmp );
}

 /**
  * @brief :设置频率
  * @param :
  *            @FreqPoint:频率设置参数
  * @note  :值不大于127
  * @retval:无
  */
void RF24LL01_Write_Hopping_Point( uint8_t FreqPoint )
{
    NRF24L01_Write_Reg(  RF_CH, FreqPoint & 0x7F );
}

/**
  * @brief :NRF24L01检测
  * @param :无
  * @note  :无
  * @retval:无
  */ 
void  NRF24L01_check( void )
{
    uint8_t i;
    uint8_t buf[5]={ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5 };
    uint8_t read_buf[ 5 ] = { 0 };
     
    while( 1 )
    {
        NRF24L01_Write_Buf( TX_ADDR, buf, 5 );            //写入5个字节的地址
        NRF24L01_Read_Buf( TX_ADDR, read_buf,5 );        //读出写入的地址  
        for( i = 0; i < 5; i++ )
        {
            if( buf[ i ] != read_buf[ i ] )
            {
                break;            //读出的值和写入的置不同
            }    
        } 
        
        if( 5 == i )
        {
            break;                //读出的字符串与写入的字符串相同,判断为设备存在
        }
        else
        {
            drv_uart_tx_bytes( (uint8_t *)g_ErrorString, 26 );    //检测不到设备,输出警告信息
        }
        drv_delay_ms( 500 );    //500MS检测一次
    }
}

 /**
  * @brief :设置模式
  * @param :
  *            @Mode:模式发送模式或接收模式
  * @note  :无
  * @retval:无
  */
void RF24L01_Set_Mode( nRf24l01ModeType Mode )
{
    uint8_t controlreg = 0;
    controlreg = NRF24L01_Read_Reg( CONFIG );
    
    if( Mode == MODE_TX )       
    {
        controlreg &= ~( 1<< PRIM_RX );
    }
    else 
    {
        if( Mode == MODE_RX )  
        { 
            controlreg |= ( 1<< PRIM_RX ); 
        }
    }

    NRF24L01_Write_Reg( CONFIG, controlreg );
}

/**
  * @brief :NRF24L01发送一次数据
  * @param :
  *            @txbuf:待发送数据首地址
  *            @Length:发送数据长度
  * @note  :无
  * @retval:
  *            MAX_TX:达到最大重发次数
  *            TX_OK:发送完成
  *            0xFF:其他原因
  */ 
uint8_t NRF24L01_TxPacket( uint8_t *txbuf, uint8_t Length )
{
    uint8_t l_Status = 0;
    uint16_t l_MsTimes = 0;
    
    RF24L01_SET_CS_LOW( );        //片选
    drv_spi_read_write_byte( FLUSH_TX );
    RF24L01_SET_CS_HIGH( );
    
    RF24L01_SET_CE_LOW( );        
    NRF24L01_Write_Buf( WR_TX_PLOAD, txbuf, Length );    //写数据到TX BUF 32字节  TX_PLOAD_WIDTH
    RF24L01_SET_CE_HIGH( );            //启动发送
    while( 0 != RF24L01_GET_IRQ_STATUS( ))
    {
        drv_delay_ms( 1 );
        if( 500 == l_MsTimes++ )                        //500ms还没有发送成功,重新初始化设备
        {
            NRF24L01_Gpio_Init( );
            RF24L01_Init( );
            RF24L01_Set_Mode( MODE_TX );
            break;
        }
    }
    l_Status = NRF24L01_Read_Reg(STATUS);                        //读状态寄存器
    NRF24L01_Write_Reg( STATUS, l_Status );                        //清除TX_DS或MAX_RT中断标志
    
    if( l_Status & MAX_TX )    //达到最大重发次数
    {
        NRF24L01_Write_Reg( FLUSH_TX,0xff );    //清除TX FIFO寄存器
        return MAX_TX; 
    }
    if( l_Status & TX_OK )    //发送完成
    {
        return TX_OK;
    }
    
    return 0xFF;    //其他原因发送失败
}

/**
  * @brief :NRF24L01接收数据
  * @param :
  *            @rxbuf:接收数据存放地址
  * @note  :无
  * @retval:
  *            0:接收完成
  *            1:没有接收到数据
  */ 
uint8_t NRF24L01_RxPacket( uint8_t *rxbuf )
{
    uint8_t l_Status = 0, l_RxLength = 0, l_100MsTimes = 0;
    
    RF24L01_SET_CS_LOW( );        //片选
    drv_spi_read_write_byte( FLUSH_RX );
    RF24L01_SET_CS_HIGH( );
    
    while( 0 != RF24L01_GET_IRQ_STATUS( ))
    {
        drv_delay_ms( 100 );
        
        if( 30 == l_100MsTimes++ )        //3s没接收过数据,重新初始化模块
        {
            NRF24L01_Gpio_Init( );
            RF24L01_Init( );
            RF24L01_Set_Mode( MODE_RX );
            break;
        }
    }
    
    l_Status = NRF24L01_Read_Reg( STATUS );        //读状态寄存器
    NRF24L01_Write_Reg( STATUS,l_Status );        //清中断标志
    if( l_Status & RX_OK)    //接收到数据
    {
        l_RxLength = NRF24L01_Read_Reg( R_RX_PL_WID );        //读取接收到的数据个数
        NRF24L01_Read_Buf( RD_RX_PLOAD,rxbuf,l_RxLength );    //接收到数据 
        NRF24L01_Write_Reg( FLUSH_RX,0xff );                //清除RX FIFO
        return l_RxLength; 
    }    
    
    return 0;                //没有收到数据    
}

/**
  * @brief :NRF24L01初始化
  * @param :无
  * @note  :无
  * @retval:无
  */ 
void NRF24L01_Gpio_Init( void )
{    
    //引脚配置 部分51单片机不需要 
    //CE 配置为输出 IRQ配置为输入
    RF24L01_CE_PxM0 |= IO_OUT_PUT_PP_M0 << RF24L01_CE_PIN_BIT;
    RF24L01_CE_PxM1 |= IO_OUT_PUT_PP_M1 << RF24L01_CE_PIN_BIT;
    RF24L01_CE = 1;
    
    RF24L01_IRQ_PxM0 |= IO_IN_PUT_ONLY_M0 << RF24L01_IRQ_PIN_BIT;
    RF24L01_IRQ_PxM1 |= IO_IN_PUT_ONLY_M1 << RF24L01_IRQ_PIN_BIT;
    
    RF24L01_CE = 0;                //使能设备
    RF24L01_IRQ = 1;            //清中断
    RF24L01_SET_CS_HIGH( );        //取消SPI片选
}

 /**
  * @brief :RF24L01模块初始化
  * @param :无
  * @note  :无
  * @retval:无
  */
void RF24L01_Init( void )
{
    uint8_t addr[5] = {INIT_ADDR};

    RF24L01_SET_CE_HIGH( );
    NRF24L01_Clear_IRQ_Flag( IRQ_ALL );
#if DYNAMIC_PACKET == 1

    NRF24L01_Write_Reg( DYNPD, ( 1 << 0 ) );     //使能通道1动态数据长度
    NRF24L01_Write_Reg( FEATRUE, 0x07 );
    NRF24L01_Read_Reg( DYNPD );
    NRF24L01_Read_Reg( FEATRUE );
    
#elif DYNAMIC_PACKET == 0
    
    L01_WriteSingleReg( L01REG_RX_PW_P0, FIXED_PACKET_LEN );    //固定数据长度
    
#endif    //DYNAMIC_PACKET

    NRF24L01_Write_Reg( CONFIG, /*( 1<<MASK_RX_DR ) |*/        //接收中断
                                      ( 1 << EN_CRC ) |     //使能CRC 1个字节
                                      ( 1 << PWR_UP ) );    //开启设备
    NRF24L01_Write_Reg( EN_AA, ( 1 << ENAA_P0 ) );           //通道0自动应答
    NRF24L01_Write_Reg( EN_RXADDR, ( 1 << ERX_P0 ) );        //通道0接收
    NRF24L01_Write_Reg( SETUP_AW, AW_5BYTES );                 //地址宽度 5个字节
    NRF24L01_Write_Reg( SETUP_RETR, ARD_4000US |
                        ( REPEAT_CNT & 0x0F ) );             //重复等待时间 ---250us
    NRF24L01_Write_Reg( RF_CH, 60 );                         //初始化通道-----
    NRF24L01_Write_Reg( RF_SETUP, 0x26 );

    NRF24L01_Set_TxAddr( &addr[0], 5 );                      //设置TX地址----
    NRF24L01_Set_RxAddr( 0, &addr[0], 5 );                   //设置RX地址-----
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值