加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
nrf24l01.c 15.18 KB
一键复制 编辑 原始数据 按行查看 历史
莫诗书 提交于 2020-05-06 22:44 . update 加入全部的api函数
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
#include "nrf24l01.h"
#include "delay.h"
#include "spi.h"
#include "uart.h"
const char code *Error = "RF24L01 is not find !...\r\n";
/**
* @brief :NRF24L01读寄存器
* @param :
@Addr:寄存器地址
* @note :地址在设备中有效
* @retval:读取的数据
*/
uchar NRF24L01_Read_Reg( uchar RegAddr )
{
uchar 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( uchar RegAddr, uchar *pBuf, uchar len )
{
uchar 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( uchar RegAddr, uchar 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( uchar RegAddr, uchar *pBuf, uchar len )
{
uchar 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状态
*/
uchar NRF24L01_Read_Status_Register( void )
{
uchar 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:清除后状态寄存器的值
*/
uchar NRF24L01_Clear_IRQ_Flag( uchar IRQ_Source )
{
uchar 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:中断状态
*/
uchar RF24L01_Read_IRQ_Status( void )
{
return ( NRF24L01_Read_Status_Register( ) & (( 1 << RX_DR ) | ( 1 << TX_DS ) | ( 1 << MAX_RT ))); //返回中断状态
}
/**
* @brief :读FIFO中数据宽度
* @param :无
* @note :无
* @retval:数据宽度
*/
uchar NRF24L01_Read_Top_Fifo_Width( void )
{
uchar 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:数据存放地址首地址
*/
uchar NRF24L01_Read_Rx_Payload( uchar *pRxBuf )
{
uchar 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( uchar *pTxBuf, uchar len )
{
uchar btmp;
uchar 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( uchar *pTxBuf, uchar 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( uchar *pData, uchar len )
{
uchar 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( uchar *pAddr, uchar 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( uchar PipeNum, uchar *pAddr, uchar 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 )
{
uchar 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 )
{
uchar 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( uchar FreqPoint )
{
NRF24L01_Write_Reg( RF_CH, FreqPoint & 0x7F );
}
/**
* @brief :NRF24L01检测
* @param :无
* @note :无
* @retval:无
*/
void NRF24L01_check( void )
{
uchar i;
uchar buf[5]= { 0XA5, 0XA5, 0XA5, 0XA5, 0XA5 };
uchar 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((uchar *)Error, 26); //检测不到设备,输出警告信息
}
delay_ms( 500 ); //500MS检测一次
}
}
/**
* @brief :设置模式
* @param :
* @Mode:模式发送模式或接收模式
* @note :无
* @retval:无
*/
void RF24L01_Set_Mode( nRf24l01ModeType Mode )
{
uchar 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:其他原因
*/
uchar NRF24L01_TxPacket( uchar *txbuf, uchar Length )
{
uchar l_Status = 0;
ushort 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( ))
{
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:没有接收到数据
*/
uchar NRF24L01_RxPacket( uchar *rxbuf )
{
uchar 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( ))
{
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 )
{
uchar 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地址
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化