nRF24L01+基于51单片机的驱动(库)实战代码分享
关于代码来源
之前我发过几篇关于nRF24L01+的博文,很多网友看后希望能提供完整的驱动库,本人将以前实际应用于实际项目中的一个nRF24L01+的驱动代码完整的分享给大家,希望能对广大nRF24L01+爱好者提供一些帮助。这些代码是参照芯片官方文档针对项目应用改良后的,在实际项目中实践是正常的,如果您在使用中有异议,请参看官方文档。本人提供的代码只供参考,不对代码运行结果承担任何责任。
这里提供的是基于STC15系列的51单片机nRF24L01+驱动库,对于通信组网逻辑,还是要有很多考虑的,否则也可能达不到您希望的结果,尤其是多机或高速频繁交互的时候。
定义数据类型的头文件Type.h
#ifndef _Type_H_
#define _Type_H_
typedef unsigned char U8;
typedef unsigned int U16;
typedef unsigned long U32;
typedef signed char S8;
typedef signed int S16;
typedef signed long S32;
#endif
nRF24L01+驱动源代码文件nRF24L01P.c
#include "nRF24L01P.h"
U8 SelfAddr[TX_ADR_WIDTH] = {0x01, 0x01, 0x01, 0x01, 0x01};
U8 SPI_RW(U8 byte){
U8 i;
for(i=0; i<8; i++)
{
if(byte & 0x80)
MOSI = 1;
else
MOSI = 0;
byte = (byte << 1);
SCK = 1;
byte |= MISO;
SCK = 0;
}
return byte;
}
void nRF24L01P_Write_Reg(U8 reg, U8 value){
CSN = 0;
SPI_RW(reg);
SPI_RW(value);
CSN = 1;
}
void nRF24L01P_Write_Buf(U8 reg, const U8 *pBuf, U8 bytes){
U8 i;
CSN = 0;
SPI_RW(reg);
for(i=0; i<bytes; i++)
SPI_RW(*pBuf++);
CSN = 1;
}
U8 nRF24L01P_Read_Reg(U8 reg){
U8 value;
CSN = 0;
SPI_RW(reg);
value = SPI_RW(0);
CSN = 1;
return(value);
}
void nRF24L01P_Read_Buf(U8 reg, U8 *pBuf, U8 bytes){
U8 i;
CSN = 0;
SPI_RW(reg);
for(i=0; i<bytes; i++)
pBuf[i] = SPI_RW(0);
CSN = 1;
}
void RF24_SetRfCh(U8 ch){
CE = 0;
nRF24L01P_Write_Reg(WR_RF_CH, ch);
CE = 1;
}
void RF24_Init(){
SCK = 0;
CSN = 1;
CE = 0;
IRQ = 1;
CE = 0;
nRF24L01P_Write_Reg(WR_SETUP_AW, 0x03);
nRF24L01P_Write_Reg(WR_RF_SETUP, RFSETUP);
nRF24L01P_Write_Reg(WR_EN_AA, 0x01);
nRF24L01P_Write_Reg(WR_EN_RXADDR, 0x01);
nRF24L01P_Write_Reg(WR_RX_PW_P0, TX_PLOAD_WIDTH);
nRF24L01P_Write_Reg(WR_SETUP_RETR, RETE_VAL);
CE = 1;
}
void RF24_RX_Mode()
{
CE = 0;
nRF24L01P_Write_Buf(WR_RX_ADDR_P0, SelfAddr, TX_ADR_WIDTH);
nRF24L01P_Write_Reg(WR_CONFIG, 0x0F);
nRF24L01P_Write_Reg(WR_STATUS, 0xFF);
CE = 1;
}
void RF24_TX_Mode(U8 *toAddr)
{
CE = 0;
nRF24L01P_Write_Buf(WR_TX_ADDR, toAddr, TX_ADR_WIDTH);
nRF24L01P_Write_Reg(WR_CONFIG, 0x0E);
nRF24L01P_Write_Buf(WR_RX_ADDR_P0, toAddr, TX_ADR_WIDTH);
nRF24L01P_Write_Reg(WR_STATUS, 0xFF);
}
bit RF24_RxData(U8 *rxbuf)
{
U8 state;
if(IRQ == 0)
{
state = nRF24L01P_Read_Reg(STATUS);
nRF24L01P_Write_Reg(WR_STATUS, state);
if(state & RX_DR)
{
nRF24L01P_Read_Buf(RD_RX_PLOAD,rxbuf,TX_PLOAD_WIDTH);
nRF24L01P_Write_Reg(FLUSH_RX,0xFF);
return ON;
}
}
return OFF;
}
bit RF24_TxData(U8 *txbuf)
{
U8 state;
while(RPD == 1);
CE=0;
nRF24L01P_Write_Buf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);
CE=1;
while(IRQ == 1);
state=nRF24L01P_Read_Reg(STATUS);
nRF24L01P_Write_Reg(WR_STATUS, state);
if(state&TX_DS)
return ON;
nRF24L01P_Write_Reg(FLUSH_TX,0xff);
return OFF;
}
nRF24L01+驱动的头文件nRF24L01P.h
#ifndef __NRF24L01P__
#define __NRF24L01P__
#include "STC15.H"
#include "Sys.h"
#include "Type.h"
#include "Timer.h"
#define MOSI P13
#define MISO P14
#define SCK P15
#define CSN P16
#define CE P17
#define IRQ P12
#define AUTO_RESEND_TIME 500
#define AUTO_RESEND_NUM 15
#define RFSETUP (RATE_1Mbps | E01ML01SP4_20dBm)
#define TX_ADR_WIDTH 5
#define TX_PLOAD_WIDTH 32
extern U8 SelfAddr[TX_ADR_WIDTH];
#define READ_REG 0x00
#define WRITE_REG 0x20
#define RD_RX_PLOAD 0x61
#define WR_TX_PLOAD 0xA0
#define WR_TX_PLOAD_NOACK 0xB0
#define FLUSH_TX 0xE1
#define FLUSH_RX 0xE2
#define REUSE_TX_PL 0xE3
#define NOP 0xFF
#define RETE_VAL ((AUTO_RESEND_TIME/250-1)<<4) + AUTO_RESEND_NUM
#define CONFIG 0x00
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_RETR 0x04
#define RF_CH 0x05
#define RF_SETUP 0x06
#define STATUS 0x07
#define OBSERVE_TX 0x08
#define RPD 0x09
#define RX_ADDR_P0 0x0A
#define RX_ADDR_P1 0x0B
#define RX_ADDR_P2 0x0C
#define RX_ADDR_P3 0x0D
#define RX_ADDR_P4 0x0E
#define RX_ADDR_P5 0x0F
#define TX_ADDR 0x10
#define RX_PW_P0 0x11
#define RX_PW_P1 0x12
#define RX_PW_P2 0x13
#define RX_PW_P3 0x14
#define RX_PW_P4 0x15
#define RX_PW_P5 0x16
#define FIFO_STATUS 0x17
#define FEATURE 0x1D
#define WR_CONFIG 0x20
#define WR_EN_AA 0x21
#define WR_EN_RXADDR 0x22
#define WR_SETUP_AW 0x23
#define WR_SETUP_RETR 0x24
#define WR_RF_CH 0x25
#define WR_RF_SETUP 0x26
#define WR_STATUS 0x27
#define WR_OBSERVE_TX 0x28
#define WR_RPD 0x29
#define WR_RX_ADDR_P0 0x2A
#define WR_RX_ADDR_P1 0x2B
#define WR_RX_ADDR_P2 0x2C
#define WR_RX_ADDR_P3 0x2D
#define WR_RX_ADDR_P4 0x2E
#define WR_RX_ADDR_P5 0x2F
#define WR_TX_ADDR 0x30
#define WR_RX_PW_P0 0x31
#define WR_RX_PW_P1 0x32
#define WR_RX_PW_P2 0x33
#define WR_RX_PW_P3 0x34
#define WR_RX_PW_P4 0x35
#define WR_RX_PW_P5 0x36
#define WR_FIFO_STATUS 0x37
#define WR_FEATURE 0x3D
#define RX_DR 0x40
#define TX_DS 0x20
#define MAX_RT 0x10
#define RATE_2Mbps 0x08
#define RATE_1Mbps 0x00
#define RATE_250Kbps 0x20
#define SI24R1_7dBm 0x07
#define SI24R1_4dBm 0x06
#define SI24R1_3dBm 0x05
#define SI24R1_1dBm 0x04
#define SI24R1_0dBm 0x03
#define SI24R1_f4dBm 0x02
#define SI24R1_f6dBm 0x01
#define SI24R1_f12dBm 0x00
#define E01ML01SP4_20dBm 0x06
#define E01ML01SP4_14dBm 0x04
#define E01ML01SP4_8dBm 0x02
#define E01ML01SP4_2dBm 0x00
void RF24_SetRfCh(U8 ch);
void RF24_Init();
void RF24_RX_Mode();
void RF24_TX_Mode(U8 *toAddr);
bit RF24_RxData(U8 *rxbuf);
bit RF24_TxData(U8 *txbuf);
#endif
写在后面
如果在使用中遇到问题,请先看我的另一条博文《nRF24L01+不能接收或接收偶尔异常等问题实战分享》,或直接在下面留言!
|