Hi Team,
I am working with Nrf24L01 chip with ATMEGA328(ATMEL C code) i made separate TX and RX module it works fine. But i want TX and RX in same module i done coding but it work as only receiver not switched to TX mode.Please find below code and give solution for me. If possible send me sample TXRX code.
/*
* TxRx_1.c
*
* Created: 5/4/2018 2:38:27 PM
* Author : Mahesh
*/
//header files
#include <avr/io.h>
#include <stdio.h>
#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/interrupt.h>
#include "nRF24L01.h"
//Function declaration
uint8_t GetReg(uint8_t);
uint8_t *WriteToNrf(uint8_t, uint8_t, uint8_t *, uint8_t);
void nrf24L01_init(void);
void nrf24L01_init_tx (void);
void nrf24L01_init_rx (void);
void Initspi(void);
void transmit_payload(uint8_t *);
void receive_payload(void);
void reset(void);
#define dataLen 5
#define W 1
#define R 0
//char data[10];
uint8_t *data;
uint8_t *data2;
int main(void)
{
char mode;
char tx_mode,rx_mode;
Initspi();
nrf24L01_init();
unsigned char W_buffer[5];
W_buffer[0]=1;
uint8_t str[5]={1,2,3,4,5}; //array contain number
// unsigned char W_buffer[5]; //TRANSMISSION
int i;
for(i=0;i<5;i++)
{
W_buffer[i]=str[i]; //sending something data in 0x93;
}
while(1)
{
if ((PIND & (1<<PIND5))==0)
mode=tx_mode;
else
mode=rx_mode;
if(mode==rx_mode)
{
reset();
nrf24L01_init_rx();
l1:
receive_payload();
if((GetReg(STATUS) & (1<<6)) != 0)
{
PORTD &= ~(1<<2);
_delay_us(50);
data=WriteToNrf(R,R_RX_PAYLOAD,data,5);
if(data[0]==1)
{
//mode=tx_mode;
PORTD &= ~(1<<4);
_delay_ms(2000);
PORTD |=(1<<4);
}
else
goto l1;
}
}
else if(mode=tx_mode)
{
//reset();
//_delay_ms(200);
nrf24L01_init_tx();
transmit_payload(W_buffer);
if((GetReg(STATUS) & (1<<5)) != 0)
{
PORTD &= ~(1<<4);
_delay_ms(2000);
PORTD |=(1<<4); //blink led
//_delay_ms(1000);
}
return 0;
}
}
}
void Initspi(void)
{
DDRD |= (1<<4); //LED
DDRB|=(1<<PINB5); //sck out
DDRB &= ~(1<<PINB4); //MISO
DDRB|=(1<<PINB2); //CSN out
DDRB|=(1<<PIND2); //CE out
DDRB|= (1<<PINB3); //MOSI
//PORTB |=(1<<PINB4);
PORTB |=(1<<PINB2); //CSN high to start with nothing to be sent to RF yet
PORTD &= ~(1<<PIND2); //CE low to start with nothing to sent /receive
DDRD &= ~(1<<5); //switch not yet used
PORTD |= (1<<5);
PORTD |= (1<<4);
SPCR|=(1<<SPE)|(1<<MSTR); // enable spi
}
char WriteByteSPI(unsigned char cData)
{
SPDR = cData; //Load byte to data register
while(!(SPSR & (1<<SPIF))); //wait for transmission complete
return SPDR; //return what received from nrf
}
void nrf24L01_init(void)
{
_delay_ms(100);
uint8_t val[5];
//EN_AA - (auto-acknowledgments) transmitter gets automatic response from receiver when successfil transmission
val[0]=0x01;
WriteToNrf(W, EN_AA, val, 1); //W=write mode EN_AA=register to write to val=data to write, 1=number of data bytes
val[0]=0x2F;
WriteToNrf(W, SETUP_RETR, val, 1); //set up automatic retransmission on fail of AA
val[0]=0x01;
WriteToNrf(W, EN_RXADDR, val, 1); //enable data pipe0 as RX address
//RF address width setup
val[0]=0x03;
WriteToNrf(W, SETUP_AW, val, 1); //5byte Rf address
//RF channel setup 2.4-2,52GHZ
val[0]=0x01;
WriteToNrf(W, RF_CH, val, 1); //2.4GHZ
//choose power mode and data speed
val[0]=0x07; //0b00000111 3rd bit 1=1Mbps,bit 2-1 power mode("11"=-0db ,"00"=-18db)
WriteToNrf(W, RF_SETUP, val, 1);
//Payload width setup
val[0]=dataLen;
WriteToNrf(W, RX_PW_P0, val, 1);
}
void nrf24L01_init_rx (void)
{
uint8_t val[5];
//RX RF address setup
int i;
for(i=0; i<5; i++)
{
val[i]=0x12;
}
WriteToNrf(W, RX_ADDR_P0, val, 5); //RX_ADDR_P0 giving address to pipe0
//Configure reg setup-now it is time to boot up the nrf and choose if it is receiver or transmitter
val[0]=0x1F;
WriteToNrf(W, CONFIG, val, 1); //0b0001 1110 bit 0="0":Transmitter bit 0="1":Receiver bit 1=power up
_delay_ms(100);
}
void nrf24L01_init_tx (void)
{
uint8_t val[5];
//TX RF address setup
for(i=0; i<5; i++)
{
val[i]=0x12;
}
WriteToNrf(W, TX_ADDR, val, 5);
//Configure reg setup-now it is time to boot up the nrf and choose if it is receiver or transmitter
val[0]=0x1E;
WriteToNrf(W, CONFIG, val, 1); //0b0001 1110 bit 0="0":Transmitter bit 0="1":Receiver bit 1=power up
_delay_ms(100);
}
uint8_t *WriteToNrf(uint8_t ReadWrite, uint8_t reg, uint8_t *val, uint8_t antVal)
{
//Read or write(W/R), reg=register, *val=array with package, antVal=number of integer in package
if (ReadWrite == W)
{
reg = W_REGISTER + reg; // add write bit to the register
}
static uint8_t ret[5];
_delay_us(10);
//CLEARBIT(PORTB, 2);
PORTB &= ~(1<<2); //CSN low nrf start listen command
WriteByteSPI(reg); //Set nrf to write/read mod of reg
_delay_us(10);
int i;
for(i=0; i<antVal; i++)
{
if (ReadWrite == R && reg != W_TX_PAYLOAD) //did you want the read registry
//when writing W_TX_PAYLOAD you cannot add the "W" since it is same level registry
{
ret[i]=WriteByteSPI(NOP); //send dummy bytes to read out the data
_delay_us(10);
}
else
{
WriteByteSPI(val[i]); //send commands once at a time
_delay_us(10);
}
}
//SETBIT(PORTB, 2);
PORTB |= (1<<2); //CSN high
return ret; //retun array
}
uint8_t GetReg(uint8_t reg)
{
_delay_us(10);
PORTB &= ~(1<<2); //CSN low nrf start listen command
//CLEARBIT(PORTB, 2); //CSN low
_delay_us(10);
WriteByteSPI(R_REGISTER + reg); //R_REGISTER set nrf to read mode reg=this register will read back
_delay_us(10);
reg = WriteByteSPI(NOP); //send dummy byte once to receive the first byte in the reg
_delay_us(10);
PORTB |= (1<<2); //CSN high stop listening
//SETBIT(PORTB, 2); //CSN IR_High
return reg;
}
void receive_payload(void)
{
PORTD |= (1<<2); //CE high listen for the data
//SETBIT(PORTB, 1);
//_delay_ms(1000);
// PORTD &= ~(1<<2); //CE low stop listening
//CLEARBIT(PORTB, 1);
//_delay_ms(10);
}
void transmit_payload(uint8_t *W_buff)
{
WriteToNrf(R, FLUSH_TX, W_buff, 0); //send 0xe1 to flush the old data
WriteToNrf(R, W_TX_PAYLOAD, W_buff,5);//send the data in W_buff to nrf
_delay_ms(10);
PORTD |= (1<<2); //CE high to transmit the data
//SETBIT(PORTB, 1);
_delay_us(20);
PORTD &= ~(1<<2); //CE low to stop
//CLEARBIT(PORTB, 1);
_delay_ms(10);
}
void reset(void)
{
_delay_us(10);
PORTB &= ~(1<<2);//CSN low
_delay_us(10);
WriteByteSPI(W_REGISTER + STATUS); //
_delay_us(10);
WriteByteSPI(0b01110000);
_delay_us(10);
PORTB |= (1<<2); //CSN IR_High
}