0% found this document useful (0 votes)
244 views9 pages

nRF24L01 Program Example

This document contains code for initializing an nRF24L01 radio frequency (RF) module to operate in either transmit (TX) or receive (RX) mode. It includes functions for configuring the module's registers and addresses for TX or RX operation, reading and writing data to registers via SPI, and transmitting or receiving payload data. The functions set parameters like the TX and RX addresses, data rate, RF channel, and payload size.

Uploaded by

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

nRF24L01 Program Example

This document contains code for initializing an nRF24L01 radio frequency (RF) module to operate in either transmit (TX) or receive (RX) mode. It includes functions for configuring the module's registers and addresses for TX or RX operation, reading and writing data to registers via SPI, and transmitting or receiving payload data. The functions set parameters like the TX and RX addresses, data rate, RF channel, and payload size.

Uploaded by

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

//**********************************************************

//
// nRF24L01 Program example
//
// Description:
// This example code is contains two functions,
// 'TX_Mode': program nRF24L01 to function as a PRIM:TX,
// i.e. program TX_Address, RX_Address for auto ack,
// TX Payload, setup of 'Auto Retransmit Delay' &
// 'Auto Retransmit Count', select RF channel,
// Datarate & RF output power.
//
// 'RX_Mode': program nRF24L01 to function as a PRIM:RX,
// i.e. ready to receive the packet that was sent with
// the 'TX_Mode' function.
//
//
// Author: RSK Date: 28.11.05
//**********************************************************
#include <c8051F330.h>
//#include "defines.h"
//#include "nRF_API.h"
//#include "LL_API.h"
//#include "Protocol_API.h"
//**********************************************************
// Prototypes
void Init_Device(void) ;
//**********************************************************
#define TX_ADR_LENGTH 5 // 5 bytes TX(RX) address widt
h
#define TX_PLOAD_WIDTH 16 // 16 bytes TX payload
#define BYTE unsigned char
//******************************************************************************
**************************************//
// SPI(nRF24L01) registers(addresses)
#define CONFIG 0x00 // 'Config' register address
#define EN_AA 0x01 // 'Enable Auto Acknowledgment' register address
#define EN_RXADDR 0x02 // 'Enabled RX addresses' register address
#define SETUP_AW 0x03 // 'Setup address width' register address
#define SETUP_RETR 0x04 // 'Setup Auto. Retrans' register address
#define RF_CH 0x05 // 'RF channel' register address
#define RF_SETUP 0x06 // 'RF setup' register address
#define STATUS 0x07 // 'Status' register address
#define OBSERVE_TX 0x08 // 'Observe TX' register address
#define CD 0x09 // 'Carrier Detect' register address
#define RX_ADDR_P0 0x0A // 'RX address pipe0' register address
#define RX_ADDR_P1 0x0B // 'RX address pipe1' register address
#define RX_ADDR_P2 0x0C // 'RX address pipe2' register address
#define RX_ADDR_P3 0x0D // 'RX address pipe3' register address
#define RX_ADDR_P4 0x0E // 'RX address pipe4' register address
#define RX_ADDR_P5 0x0F // 'RX address pipe5' register address
#define TX_ADDR 0x10 // 'TX address' register address
#define RX_PW_P0 0x11 // 'RX payload width, pipe0' register address
#define RX_PW_P1 0x12 // 'RX payload width, pipe1' register address
#define RX_PW_P2 0x13 // 'RX payload width, pipe2' register address
#define RX_PW_P3 0x14 // 'RX payload width, pipe3' register address
#define RX_PW_P4 0x15 // 'RX payload width, pipe4' register address
#define RX_PW_P5 0x16 // 'RX payload width, pipe5' register address
#define FIFO_STATUS 0x17 // 'FIFO Status Register' register address
//******************************************************************************
**************************************//
// SPI(nRF24L01) commands
#define READ_REG 0x00 // Define read command to register
#define WRITE_REG 0x20 // Define write command to register
#define RD_RX_PLOAD 0x61 // Define RX payload register address
#define WR_TX_PLOAD 0xA0 // Define TX payload register address
#define FLUSH_TX 0xE1 // Define flush TX register command
#define FLUSH_RX 0xE2 // Define flush RX register command
#define REUSE_TX_PL 0xE3 // Define reuse TX payload register command
#define NOP 0xFF // Define No Operation, might be used to read stat
us register
// Define nRF24L01 interrupt flag's
#define IDLE 0x00 // Idle, no interrupt pending
#define MAX_RT 0x10 // Max #of TX retrans interrupt
#define TX_DS 0x20 // TX data sent interrupt
#define RX_DR 0x40 // RX data received
#define SPI_CFG 0x40 // SPI Configuration register value
#define SPI_CTR 0x01 // SPI Control register values
#define SPI_CLK 0x00 // SYSCLK/2*(SPI_CLK+1) == > 12MHz / 2 = 6MHz
#define SPI0E 0x02 // SPI Enable in XBR0 register
#define EXT_INT0 0x00
BYTE IRQ_Source = 0; // Indicates IRQ source from n
RF24L01
BYTE SPI_Buffer[32]; // Buffer to hold data from 'S
PI_Read_Buf()' function
// Predefine a static TX address
BYTE const TX_ADDRESS[TX_ADR_LENGTH] = {0xe7,0xe7,0xe7,0xe7,0xe7};
// Predefine TX payload packet..
BYTE const TX_PAYLOAD[TX_PLOAD_WIDTH] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
};
// Define CE & IRQ pins
sbit CS = P0^3 ; // CS for SPI
sbit CE = P0^4; // Chip Enable pin signal (output)
sbit IRQ = P0^5; // Interrupt signal, from nRF24L01 (input)
//**********************************************************//
//
// Function: CSN_Pin
//
// CSN Pin handling
//
// In/Out parameters:
// In: "state"
// Out: --
//
//**********************************************************//
void CSN_Pin(BYTE state) // Set/reset CSN pin
{
if ( state )
CS = 1 ;
else
CS = 0 ;
}
//**********************************************************//
//
// Function: SPI_RW
//
// Description:
// Writes one byte to nRF24L01, and return the byte read
// from nRF24L01 during write, according to SPI protocol
//
// In/Out parameters:
// In: 'byte', current byte to be written
// Out: 'SPI0DAT', HW SPI mode, 'byte' SW SPI mode,
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_RW(BYTE byte) // Write one byte using
F320's hardware SPI
{
while(!SPIF);
{ }
SPIF = 0 ;
SPI0DAT = byte; // Writes 'byte' to nRF2
4L01


while(!SPIF);
{ }
return(SPI0DAT); // return received byte
}
//**********************************************************//
//
// Function: SPI_Read
//
// Description:
// Read one byte from nRF24L01 register, 'reg'
//
//
// In/Out parameters:
// In: reg, register to read
// Out: return reg_val, register value.
//
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_Read(BYTE reg)
{
BYTE reg_val;
CSN_Pin(0);
SPI_RW(reg); // Select register to read fro
m..
reg_val = SPI_RW(0); // ..then read registervalue
CSN_Pin(1); // CSN high, terminate SPI com
munication
return(reg_val); // return register value
}
//**********************************************************//
//
// Function: SPI_RW_Reg
//
// Description:
// Writes value 'value' to register 'reg'
//
//
// In/Out parameters:
// In: 'reg' register to write value 'value' to.
// Return status byte.
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_RW_Reg(BYTE reg, BYTE value)
{
BYTE status;
CSN_Pin(0); // CSN low, init SPI transacti
on
status = SPI_RW(reg); // select register
SPI_RW(value); // ..and write value to it..
CSN_Pin(1); // CSN high again
return(status); // return nRF24L01 status byte
}
//**********************************************************//
//
// Function: SPI_Write_Buf
//
// Description:
// Writes contents of buffer '*pBuf' to nRF24L01
// Typically used to write TX payload, Rx/Tx address
//
//
// In/Out parameters:
// In: register 'reg' to write, buffer '*pBuf*' contains
// data to be written and buffer size 'buf_size' is #of
// bytes to be written
// Out: return nRF24L01 status byte.
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_Write_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
BYTE status,byte_ctr;
CSN_Pin(0); // Set CSN low, init SPI trana
ction
status = SPI_RW(reg); // Select register to write to
and read status byte
for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buff
er(*pBuf)
SPI_RW(*pBuf++);
CSN_Pin(1); // Set CSN high again
return(status); // return nRF24L01 status byte
}
//**********************************************************//
//
// Function: SPI_Read_Buf
//
// Description:
// Reads 'bytes' #of bytes from register 'reg'
// Typically used to read RX payload, Rx/Tx address
//
//
// In/Out parameters:
// In: 'reg', register to read from, '*pBuf' are buffer
// the read bytes are stored to and 'bytes' are #of bytes
// to read.
// Out: return nRF24L01 status byte.
//
// Author: RSK Date: 28.11.05
//**********************************************************//
BYTE SPI_Read_Buf(BYTE reg, BYTE *pBuf, BYTE bytes)
{
BYTE status,byte_ctr;
CSN_Pin(0); // Set CSN low, init SPI trana
ction
status = SPI_RW(reg); // Select register to write to
and read status byte
for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
pBuf[byte_ctr] = SPI_RW(0); // Perform SPI_RW to read byte
from nRF24L01
CSN_Pin(1); // Set CSN high again
return(status); // return nRF24L01 status byte
}
BYTE NRFStat ;
//**********************************************************
//
// Function: TX_Mode
//
// Description:
// This function initializes one nRF24L01 device to
// TX mode, set TX address, set RX address for auto.ack,
// fill TX payload, select RF channel, datarate & TX pwr.
// PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.
//
// ToDo: One high pulse(>10s) on CE will now send this !!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!
// packet and expext an acknowledgment from the RX device.
//
//
// Author: RSK Date: 28.11.05
//**********************************************************
void TX_Mode(void)
{
SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_LENGTH); // W
rites TX_Address to nRF24L01
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_LENGTH); // R
X_Addr0 same as TX_Adr for Auto.Ack
SPI_Write_Buf(WR_TX_PLOAD, TX_PAYLOAD, TX_PLOAD_WIDTH); // W
rites data to TX payload
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // E
nable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // E
nable Pipe0
SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 5
00s + 86s, 10 retrans...
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // S
elect RF channel 40
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // T
X_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // S
et PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..
// This device is now ready to transmit one packet of 16 bytes payload to a R
X device at address
// '3443101001', with auto acknowledgment, retransmit count of 10(retransmit
delay of 500s+86s)
// RF channel 40, datarate = 2Mbps with TX power = 0dBm.
}
void Delay100us(volatile unsigned char n) // Schleifenbeis
piel von Nordic
{
unsigned char i;
while(n--)
for(i=0;i<32;i++);
}
//**********************************************************
//
// Function: RX_Mode
//
// Description:
// This function initializes one nRF24L01 device to
// RX Mode, set RX address, writes RX payload width,
// select RF channel, datarate & LNA HCURR.
// After init, CE is toggled high, which means that
// this device is now ready to receive a datapacket.
//
// Author: RSK Date: 28.11.05
//**********************************************************
void RX_Mode(void)
{
unsigned int i ;
SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_LENGTH); // Use the s
ame address on the RX device as the TX device
SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); // Enable Auto.Ack:Pipe0
SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // Enable Pipe0
SPI_RW_Reg(WRITE_REG + RF_CH, 40); // Select RF channel 40
SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload wi
dth as TX Payload width
SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x0f); // TX_PWR:0dBm, Datarate:2Mbps
, LNA:HCURR
SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // Set PWR_UP bit, enable CRC(
2 bytes) & Prim:RX. RX_DR enabled..
CE = 1; // Set CE pin high to enable RX device
Delay100us(15);
//for ( i = 0 ; i< 30000 ; )
// { i++;
// }
// This device is now ready to receive one packet of 16 bytes payload from a
TX device sending to address
// '3443101001', with auto acknowledgment, retransmit count of 10, RF channel
40 and datarate = 2Mbps.
}
//BYTE IRQCNT ;
void nRF24L01_IRQ (void) interrupt EXT_INT0
{
BYTE temp,rx_pw;
//IRQCNT++;
EA = 0; // disable global interrupt d
uring processing
temp = SPI_RW_Reg(WRITE_REG + STATUS, 0x70); // Read STATUS byte and clear
IRQ flag's(nRF24L01)
if(temp & MAX_RT) IRQ_Source = MAX_RT; // Indicates max #of retransmi
t interrupt
if(temp & TX_DS) IRQ_Source = TX_DS; // Indicates TX data succsessf
ully sent
if(temp & RX_DR) // In RX mode, check for data
received
{
// Data received, so find out which datapipe the data was received on:
temp = (0x07 & (temp > 1)); // Shift bits in status
byte one bit to LSB and mask 'Data Pipe Number'
rx_pw = SPI_Read(READ_REG + RX_PW_P0 + temp); // Read current RX_PW_P
register, where Pn is the pipe the data was received on..
SPI_Read_Buf( RD_RX_PLOAD, SPI_Buffer, rx_pw ); // Data from RX Paylo
ad register is now copied to SPI_Buffer[].
IRQ_Source = RX_DR; // Indicates RX data rec
eived
}
EA = 1;
// enable global interrupt again
}
BYTE temp,rx_pw;
void main ( void )
{
unsigned int CDD=0;
RX_Mode ();
Init_Device() ;
SPIF = 1 ; // SPI IRQ-Flag
IT0 = 1 ; // Edge trigger for Int0
CE = 0 ;
EA = 1 ; // enable IRQ global
while ( 1 )
{
NRFStat = SPI_Read(READ_REG + STATUS );
// if ( NRFStat == 1 )
// { CDD++; }
;
}
}

You might also like