проблема AVR codevision получение подтверждения или флага TX_DS в модуле nRF24L01+

Я пытаюсь общаться с помощью двух радиомодулей nRF24L01, подключенных к atmega8s через spi.

Все, что я могу сделать, это написать некоторый реестр nRF, но никакие данные не могут быть отправлены. Когда я читаю регистр состояния радио, он возвращает decimal 14 или иногда 0 или иногда decimal 30.

Вот мой код atmega8:

#include <mega8.h>
#include <C:cvavrBINnRF24L01nrf24l012.h>
#include <stdio.h>
#include <pcf8576d.h>

#define    _CH 1            // Channel 0..125
#define    _Address_Width 5    // 3..5
#define _Buffer_Size 32 // 1..32


// Declare your global variables here
unsigned char global_var=0;

void NRF24L01_Receive(char Buf[_Buffer_Size]) {
    NRF24L01_CE_HIGH;
    delay_us(130);

    while ((NRF24L01_Get_Status() & _RX_DR) != _RX_DR);

    NRF24L01_CE_LOW;

    NRF24L01_Read_RX_Buf(Buf, _Buffer_Size);
    NRF24L01_Clear_Interrupts();
}


void NRF24L01_Send(char* Buf) {
    NRF24L01_Write_TX_Buf(Buf, _Buffer_Size);

    NRF24L01_RF_TX();

    while ((NRF24L01_Get_Status() & _TX_DS) != _TX_DS) ;

    NRF24L01_Clear_Interrupts();

}

// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
    char buffer[32];
    char state = NRF24L01_Get_Status(); 
    lcd_erase();
    lcd_printf("INT ");
    lcd_print(state);
    if(state==0) NRF24L01_Read_RX_Buf(buffer,32);
    lcd_print(buffer[0]); 
    delay_ms(100);

    NRF24L01_Clear_Interrupts();
}

// SPI interrupt service routine
interrupt [SPI_STC] void spi_isr(void)
{



}


void main(void)
{
    // Declare your local variables here
    char i;
    unsigned char bffr[5];
    unsigned char Buf[_Buffer_Size];
    unsigned char Data[5]={3,9,5,8,4};
    unsigned char Address_p0[_Address_Width] = { 0xf0,0xf0,0xf0,0xf0,0xe1  }; 
    unsigned char Address_p1[_Address_Width] = { 0xf0,0xf0,0xf0,0xf0,0xd2  }; 
    unsigned char Address_p2[1]={0xc3};
    unsigned char Address_p3[1]={0xc4};
    unsigned char Address_p4[1]={0xc5};
    unsigned char Address_p5[1]={0xc6};
    spi_int1_init();    
    TWI_init_master();

    delay_ms(300); 
    lcd_erase();
    lcd_printf("start");
    delay_ms(1200);

    NRF24L01_Init(_TX_MODE, _CH, _1Mbps, Address_p0, _Address_Width, _Buffer_Size);
    NRF24L01_WriteReg(W_REGISTER | EN_RXADDR,0x03);
    NRF24L01_Set_RX_Pipe (0,Address_p0,_Address_Width, _Buffer_Size);
    NRF24L01_Set_RX_Pipe (1,Address_p1,_Address_Width, _Buffer_Size); 
    NRF24L01_Set_TX_Address(Address_p0,_Address_Width);
    NRF24L01_Set_RX_Pipe (2,Address_p2,1,0); 
    NRF24L01_Set_RX_Pipe (3,Address_p3,1,0);
    NRF24L01_Set_RX_Pipe (4,Address_p4,1,0);
    NRF24L01_Set_RX_Pipe (5,Address_p5,1,0);
    NRF24L01_WriteReg(W_REGISTER | EN_AA,0X3F);
    NRF24L01_WriteReg(W_REGISTER | EN_RXADDR,0x03);
    NRF24L01_WriteReg(W_REGISTER | RF_CH, 0x0c); 
    NRF24L01_WriteReg(W_REGISTER | RF_SETUP,0X03);
    NRF24L01_WriteReg(W_REGISTER | CONFIG,0X0E);
    NRF24L01_WriteReg(W_REGISTER | SETUP_RETR,0X28);


    global_var = NRF24L01_Get_Status();
    //global_var=SPI(234);
    lcd_erase();
    lcd_print(global_var);
    delay_ms(1000);
    global_var = NRF24L01_ReadReg(CONFIG);
    lcd_erase();
    lcd_print(global_var);
    delay_ms(1000);

    lcd_erase();
    NRF24L01_ReadRegBuf(TX_ADDR,bffr,5);
    for(i=0;i<5;i++)
        lcd_print(bffr[i]);
    delay_ms(1000);

    global_var = NRF24L01_ReadReg(FIFO_STATUS);
    lcd_erase();
    lcd_printf("ffo ");
    lcd_print(global_var);  
    delay_ms(1000);

    NRF24L01_Send(Data);  
    global_var = NRF24L01_Get_Status();
    lcd_erase();
    lcd_print(global_var);  
    delay_ms(1000);

    global_var = NRF24L01_ReadReg(FIFO_STATUS);
    lcd_erase();
    lcd_printf("mioh ");
    lcd_print(global_var);  
    delay_ms(1000);

    while (1);
}

а вот мой nrf24l012.ч

#include <delay.h>
#include <C:cvavrBINnRF24L01nrf24l011.h>  


/*
 * SPI pins:
 * MOSI: DDB3
 * MISO: DDB4
 * SCK : DDB5
 * CSN : DDB2
 * CE   : DDB1
 */
 void spi_int1_init(void){
 // Input/Output Ports initialization
// Port B initialization
// Function: Bit7=In Bit6=In Bit5=Out Bit4=In Bit3=Out Bit2=Out Bit1=In Bit0=In 
DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (0<<DDB4) | (1<<DDB3) | (1<<DDB2) | (1<<DDB1) | (0<<DDB0);
// State: Bit7=T Bit6=T Bit5=0 Bit4=T Bit3=0 Bit2=0 Bit1=T Bit0=T 
PORTB=(0<<PORTB7) | (0<<PORTB6) | (0<<PORTB5) | (0<<PORTB4) | (0<<PORTB3) | (0<<PORTB2) | (0<<PORTB1) | (0<<PORTB0);


// External Interrupt(s) initialization
// INT0: Off
// INT1: On
// INT1 Mode: Falling Edge
GICR|=(1<<INT1) | (0<<INT0);
MCUCR=(1<<ISC11) | (0<<ISC10) | (0<<ISC01) | (0<<ISC00);
GIFR=(1<<INTF1) | (0<<INTF0);


// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 2000.000 kHz
// SPI Clock Phase: Cycle Start
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=(1<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (0<<SPR1) | (0<<SPR0);
SPSR=(0<<SPI2X);

// Clear the SPI interrupt flag
#asm
    in   r30,spsr
    in   r30,spdr
#endasm


// Global enable interrupts
#asm("sei")
 }

//Function to send and receive data for both master and slave
unsigned char SPI(unsigned char data)
{

    // Load data into the buffer
    SPDR = data;

    //Wait until transmission complete
    while(!(SPSR & (1<<SPIF) )); 

    SPSR = (1<<SPIF);      
    // Return received data
    return(SPDR);
}



/* CE is set to output */

#define NRF24L01_CE_OUT       DDRB  |= (1<<DDB1) ;
#define NRF24L01_CE_HIGH      PORTB |= (1<<DDB1) ;
#define NRF24L01_CE_LOW       PORTB &= ~(1<<DDB1);
#define NRF24L01_CSN_HIGH     PORTB |= (1<<DDB2) ;
#define NRF24L01_CSN_LOW      PORTB &= ~(1<<DDB2);

/**
 Read a register

 @param Reg Register to read

 @return Registry Value
*/
char NRF24L01_ReadReg(char Reg) {
    char Result;

    NRF24L01_CSN_LOW;
    SPI(Reg);
    Result = SPI(NOP);    // "NOP"  in here just roles as a dummy data byte  nothing more.
    NRF24L01_CSN_HIGH;

    return Result;
}

/**
 Returns the STATUS register and then modify a register

 @param Reg Register to change
 @param Value New value

 @return STATUS Register
*/
char NRF24L01_WriteReg(char Reg, char Value) {
    char Result;

    NRF24L01_CSN_LOW;
    Result = SPI(Reg);
    SPI(Value);
    NRF24L01_CSN_HIGH;

    return Result;
}

/**
 Returns the STATUS register and then read "n" registers

 @param Reg Register to read
 @param Buf Pointer to a buffer
 @param Size Buffer Size

 @return STATUS Register
*/
char NRF24L01_ReadRegBuf(char Reg, char *Buf, int Size) {
    int i;
    char Result;

    NRF24L01_CSN_LOW;
    Result = SPI(Reg);

    for (i = 0; i < Size; i++) {
        Buf[i] = SPI(NOP);
    }

    NRF24L01_CSN_HIGH;

    return Result;
}

/**
 Returns the STATUS register and then write "n" registers

 @param Reg Registers to change
 @param Buf Pointer to a buffer
 @param Size Buffer Size

 @return STATUS Register
*/
char NRF24L01_WriteRegBuf(char Reg, char *Buf, int Size) {
    int i;
    char Result;

    NRF24L01_CSN_LOW;
    Result = SPI(Reg);

    for (i = 0; i < Size; i++) {
        SPI(Buf[i]);
    }
    NRF24L01_CSN_HIGH;

    return Result;
}

/**
 Returns the STATUS register

 @return STATUS Register
*/
char NRF24L01_Get_Status(void) {
    char Result;

    NRF24L01_CSN_LOW;
    Result = SPI(NOP);
    NRF24L01_CSN_HIGH;

    return Result;
}

/**
 Returns the carrier signal in RX mode (high when detected)

 @return CD
*/
char NRF24L01_Get_CD(void) {
    return (NRF24L01_ReadReg(CD) & 1);
}

/**
 Select power mode

 @param Mode = _POWER_DOWN, _POWER_UP

 @see _POWER_DOWN
 @see _POWER_UP

*/
void NRF24L01_Set_Power(char Mode) {
    char Result;

    Result = NRF24L01_ReadReg(CONFIG) & 0b01111101; // Read Conf. Reg. AND Clear bit 1 (PWR_UP) and 7 (Reserved)
    NRF24L01_WriteReg(W_REGISTER | CONFIG, Result | Mode);
}

/**
 Select the radio channel

 @param CH = 0..125

*/
void NRF24L01_Set_CH(char CH) {
    NRF24L01_WriteReg(W_REGISTER | RF_CH, (CH & 0b01111111)); // Clear bit 8
}

/**
 Select Enhanced ShockBurst ON/OFF

 Disable this functionality to be compatible with nRF2401

 @param Mode = _ShockBurst_ON, _ShockBurst_OFF

 @see _ShockBurst_ON
 @see _ShockBurst_OFF

*/
void NRF24L01_Set_ShockBurst(char Mode) {
    NRF24L01_WriteReg(W_REGISTER | SETUP_RETR, Mode);
    NRF24L01_WriteReg(W_REGISTER | EN_AA, Mode);
}

/**
 Select the address width

 @param Width = 3..5
*/
void NRF24L01_Set_Address_Width(char Width) {
    NRF24L01_WriteReg(W_REGISTER | SETUP_AW, (Width - 2));  //  orginal was (Width & 3) -2)  but is incorrect
}

/**
 Select mode receiver or transmitter

 @param Device_Mode = _TX_MODE, _RX_MODE

 @see _TX_MODE
 @see _RX_MODE
*/
void NRF24L01_Set_Device_Mode(char Device_Mode) {
    char Result;

    Result = NRF24L01_ReadReg(CONFIG) & 0b01111110; // Read Conf. Reg. AND Clear bit 0 (PRIM_RX) and 7 (Reserved)
    NRF24L01_WriteReg(W_REGISTER | CONFIG, Result | Device_Mode);
}

/**
 Enables and configures the pipe receiving the data

 @param PipeNum Number of pipe
 @param Address Address
 @param AddressSize Address size
 @param PayloadSize Buffer size, data receiver

*/
void NRF24L01_Set_RX_Pipe(char PipeNum, char *Address, int AddressSize, char PayloadSize) {
    char Result;

    Result = NRF24L01_ReadReg(EN_RXADDR);
    NRF24L01_WriteReg(W_REGISTER | EN_RXADDR, Result | (1 << PipeNum));

    NRF24L01_WriteReg(W_REGISTER | (RX_PW_P0 + PipeNum), PayloadSize);
    NRF24L01_WriteRegBuf(W_REGISTER | (RX_ADDR_P0 + PipeNum), Address, AddressSize);
}

/**
 Disable all pipes
*/
void NRF24L01_Disable_All_Pipes(void) {
    NRF24L01_WriteReg(W_REGISTER | EN_RXADDR, 0);
}


/** Returns the STATUS register and then clear all interrupts
 *
 * @return STATUS Register
 */
char NRF24L01_Clear_Interrupts(void) {
    return NRF24L01_WriteReg(W_REGISTER | STATUS, _RX_DR | _TX_DS | _MAX_RT);
}

/**
 Sets the direction of transmission

 @param Address Address
 @param Size Address size 3..5

*/
void NRF24L01_Set_TX_Address(char *Address, int Size) {
    NRF24L01_WriteRegBuf(W_REGISTER | TX_ADDR, Address, Size);
}

/**
 Empty the transmit buffer

*/
void NRF24L01_Flush_TX(void) {
    NRF24L01_CSN_LOW;
    SPI(FLUSH_TX);
    NRF24L01_CSN_HIGH;
}

/**
 Empty the receive buffer
*/
void NRF24L01_Flush_RX(void) {
    NRF24L01_CSN_LOW;
    SPI(FLUSH_RX);
    NRF24L01_CSN_HIGH;
}

/**
 Initializes the device
 @param Device_Mode = _TX_MODE, _RX_MODE
 @param CH = 0..125
 @param DataRate = _1Mbps, _2Mbps
 @param Address Address
 @param Address_Width Width direction: 3..5
 @param Size_Payload Data buffer size

 @see _TX_MODE
 @see _RX_MODE
 @see _1Mbps
 @see _2Mbps
*/
void NRF24L01_Init(char Device_Mode, char CH, char DataRate,
        char *Address, char Address_Width, char Size_Payload) {

    NRF24L01_CE_OUT; // Set Port DIR out

    // Enable Enhanced ShockBurst....._ShockBurst_OFF
    NRF24L01_Set_ShockBurst(_ShockBurst_ON);

    // RF output power in TX mode = 0dBm (Max.)
    // Set LNA gain
    NRF24L01_WriteReg(W_REGISTER | RF_SETUP, 0b00000111 | DataRate);

    NRF24L01_Set_Address_Width(Address_Width);

    NRF24L01_Set_RX_Pipe(0, Address, Address_Width, Size_Payload);

    NRF24L01_Set_CH(CH);

    NRF24L01_Set_TX_Address(Address, Address_Width); // Set Transmit address

    // Bits 4..6: Reflect interrupts as active low on the IRQ pin
    // Bit 3: Enable CRC
    // Bit 2: CRC 1 Byte
    // Bit 1: Power Up
    NRF24L01_WriteReg(W_REGISTER | CONFIG, 0b00001010 | Device_Mode);

    delay_us(1500);
}

/**
 Turn on transmitter, and transmits the data loaded into the buffer
*/
void NRF24L01_RF_TX(void) {
    NRF24L01_CE_LOW;
    NRF24L01_CE_HIGH;
    delay_us(10);
    NRF24L01_CE_LOW;
}

/**
 Writes the buffer of data transmission

 @param Buf Buffer with data to send
 @param Size Buffer size

*/
void NRF24L01_Write_TX_Buf(char *Buf, int Size) {
    NRF24L01_WriteRegBuf(W_REGISTER | W_TX_PAYLOAD, Buf, Size);
}

/**
 Read the data reception buffer

 @param Buf Buffer with data received
 @param Size Buffer size

*/
void NRF24L01_Read_RX_Buf(char *Buf, int Size) {
    NRF24L01_ReadRegBuf(R_RX_PAYLOAD, Buf, Size);
}

не могу понять в чем проблема..
пожалуйста, помогите мне спасибо?!

А вот nrf24l01+.H определение

/*
 * @author
 * Copyright (C) 2012 Luis R. Hilario http://www.luisdigital.com
 *
 */

// Bits

/**
 * Data Ready RX FIFO interrupt
 */
#define _RX_DR (1<<6)

/**
 * Data Sent TX FIFO interrupt
 */
#define _TX_DS (1<<5)

/**
 * Maximum number of TX retransmits interrupt
 */
#define _MAX_RT (1<<4)

/** Power Down mode
 *
 * Minimal current consumption, SPI can be activated
 *
 * @see NRF24L01_Set_Power(char Mode)
 */
#define _POWER_DOWN    0

/** Power Up mode
 *
 * Standby-I mode
 *
 * @see NRF24L01_Set_Power(char Mode)
 */
#define _POWER_UP    (1<<1)

/** Mode radio transmitter
 *
 * @see NRF24L01_Set_Device_Mode(char Device_Mode)
 * @see NRF24L01_Init(char Device_Mode, char CH, char DataRate,
        char *Address, char Address_Width, char Size_Payload)
 */
#define _TX_MODE    0

/** Mode radio receiver
 *
 * @see NRF24L01_Set_Device_Mode(char Device_Mode)
 * @see NRF24L01_Init(char Device_Mode, char CH, char DataRate,
        char *Address, char Address_Width, char Size_Payload)
 */
#define _RX_MODE    1

/**  Air data rate = 1 Mbps
 *
 *
 * @see NRF24L01_Init(char Device_Mode, char CH, char DataRate,
        char *Address, char Address_Width, char Size_Payload)
 */
#define    _1Mbps    0

/** Air data rate = 2 Mbps
 *
 * @see NRF24L01_Init(char Device_Mode, char CH, char DataRate,
        char *Address, char Address_Width, char Size_Payload)
 */
#define    _2Mbps    (1<<3)

/** Enable ShockBurst

 Automatic Retransmission (Up to 1 Re-Transmit on fail of AA)

 Auto Acknowledgment (data pipe 0)

 @see NRF24L01_Set_ShockBurst(char Mode)
 */
#define _ShockBurst_ON 1

/** Disable ShockBurst
 *
 @see NRF24L01_Set_ShockBurst(char Mode)
 */
#define _ShockBurst_OFF 0


// REGISTERS
#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 CD            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 DYNPD        0x1C
#define FEATURE        0x1D

// COMMANDS
#define R_REGISTER            0x00
#define W_REGISTER            0x20
#define R_RX_PAYLOAD        0x61
#define W_TX_PAYLOAD        0xA0
#define FLUSH_TX              0xE1
#define FLUSH_RX             0xE2
#define REUSE_TX_PL          0xE3
#define ACTIVATE            0x50
#define R_RX_PL_WID         0x60
#define W_ACK_PAYLOAD        0xA8
#define W_TX_PAYLOAD_NOACK    0x58
#define NOP                 0xFF

/*
 * SPI functions for NRF24L01
 */
char NRF24L01_ReadReg(char Reg);
char NRF24L01_WriteReg(char Reg, char Value);
char NRF24L01_ReadRegBuf(char Reg, char *Buf, int Size);
char NRF24L01_WriteRegBuf(char Reg, char *Buf, int Size);

/*
 * NRF24L01 functions
 */
char NRF24L01_Get_Status(void);
char NRF24L01_Get_CD(void);
void NRF24L01_Set_Power(char Mode);
void NRF24L01_Set_CH(char CH);
void NRF24L01_Set_ShockBurst(char Mode);
void NRF24L01_Set_Address_Width(char Width);
void NRF24L01_Set_Device_Mode(char Device_Mode);
void NRF24L01_Set_RX_Pipe(char PipeNum, char *Address, int AddressSize, char PayloadSize);
void NRF24L01_Disable_All_Pipes(void);
char NRF24L01_Clear_Interrupts(void);
void NRF24L01_Set_TX_Address(char *Address, int Size);
void NRF24L01_Flush_TX(void);
void NRF24L01_Flush_RX(void);
void NRF24L01_Init(char Device_Mode, char CH, char DataRate,
        char *Address, char Address_Width, char Size_Payload);
void NRF24L01_RF_TX(void);
void NRF24L01_Write_TX_Buf(char *Buf, int Size);
void NRF24L01_Read_RX_Buf(char *Buf, int Size);

1 ответ

  1. привет друзья успешно я получил его, и я был в состоянии отправить данные по модулю nrf24l01+ к другому модулю NRF24L01+ для этого я использовал ATMEGA16A в качестве TX и ATmega8a в качестве контроллера RX (приемник) :
    я использовал код в этой ссылке, написанный некоторыми хорошими людьми, и он работает отлично, но мне нужно изменить порт ввода-вывода som, чтобы быть совместимым с Atmega8 для модуля receiver .
    когда я сравниваю свой последний код с этим, я понимаю, что я изменил адреса rx и tx, и в этом коде (хорошо работает) ничего не меняется, связанное с адресами модуля и оставленное к его значениям по умолчанию..
    так что моей ошибкой было неправильное манипулирование адресами..

    вот ссылка на код работает хорошо..

    UPDATE: поскольку я пересмотрел свой код, чтобы увидеть, что проблема, я понимаю, что вся проблема была из nrf24l01.H файл, который объявил функцию misdingushly он отправляет W_tx_payload ORing с W_REGISTER в то время как такой адрес не существует в nrf, так что весь процесс получил неправильно..
    ошибка в объявлении :
    Функция ‘NRF24L01_Write_TX_Buf’
    в очереди:
    NRF24L01_WriteRegBuf(W_REGISTER | W_TX_PAYLOAD, Buf, Size);
    пока это неправильно и должно быть исправлено как:

    NRF24L01_WriteRegBuf(W_TX_PAYLOAD, Buf, Size);
    wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

    http://www.avrfreaks.net/forum/nrf24l01-problem-communication-failure-cannot-even-read-registers-data-atmega16a