0% found this document useful (0 votes)
234 views18 pages

NRF24L01 Interfacing With 8051

The document discusses interfacing an NRF24L01 wireless module with an 8051 microcontroller. It provides details on the hardware and software needed to transmit and receive data between two 8051 boards wirelessly using the NRF24L01 modules. Programming code examples for the transmitter and receiver are included.

Uploaded by

gprodan2002a2948
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
234 views18 pages

NRF24L01 Interfacing With 8051

The document discusses interfacing an NRF24L01 wireless module with an 8051 microcontroller. It provides details on the hardware and software needed to transmit and receive data between two 8051 boards wirelessly using the NRF24L01 modules. Programming code examples for the transmitter and receiver are included.

Uploaded by

gprodan2002a2948
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

NRF24L01 interfacing with 8051 – Wireless

Xbee
by SLR
In our previous tutorial, we have seen a gas detection sensor interfacing with 8051. NRF24L01
interfacing with 8051 tutorial is intended to enable wireless data transfer for 8051. So to do that, we
will interface nRF24L10 with 8051. This will enable us to transfer the data wirelessly (by air) between
two 8051 boards using NRF24L01.

Post Contents [hide]

• 1 NRF24L01 interfacing with 8051


• 2 Hardware Required
• 3 NRF24L0
o 3.1 nRF24L01 Features
o 3.2 nRF24L01 Pin Configuration
o 3.3 Applications
o 3.4 How to Use the NRF24L01
▪ 3.4.1 Write Register
▪ 3.4.2 Read Register
• 4 Programming – NRF24L01 interfacing with 8051
o 4.1 Connection
o 4.2 TX Code
o 4.3 RX Code
o 4.4 Related

NRF24L01 interfacing with 8051


Hardware Required

• 8051 Development board – 2


• NRF24L01 – 2
• PC (To send/read data through UART using any serial terminal)

NRF24L0

Before start coding, we will see something about NRF24L01 to get some idea.

The nRF24L01 is a wireless transceiver module, meaning each module can both send as well as
receive data. They operate at the frequency of 2.4GHz, which falls under the ISM band, and hence it
is legal to use in almost all countries for engineering applications. The modules when operated
efficiently can cover a distance of 100 meters (200 feet) which makes it a great choice for all wireless
remote-controlled projects.
The module operates at 3.3V hence can be easily used with 3.2V systems or 5V systems. Each
module has an address range of 125 and each module can communicate with 6 other modules
hence it is possible to have multiple wireless units communicating with each other in a
particular area. Hence mesh networks or other types of networks are possible using this module.
So if you are looking for a wireless module with the above properties then this module would
be an ideal choice for you.

These modules are very cheap, smaller in size, and have a lot of specifications. Some of the
specifications of these modules are as follows,

nRF24L01 Features

• 2.4GHz RF transceiver Module


• Operating Voltage: 3.3V
• Nominal current: 50mA
• Range: 50 – 200 feet
• Operating current: 250mA (maximum)
• Communication Protocol: SPI
• Baud Rate: 250 kbps – 2 Mbps.
• Channel Range: 125
• Maximum Pipelines/node: 6
• Low-cost wireless solution

Note: Complete Technical Details can be found on the NRF24L01 datasheet.

nRF24L01 Pin Configuration

Pin Pin
Abbreviation Function
Number Name

1 Ground Ground Connected to the Ground of the system

2 Vcc Power Powers the module using 3.3V

3 CE Chip Enable Used to enable SPI communication

This pin has to be kept high always, else it will disable the
4 CSN Ship Select Not
SPI

Provides the clock pulse using which the SPI communication


5 SCK Serial Clock
works

Master Out Slave Connected to MOSI pin of MCU, for the module to receive
6 MOSI
In data from the MCU

Master In Slave Connected to MISO pin of MCU, for the module to send
7 MISO
Out data from the MCU

It is an active low pin and is used only if the interrupt is


8 IRQ Interrupt
required
Applications

• Wireless Control application


• Mesh Networks
• RF Remote Controllers
• Connected devices

How to Use the NRF24L01

The NRF24L01 module works with the help of SPI communications. These modules can
either be used with a 3.3V microcontroller or a 5V microcontroller but they should have an SPI
port. Since 8051 doesn’t have the SPI, we are going to implement the SPI using the bit-banging
method.

And SPI will be having just 4 lines but here it has one more line extra called CE pin to enable
reception, transmission, and put the device into standby mode.

Write Register

• Write SPI write register address + 0x20


• Then write register value

Read Register

• Write the registered address


• Read the data

One status register is there (0x07). You can read the status of the transaction.

For more information, please check the datasheet.

Programming – NRF24L01 interfacing with 8051

In this tutorial, we are going to use one setup for transmitter purpose and another for receiver
purpose. The concept is much simple. When we send something through the serial port in the
transmitter, that will be transmitted over the air. Since we are using the same address for both
TX and RX, RX will receive the data from the air and print the data through the serial port.

You can get the complete source code from GitHub.

Connection

• MISO – Port 1.0


• MOSI – Port 1.1
• SCK – Port 1.2
• CSN – Port 1.3
• CE – Port 1.4
TX Code

We have added only the NRF24L01 related source code. You can get the full project’s code
from GitHub.

nRF24L01.h

#include<intrins.h>

#include<reg51.h>

#include"SERIAL.H"

#define TX_mode //If u want to receive Change to RX_mode

sbit MISO = P1^0; //SPI signal

sbit MOSI = P1^1; //SPI signal

sbit SCK = P1^2; //SPI signal-Clk

sbit CSN = P1^3; //SPI signal-Chip select

sbit CE = P1^4; //this signal is active high and is used to activate the chip in RX or TX mode

//Commands

#define R_REG 0x00 //Read command from reg

#define W_REG 0x20 //Write command to reg

#define R_RX_PL 0x61 //RX payload register address

#define W_TX_PL 0xA0 //TX payload register address

#define FLUSH_TX 0xE1 //Flush TX register

#define FLUSH_RX 0xE2 //Flush RX register

#define REUSE_TX_PL 0xE3 //Reuse TX payload register

#define NOP 0xFF //No operation, might be used to read status register

//Register Address

#define CONFIG 0x00 //'Config' Reg

#define EN_AA 0x01 //Enable Auto Ack Reg

#define EN_RXADDR 0x02 //Enabled RX Addresses Reg

#define SETUP_AW 0x03 //Setup of Address Widths Reg

#define SETUP_PETR 0x04 //Setup of Automatic Retransmission Reg

#define RF_CH 0x05 //RF Channel Reg

#define RF_SETUP 0x06 //RF Setup Reg

#define STATUS 0x07 //Status Reg


#define OBSERVE_TX 0x08 //Transmit observe Reg

#define CD 0x09 //Carrier Detect Reg

#define RX_ADDR_P0 0x0A //Receive address data pipe 0

#define RX_ADDR_P1 0x0B //Receive address data pipe 1

#define RX_ADDR_P2 0x0C //Receive address data pipe 2

#define RX_ADDR_P3 0x0D //Receive address data pipe 3

#define RX_ADDR_P4 0x0E //Receive address data pipe 4

#define RX_ADDR_P5 0x0F //Receive address data pipe 5

#define TX_ADDR 0x10 //Transmit address. Used for a PTX device only

#define RX_PW_P0 0x11 //RX payload width, pipe 0

#define RX_PW_P1 0x12 //RX payload width, pipe 1

#define RX_PW_P2 0x13 //RX payload width, pipe 2

#define RX_PW_P3 0x14 //RX payload width, pipe 3

#define RX_PW_P4 0x15 //RX payload width, pipe 4

#define RX_PW_P5 0x16 //RX payload width, pipe 5

#define FIFO_STATUS 0x17 //FIFO Status Reg

#define TX_PLOAD_WIDTH 1

#define TX_ADD_WIDTH 5

const unsigned char TX_ADDRESS[TX_ADD_WIDTH] ={'i','n','t','e','r'};

unsigned char read_buf[TX_PLOAD_WIDTH+1];

volatile unsigned char bdata ack;

sbit RX_DR=ack^6;

sbit TX_DS=ack^5;

sbit MAX_RT=ack^4;

volatile unsigned char bdata buffer;

sbit msb = buffer^7;

sbit lsb = buffer^0;

void spi_delay(void); //Delay

void nRF_config(void); //Select RX or TX

unsigned char spi_W(unsigned char); //Write byte and read the status

unsigned char spi_WREG(unsigned char,unsigned char); //Write byte to REG and Read Status
unsigned char spi_WBUF(unsigned char reg,unsigned char *buff ,unsigned char count); //Write the
no of char to REG

unsigned char spi_RREG(unsigned char); //Read the REG that have one byte

void spi_RBUF(unsigned char reg,unsigned char count); //Read the REG that have more than one
byte

unsigned char TX_PL(const unsigned char *payload); //Transmit payload

unsigned char* RX_PL(void); //Receive payload

void get_status(void); //Get the status

void clear_irq(void); //Clear IRQ bits (TX_DS, MAX_RT, RX_DR)

void spi_delay()

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

void get_status(void)

ack=0;

ack=spi_RREG(STATUS);

void clear_irq()

spi_WREG(W_REG|STATUS,0x70); //Clear RX_DR, TX_DS, MAX_RT flags

void nRF_config()

CE=0; //Chip enable

CSN=1; //SPI disable

SCK=0; //SPI clock line init high

#ifdef TX_mode

spi_WBUF(W_REG|TX_ADDR,TX_ADDRESS,TX_ADD_WIDTH); //Set static TX address

spi_WBUF(W_REG|RX_ADDR_P0,TX_ADDRESS,TX_ADD_WIDTH); //Set static RX address for auto ack

#endif
#ifdef RX_mode

CE=0;

spi_WREG(FLUSH_RX,NOP); //Clear the RX_FIFO

spi_WREG(W_REG|CONFIG,0x0F); //Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled

spi_WREG(W_REG|EN_AA,0x01); //Enable ShockBurst (Enable Auto ACK)

spi_WREG(W_REG|SETUP_AW,0x03); //Puts the address field width 5bytes

spi_WREG(W_REG|RF_CH,0x6E); //Set frequency channel 110 (2.510MHz)

spi_WREG(W_REG|RF_SETUP,0x06); //Setup: 1Mbps, 0dBm, LNA off

spi_WREG(W_REG|EN_RXADDR,0x01); //Enable data pipe 0

spi_WBUF(W_REG|RX_ADDR_P0,TX_ADDRESS,TX_ADD_WIDTH); //Set static RX address

spi_WREG(W_REG|RX_PW_P0,TX_PLOAD_WIDTH); //Set RX payload length

CE=1;

#endif

unsigned char spi_W(unsigned char buf)

int sp;

buffer=buf;

for(sp=0;sp<=7;sp++)

MOSI=msb; //MSB to MOSI-OUTPUT

buffer=buffer<<1;

SCK=1;

buffer&=0xfe; //Clear 0th bit

buffer|=MISO; //capture current MISO bit

SCK=0;

return buffer;

unsigned char spi_WREG(unsigned char reg,unsigned char value)

{
unsigned char stat;

CSN=0; //CSN low, init SPI transaction

stat=spi_W(reg); //Select Reg

spi_W(value); //Send Value

CSN=1; //CSN high

return stat;

unsigned char spi_WBUF(unsigned char reg,unsigned char *buff ,unsigned char count)

unsigned char stat,sp;

CSN=0;

stat=spi_W(reg);

for(sp=0;sp<count;sp++)

spi_W(buff[sp]);

CSN=1;

return stat;

#ifdef TX_mode

unsigned char TX_PL(unsigned char *payload)

unsigned char stat;

clear_irq();

CE=0;

spi_WREG(FLUSH_TX,NOP); //Clear the TX_FIFO

spi_WREG(W_REG|CONFIG,0x00); //PRIM_RX : PTX

spi_WREG(W_REG|EN_AA,0x01); //Enable ShockBurst (Enable Auto ACK)

spi_WREG(W_REG|EN_RXADDR,0x01); //Enable data pipe 0

spi_WREG(W_REG|SETUP_AW,0x03); // Puts the address field width 5bytes

spi_WREG(W_REG|SETUP_PETR,0x1A); //Auto retransmit: wait 500us, 10 retries


spi_WREG(W_REG|RF_CH,0x6E); //Set frequency channel 110 (2.510MHz)

spi_WREG(W_REG|RF_SETUP,0x06); //Setup: 1Mbps, 0dBm, LNA off

spi_WREG(W_REG|CONFIG,0x0E); //Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT &
TX_DS enabled

spi_WBUF(W_TX_PL,payload,TX_PLOAD_WIDTH); //Write specified buffer to FIFO

CE=1;

spi_delay();

CE=0;

get_status();

if(MAX_RT)

return 0;

if(TX_DS)

return 1;

return stat;

#endif

unsigned char spi_RREG(unsigned char reg)

unsigned char rd;

CSN=0;

spi_W(reg);

rd=spi_W(0);

CSN=1;

return rd;

#ifdef RX_mode

void spi_RBUF(unsigned char reg,unsigned char count)

unsigned char stat,sp;

CSN = 0; // Set CSN low, init SPI tranaction

stat=spi_W(reg);
for(sp=0;sp<count;sp++)

read_buf[sp]=spi_W(0);

read_buf[sp]='\0';

CSN = 1; // Set CSN high again

unsigned char* RX_PL()

spi_WREG(FLUSH_RX,NOP);

do

get_status();

}while(RX_DR==0);

if(RX_DR)

clear_irq();

get_status();

if(ack ==0)

spi_RBUF(R_RX_PL,TX_PLOAD_WIDTH);

spi_delay();

return read_buf;

#endif

RX Code
We have added only the NRF24L01 related source code. You can get the full project’s code from
GitHub.

nRF24L01.h
#include<intrins.h>

#include<reg51.h>

#include"SERIAL.H"

#define RX_mode //If u want to receive Change to RX_mode

sbit MISO = P1^0; //SPI signal

sbit MOSI = P1^1; //SPI signal

sbit SCK = P1^2; //SPI signal-Clk

sbit CSN = P1^3; //SPI signal-Chip select

sbit CE = P1^4; //this signal is active high and is used to activate the chip in RX or TX mode

//Commands

#define R_REG 0x00 //Read command from reg

#define W_REG 0x20 //Write command to reg

#define R_RX_PL 0x61 //RX payload register address

#define W_TX_PL 0xA0 //TX payload register address

#define FLUSH_TX 0xE1 //Flush TX register

#define FLUSH_RX 0xE2 //Flush RX register

#define REUSE_TX_PL 0xE3 //Reuse TX payload register

#define NOP 0xFF //No operation, might be used to read status register

//Register Address

#define CONFIG 0x00 //'Config' Reg

#define EN_AA 0x01 //Enable Auto Ack Reg

#define EN_RXADDR 0x02 //Enabled RX Addresses Reg

#define SETUP_AW 0x03 //Setup of Address Widths Reg

#define SETUP_PETR 0x04 //Setup of Automatic Retransmission Reg

#define RF_CH 0x05 //RF Channel Reg

#define RF_SETUP 0x06 //RF Setup Reg

#define STATUS 0x07 //Status Reg

#define OBSERVE_TX 0x08 //Transmit observe Reg

#define CD 0x09 //Carrier Detect Reg

#define RX_ADDR_P0 0x0A //Receive address data pipe 0

#define RX_ADDR_P1 0x0B //Receive address data pipe 1


#define RX_ADDR_P2 0x0C //Receive address data pipe 2

#define RX_ADDR_P3 0x0D //Receive address data pipe 3

#define RX_ADDR_P4 0x0E //Receive address data pipe 4

#define RX_ADDR_P5 0x0F //Receive address data pipe 5

#define TX_ADDR 0x10 //Transmit address. Used for a PTX device only

#define RX_PW_P0 0x11 //RX payload width, pipe 0

#define RX_PW_P1 0x12 //RX payload width, pipe 1

#define RX_PW_P2 0x13 //RX payload width, pipe 2

#define RX_PW_P3 0x14 //RX payload width, pipe 3

#define RX_PW_P4 0x15 //RX payload width, pipe 4

#define RX_PW_P5 0x16 //RX payload width, pipe 5

#define FIFO_STATUS 0x17 //FIFO Status Reg

#define TX_PLOAD_WIDTH 1

#define TX_ADD_WIDTH 5

const unsigned char TX_ADDRESS[TX_ADD_WIDTH] ={'i','n','t','e','r'};

unsigned char read_buf[TX_PLOAD_WIDTH+1];

volatile unsigned char bdata ack;

sbit RX_DR=ack^6;

sbit TX_DS=ack^5;

sbit MAX_RT=ack^4;

volatile unsigned char bdata buffer;

sbit msb = buffer^7;

sbit lsb = buffer^0;

void spi_delay(void); //Delay

void nRF_config(void); //Select RX or TX

unsigned char spi_W(unsigned char); //Write byte and read the status

unsigned char spi_WREG(unsigned char,unsigned char); //Write byte to REG and Read Status

unsigned char spi_WBUF(unsigned char reg,unsigned char *buff ,unsigned char count); //Write the
no of char to REG

unsigned char spi_RREG(unsigned char); //Read the REG that have one byte

void spi_RBUF(unsigned char reg,unsigned char count); //Read the REG that have more than one
byte
unsigned char TX_PL(const unsigned char *payload); //Transmit payload

unsigned char* RX_PL(void); //Receive payload

void get_status(void); //Get the status

void clear_irq(void); //Clear IRQ bits (TX_DS, MAX_RT, RX_DR)

void spi_delay()

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

void get_status(void)

ack=0;

ack=spi_RREG(STATUS);

void clear_irq()

spi_WREG(W_REG|STATUS,0x70); //Clear RX_DR, TX_DS, MAX_RT flags

void nRF_config()

CE=0; //Chip enable

CSN=1; //SPI disable

SCK=0; //SPI clock line init high

#ifdef TX_mode

spi_WBUF(W_REG|TX_ADDR,TX_ADDRESS,TX_ADD_WIDTH); //Set static TX address

spi_WBUF(W_REG|RX_ADDR_P0,TX_ADDRESS,TX_ADD_WIDTH); //Set static RX address for auto ack

#endif

#ifdef RX_mode

CE=0;

spi_WREG(FLUSH_RX,NOP); //Clear the RX_FIFO

spi_WREG(W_REG|CONFIG,0x0F); //Set PWR_UP bit ,PRIM_RX : PRX


spi_WREG(W_REG|EN_AA,0x01); //Disable ShockBurst (Disable Auto ACK)

spi_WREG(W_REG|SETUP_AW,0x03); // Puts the address field width 5bytes

spi_WREG(W_REG|RF_CH,0x6E); //Set frequency channel 110 (2.510MHz)

spi_WREG(W_REG|RF_SETUP,0x06); //Setup: 1Mbps, 0dBm, LNA off

spi_WREG(W_REG|EN_RXADDR,0x01); //Enable data pipe 0

spi_WBUF(W_REG|RX_ADDR_P0,TX_ADDRESS,TX_ADD_WIDTH); //Set static RX address

spi_WREG(W_REG|RX_PW_P0,TX_PLOAD_WIDTH); //Set RX payload length

CE=1;

#endif

unsigned char spi_W(unsigned char buf)

int sp;

buffer=buf;

for(sp=0;sp<=7;sp++)

MOSI=msb; //MSB to MOSI-OUTPUT

buffer=buffer<<1;

SCK=1;

buffer&=0xfe; //Clear 0th bit

buffer|=MISO; //capture current MISO bit

SCK=0;

return buffer;

unsigned char spi_WREG(unsigned char reg,unsigned char value)

unsigned char stat;

CSN=0; //CSN low, init SPI transaction

stat=spi_W(reg); //Select Reg

spi_W(value); //Send Value


CSN=1; //CSN high

return stat;

unsigned char spi_WBUF(unsigned char reg,unsigned char *buff ,unsigned char count)

unsigned char stat,sp;

CSN=0;

stat=spi_W(reg);

for(sp=0;sp<count;sp++)

spi_W(buff[sp]);

CSN=1;

return stat;

#ifdef TX_mode

unsigned char TX_PL(unsigned char *payload)

unsigned char stat;

clear_irq();

CE=0;

spi_WREG(FLUSH_TX,NOP); //Clear the TX_FIFO

spi_WREG(W_REG|CONFIG,0x00); //PRIM_RX : PTX

spi_WREG(W_REG|EN_AA,0x01); //Disable ShockBurst (Disable Auto ACK)

spi_WREG(W_REG|EN_RXADDR,0x01); //Enable data pipe 0

spi_WREG(W_REG|SETUP_AW,0x03); // Puts the address field width 5bytes

spi_WREG(W_REG|SETUP_PETR,0x1A); //Auto retransmit: wait 500us, 10 retries

spi_WREG(W_REG|RF_CH,0x6E); //Set frequency channel 110 (2.510MHz)

spi_WREG(W_REG|RF_SETUP,0x06); //Setup: 1Mbps, 0dBm, LNA off

spi_WREG(W_REG|CONFIG,0x0E); //Set PWR_UP bit

spi_WBUF(W_TX_PL,payload,TX_PLOAD_WIDTH); //Write specified buffer to FIFO


CE=1;

spi_delay();

CE=0;

get_status();

if(MAX_RT)

return 0;

if(TX_DS)

return 1;

return stat;

#endif

unsigned char spi_RREG(unsigned char reg)

unsigned char rd;

CSN=0;

spi_W(reg);

rd=spi_W(0);

CSN=1;

return rd;

#ifdef RX_mode

void spi_RBUF(unsigned char reg,unsigned char count)

unsigned char stat,sp;

CSN = 0; // Set CSN low, init SPI tranaction

stat=spi_W(reg);

for(sp=0;sp<count;sp++)

read_buf[sp]=spi_W(0);

read_buf[sp]='\0';
CSN = 1; // Set CSN high again

unsigned char* RX_PL()

spi_WREG(FLUSH_RX,NOP);

do

get_status();

}while(RX_DR==0);

if(RX_DR)

clear_irq();

get_status();

if(ack ==0)

spi_RBUF(R_RX_PL,TX_PLOAD_WIDTH);

spi_delay();

return read_buf;

#endif

You might also like