⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nrf24l01.c

📁 AVR Mega88 + nRF24L01 wireless 2.4GHz >> Driver nRF24L01 >> AVRSTUDIO project
💻 C
字号:
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/signal.h>

#include "delay.h"
#include "myDef.h"
#include "uart.h"
#include "nrf24l01.h"

unsigned char SPI_Send_command_with_ADDR (unsigned char cmd, unsigned char addr, unsigned char data_byte)
{
    unsigned char temp,command = 0;
    unsigned char j, k;
    command = (cmd << 5) | addr;
    CSN_LOW();
    if (cmd == R_REGISTER)
    {
        if (addr == RX_ADDR_P0 || addr == RX_ADDR_P1 || addr == TX_ADDR)
        {

            status = SPI_SendByte(command);
            for (k = 0; k < 5; k++)
            {
                ADDRESS[k] = SPI_SendByte(NRF_NOP);
            }
            CSN_HIGH();
            return status;
        }
        else
        {
            status = SPI_SendByte(command);
            temp = SPI_SendByte(NRF_NOP);
            CSN_HIGH();
            return temp;
        }
    }
    if (cmd == W_REGISTER)
    {
        if (addr == RX_ADDR_P0)
        {
            status = SPI_SendByte(command);
            for (j = 0; j < 5; j++)
            {
                temp = RX_ADDRESS_P0[j];
                SPI_SendByte(temp);
            }
            CSN_HIGH();
            return status;
        }

        if (addr == RX_ADDR_P1)
        {
            status = SPI_SendByte(command);
            for (j = 0; j < 5;j++)
            {
                temp = RX_ADDRESS_P1[j];
                SPI_SendByte(temp);
            }
            CSN_HIGH();
            return status;
        }

        if (addr == TX_ADDR)
        {
            status = SPI_SendByte(command);
            for (j = 0; j < 5;j++)
            {
                temp = TX_ADDRESS[j];
                SPI_SendByte(temp);
            }
            CSN_HIGH();
            return status;
        }
        else
        {
            temp = SPI_SendByte(command);
            SPI_SendByte(data_byte);
            CSN_HIGH();
            return temp;
        }
    }
    return 1;
}

unsigned char SPI_SendByte(unsigned char DataIn)
{        
    // Start transmission
    SPDR = DataIn;      
                 
    // Wait for transmission complete
    while (!(SPSR & (1<<SPIF)))   
        ;

    return SPDR;
}

void SPI_MasterInit(void)
{
    // Set MOSI, SCK and ENB output, all other input
    DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK)|(1<<DD_SS)|(1<<DD_SIGNAL);

    // Enable SPI, Master, set clock rate fck/64 
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

unsigned char SPI_Send_command_without_ADDR (unsigned char cmd, unsigned char data_byte)
{
    unsigned char temp = 0;
    CSN_LOW();
    if (cmd == R_RX_PAYLOAD)
    {
        status = SPI_SendByte(cmd);
        temp = SPI_SendByte(NRF_NOP);
        CSN_HIGH();
        return temp;
    }
    if (cmd == W_TX_PAYLOAD)
    {
        status = SPI_SendByte(cmd);
        SPI_SendByte(data_byte);
        CSN_HIGH();
        return status;
    }
    status = SPI_SendByte(cmd);
    CSN_HIGH();
    return status;

}


void NRF_init (void)
{
    CE_LOW();
    delay_us(10);
    CSN_HIGH();

    ///////////////////////////
    // Configure chip nRF24L01
    ///////////////////////////

    // Discard transmission


    //Write CONFIG register (addres - 0x00)

    usart_puts("\n\r ** NRF_init **  \n\r"); 
    status = SPI_Send_command_with_ADDR(W_REGISTER, CONFIG_REG_ADDR, 0x0B);
    usart_SendBcd(status);
    //Write RX_ADDR_P0 register -> Set receive address data Pipe0 -> address in RX_ADDRESS_P0 array
    status = SPI_Send_command_with_ADDR(W_REGISTER, RX_ADDR_P0, NRF_NOP);
    usart_SendBcd(status);
    //Write RX_ADDR_P1 register -> Set receive address data Pipe1 -> address in RX_ADDRESS_P1 array
    status = SPI_Send_command_with_ADDR(W_REGISTER, RX_ADDR_P1, NRF_NOP);
    usart_SendBcd(status);
    //Write TX_ADDR register -> Transmit address. Used for a PTX device only. Address in TX_ADDRESS array
    status = SPI_Send_command_with_ADDR(W_REGISTER, TX_ADDR, NRF_NOP);
    usart_SendBcd(status);
    //Write RX_PW_P0 register -> Set number of bytes in RX payload in data pipe0 -> 1 byte
    status = SPI_Send_command_with_ADDR(W_REGISTER, RX_PW_P0, 1);
    usart_SendBcd(status);
    //Write RX_PW_P1 register -> Set number of bytes in RX payload in data pipe1 -> 1 byte
    status = SPI_Send_command_with_ADDR(W_REGISTER, RX_PW_P1, 1);
    usart_SendBcd(status);

    usart_puts("\n\r");
    
    NRF_prepareForReceive ();
}




/**
 * Send one byte to the air via chip nRF24L01.
 * Addresses are hardcoded:
 * @see RX_ADDRESS_P0 RX_ADDRESS_P1 TX_ADDRESS
 *
 * @param byte The data byte to send.
 */
void NRF_send (unsigned char dataIn)
{
    //unsigned char status_temp;

    // Chip enable low
//    printf(bputc," Test Send ");
    CE_LOW();

    // Setting for TX device
    // Write CONFIG register -> 00001010 - CRC enable, power-up, TX
    status = SPI_Send_command_with_ADDR (W_REGISTER,CONFIG_REG_ADDR, 0x0A);
    //printf(bputc,"%2X",status);

    // Send payload - send any data
    status = SPI_Send_command_without_ADDR (W_TX_PAYLOAD, dataIn);
    //printf(bputc,"%2X",status);

    // Pulse for CE -> starts the transmission.
    CE_HIGH();
    CE_LOW();

    // Read STATUS register
    status = SPI_Send_command_without_ADDR(NRF_NOP, NRF_NOP);
    //printf(bputc,"%2X",status);

    // if exceed number of transmision packets
    if ((status & MAX_RT) != 0) 
    {

        // Clear MAX_RT bit in status register
        status_temp = SPI_Send_command_with_ADDR(W_REGISTER, STATUS_ADDR, (status|MAX_RT));
        //printf(bputc,"%2X",status_temp);

        // No communication event here
//        LCD_printf ("MAX_RT\n");

        // Flush TX FIFO (in TX mode)
        status_temp = SPI_Send_command_without_ADDR(FLUSH_TX, NRF_NOP); // XXX test code
        //printf(bputc,"%2X",status_temp);
    }

    // If packet sent on TX
    if ((status & TX_DS) != 0) 
    {
        // Clear TX_DS bit in status register
        status_temp = SPI_Send_command_with_ADDR(W_REGISTER, STATUS_ADDR, (status|TX_DS));
        //printf(bputc,"%2X",status_temp);

        // Your code here
        //LCD_printf ("TX_DS\n");
    }

    // If TX full
    if ((status & TX_FULL) != 0)
    {
        // Flush TX FIFO (in TX mode)
        status_temp = SPI_Send_command_without_ADDR(FLUSH_TX, NRF_NOP);
        //printf(bputc,"%2X",status_temp);

        // Your code here
        // ...
        //LCD_printf ("TX_FULL\n");
    }

}




/**
 * After sending a byte you may set the device to RX mode.
 */
void NRF_prepareForReceive (void)
{
    // Setting for RX device
    //Write CONFIG register -> 00001010 - CRC enable, power-up, RX
    status = SPI_Send_command_with_ADDR(W_REGISTER,CONFIG_REG_ADDR, 0x0B);
    //printf(bputc," \n\r prepare for recieve %2X",status);
  
}

/**
 * Receive one byte from the air via chip nRF24L01. 
 * Addresses are hardcoded:
 * @see RX_ADDRESS_P0 RX_ADDRESS_P1 TX_ADDRESS
 *
 * @param byte The data byte to receive.
 * @return TRUE: if byte succesfully received.
 *         FALSE: if no input data.
 */
unsigned char NRF_receive (unsigned char * dataIn)
{
    //unsigned char payload;
    //unsigned char status_temp;

    CE_HIGH ();
    if ( ((PORTB & 0b00000010)==0b00000000)) // check interrupt line of nRF24L01...
    {
        // Read STATUS status register
        status = SPI_Send_command_without_ADDR(NRF_NOP, NRF_NOP);
        // Set high when new data arrives RX FIFO
        if ((status & RX_DR) != 0)
        {
            // Chip enable low
            CE_LOW();

            //Read payload data
            payload = SPI_Send_command_without_ADDR(R_RX_PAYLOAD, NRF_NOP);
            usart_putc(payload);
            // Clear RX_DR bit in status register
            status_temp = SPI_Send_command_with_ADDR(W_REGISTER, STATUS_ADDR, (status|RX_DR));
            // Flush RX FIFO
            status_temp = SPI_Send_command_without_ADDR(FLUSH_RX, NRF_NOP); // XXX test code
            return TRUE;
        }
    }
    return FALSE;
}

unsigned char check_recieve_nrf24L01(void)
{
     CE_HIGH ();
	 if ( !chkbit(PIND,5) ) // check interrupt line of nRF24L01...
     {
	    sbi(PORTB,0);
		do{
        	status = SPI_Send_command_without_ADDR(NRF_NOP, NRF_NOP);
        	if ((status & RX_DR) != 0)
        	{
            	CE_LOW();
            	payload = SPI_Send_command_without_ADDR(R_RX_PAYLOAD, NRF_NOP);
            	usart_putc(payload);
            	status_temp = SPI_Send_command_with_ADDR(W_REGISTER, STATUS_ADDR, (status|RX_DR));
			}
            status_temp = SPI_Send_command_without_ADDR(FLUSH_RX, NRF_NOP); // XXX test code           
        }while( !chkbit(PIND,5) );
	    cbi(PORTB,0);       

        NRF_prepareForReceive ();

		return TRUE;
     }

	 return FALSE;
}	


void CSN_HIGH(void)
{
	sbi(nRF24L01_PORT,nRF24L01_CSN);
}

void CSN_LOW (void)
{ 
    delay_us(CSN_TIME);
	cbi(nRF24L01_PORT,nRF24L01_CSN);
}

void CE_HIGH(void)
{ 
	sbi(nRF24L01_PORT,nRF24L01_CE);
    delay_us(CE_HIGH_TIME); 
}

void CE_LOW(void)
{
	cbi(nRF24L01_PORT,nRF24L01_CE);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -