PIC18F4520 + NRF24L01
阅读原文时间:2023年07月15日阅读:1

SI SO应该对调过来用。。

TX

/*
** Tx.c
** Transmit test program for PIC18F4520 and nRF24L01 or nRF24L01+
** Uses the Microchip C18 compiler
** Based on SFE code for the CC5X compiler in 24L01demo_V01.c
*/

#include
#include
#include

// Pragmas
#pragma config OSC = INTIO67
#pragma config PWRT = ON
//#pragma config MCLRE = OFF
#pragma config BOREN = OFF

//function prototypes
void init(void);
void transmit_data(void);
void configure_transmitter(void);
unsigned char spi_Send_Read(unsigned char);
unsigned char spi1_send_read_byte(unsigned char byte);
void dly(unsigned int);

// Defines
#define SPI_SCK LATCbits.LATC3 // Clock pin, PORTC pin 3
#define SPI_SO LATCbits.LATC5 // Serial output pin, PORTC pin 5
#define SPI_SI PORTCbits.RC4 // Serial input pin, PORTC pin 4
#define SPI_CSN LATCbits.LATC2 // CSN output pin, PORTC pin 2
#define SPI_CE LATCbits.LATC1 // CE output pin, PORTC pin 1
#define SPI_IRQ PORTBbits.RB0 // IRQ input pin, PORTB pin 0
#define SPI_SCALE 4 // postscaling of signal
#define LED LATDbits.LATD1
#define PB PORTAbits.RA1

// Macros
#define nop() _asm nop _endasm

void main(void)
{
init();
configure_transmitter();
while (1)
{
transmit_data();
LED = 1;
dly(63973); //200 ms delay
LED = 0;
dly(40000); //3.27 s delay
nop();
}
}

void init(void)
{
// run internal oscillator at 8 MHz
OSCCON = OSCCON | 0x70;
while (OSCCONbits.IOFS == 0)
;
PORTA = 0x00;
PORTD = 0X00;
ADCON1 = 0x0F; // set up PORTA to be digital I/Os
TRISA = 0x02; // PORTA<7.2,0> outputs PORTA<1> input
TRISD = 0XFD;
TRISCbits.TRISC3 = 0; // SDO output
TRISCbits.TRISC4 = 1;
TRISCbits.TRISC5 = 0; // SCK output
TRISCbits.TRISC2 = 0; // CSN output
TRISCbits.TRISC1 = 0; // CE output
TRISBbits.TRISB0 = 1; // IRQ input
OpenSPI(SPI_FOSC_16, MODE_00, SMPMID); //open SPI1
OpenTimer0( TIMER_INT_OFF &
T0_16BIT &
T0_SOURCE_INT &
T0_PS_1_256 );
}

void configure_transmitter(void)
{
unsigned char i, j, data, cmd;

SPI\_CE = 0;  
SPI\_CSN = 0;

// PTX, CRC enabled, mask a couple of ints  
 spi\_Send\_Read(0x20);  
  spi\_Send\_Read(0x38);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//auto retransmit off  
 spi\_Send\_Read(0x24);  
   spi\_Send\_Read(0x00);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//address width = 5  
   spi\_Send\_Read(0x23);  
 spi\_Send\_Read(0x03);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//data rate = 1MB  
   spi\_Send\_Read(0x26);  
 spi\_Send\_Read(0x07);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//set channel 2, this is default but we did it anyway...  
   spi\_Send\_Read(0x25);  
 spi\_Send\_Read(0x02);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//set address E7E7E7E7E7, also default...  
   spi\_Send\_Read(0x30);  
for (j = 0; j < 5; j++)  
{  
    spi\_Send\_Read(0xE7);  
}  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//disable auto-ack, RX mode  
//shouldn't have to do this, but it won't TX if you don't  
   spi\_Send\_Read(0x21);  
 spi\_Send\_Read(0x00);  
SPI\_CSN = 1;  

}

void transmit_data(void)
{
unsigned char i, data, cmd;

SPI\_CSN = 0;

//clear previous ints  
  spi\_Send\_Read(0x27);  
 spi\_Send\_Read(0x7E);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//PWR\_UP = 1  
   spi\_Send\_Read(0x20);  
 spi\_Send\_Read(0x3A);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//clear TX fifo  
//the data sheet says that this is supposed to come up 0 after POR, but that doesn't seem to be the case  
   spi\_Send\_Read(0xE1);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//4 byte payload  
   spi\_Send\_Read(0xA0);  
   spi\_Send\_Read(0x34);  
  spi\_Send\_Read(0x33);  
   spi\_Send\_Read(0x32);  
  spi\_Send\_Read(0x31);  
SPI\_CSN = 1;

//Pulse CE to start transmission  
SPI\_CE = 1;  
dly(65000);            //delay 69 ms  
SPI\_CE = 0;  

}

unsigned char spi_Send_Read(unsigned char byte)
{
SSPBUF = byte;
while(!DataRdySPI())
;
return SSPBUF;
}

void dly(unsigned int c)
{
INTCONbits.TMR0IF = 0;
WriteTimer0(c);
while (INTCONbits.TMR0IF == 0)
;
}

RX

/*
** Rx.c
** Receive test program for PIC18F4520 and nRF24L01 or nRF24L01+
** Uses the Microchip C18 compiler
** Based on SFE code for the CC5X compiler in 24L01demo_V01.c
**
** The LED is flashed five times when data are received.
** The received data in the buffer may be checked using the
** debugger Watch window.*/

#include
#include
#include

// Pragmas
#pragma config OSC = INTIO67
#pragma config PWRT = ON
#pragma config MCLRE = OFF
#pragma config BOREN = OFF

//function prototypes
void init(void);
void reset_RX(void);
void configure_RX(void);
unsigned char spi_Send_Read(unsigned char);
void dly(unsigned int);

// Defines
#define SPI_SCK LATCbits.LATC3 // Clock pin, PORTC pin 3
#define SPI_SO LATCbits.LATC5 // Serial output pin, PORTC pin 5
#define SPI_SI PORTCbits.RC4 // Serial input pin, PORTC pin 4
#define SPI_CSN LATCbits.LATC2 // CSN output pin, PORTC pin 2
#define SPI_CE LATCbits.LATC1 // CE output pin, PORTC pin 1
#define SPI_IRQ PORTBbits.RB0 // IRQ input pin, PORTB pin 0
#define SPI_SCALE 4 // postscaling of signal
#define LED LATDbits.LATD1
#define PB PORTAbits.RA1

// Macros
#define nop() _asm nop _endasm

void main(void)
{
unsigned char i;

init();  
configure\_RX();  
while(1)  
{  
       if (SPI\_IRQ == 0)    //wait for anything  
    {  
        for (i = 0; i < 5; i++)  //flash LED 5 times if data received  
        {  
            LED = 1;  
            dly(63973);        // 200 ms delay  
            LED = 0;  
            dly(63973);        // 196 ms  
        }  
        dly(63973);            // 196 ms  
        reset\_RX();  
    }  
}  

}

// initialise 18F4520
void init(void)
{
// run internal oscillator at 8 MHz
OSCCON = OSCCON | 0x70;
while (OSCCONbits.IOFS == 0)
;

PORTA = 0x00;  
PORTD = 0X00;  
ADCON1 = 0x0F;      // set up PORTA to be digital I/Os  
TRISA = 0x02;       // PORTA<7.2,0> outputs PORTA<1> input  
TRISD = 0XFD;  
TRISCbits.TRISC3 = 0;   // SDO output  
TRISCbits.TRISC4 = 1;  
TRISCbits.TRISC5 = 0;   // SCK output  
TRISCbits.TRISC2 = 0;   // CSN output  
TRISCbits.TRISC1 = 0;   // CE output  
TRISBbits.TRISB0 = 1;   // IRQ input  
OpenSPI(SPI\_FOSC\_16, MODE\_00, SMPMID); //open SPI1  
OpenTimer0( TIMER\_INT\_OFF &  
            T0\_16BIT &  
            T0\_SOURCE\_INT &  
            T0\_PS\_1\_256 );  

}

//configure nRF24L01 for receive
void configure_RX(void)
{
unsigned char i, j;

SPI\_CSN = 0;  
SPI\_CE = 0;

//PRX, CRC enabled  
spi\_Send\_Read(0x20);  
spi\_Send\_Read(0x39);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//disable auto-ack for all channels  
spi\_Send\_Read(0x21);  
spi\_Send\_Read(0x00);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//address width = 5 bytes  
  spi\_Send\_Read(0x23);  
spi\_Send\_Read(0x03);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//data rate = 1MB  
  spi\_Send\_Read(0x26);  
spi\_Send\_Read(0x07);  
SPI\_CSN = 1;  
  SPI\_CSN = 0;

//4 byte payload  
 spi\_Send\_Read(0x31);  
spi\_Send\_Read(0x04);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//set channel 2  
   spi\_Send\_Read(0x25);  
spi\_Send\_Read(0x02);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//set address E7E7E7E7E7  
spi\_Send\_Read(0x30);  
for (j = 0; j < 5; j++)  
     spi\_Send\_Read(0xE7);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//PWR\_UP = 1  
 spi\_Send\_Read(0x20);  
spi\_Send\_Read(0x3B);  
SPI\_CSN = 1;  
SPI\_CE = 1;  

}

void reset_RX(void)
{
unsigned char i, j;
unsigned char buffer[4];

//Read RX payload  
SPI\_CSN = 0;  
   spi\_Send\_Read(0x61);  
for (j = 0; j < 4; j++)  
{  
       buffer\[j\] = spi\_Send\_Read(0);  
}  
SPI\_CSN = 1;    

//Flush RX FIFO  
SPI\_CSN = 0;  
 spi\_Send\_Read(0xE2);  
SPI\_CSN = 1;  
SPI\_CSN = 0;

//reset int  
  spi\_Send\_Read(0x27);  
spi\_Send\_Read(0x40);  
SPI\_CSN = 1;  

}

unsigned char spi_Send_Read(unsigned char byte)
{
SSPBUF = byte;
while(!DataRdySPI())
;
return SSPBUF;
}

void dly(unsigned int c)
{
INTCONbits.TMR0IF = 0;
WriteTimer0(c);
while (INTCONbits.TMR0IF == 0)
;

}

用PICKIT3 DEBUGER 看SSPBUF 来test addr

/*
** test.c
** SPI test program for PIC18F4520 and nRF24L01 or nRF24L01+
** Checks SPI comms between PIC and wireless chip
**
** RA0 LED (output)
** RA1 PB (input)
*/

#include
#include

//function prototypes
unsigned char spi_Send_Read(unsigned char);

// Defines
#define SPI_SCK LATCbits.LATC3 // Clock pin, PORTC pin 3
#define SPI_SO LATCbits.LATC5 // Serial output pin, PORTC pin 5
#define SPI_SI PORTCbits.RC4 // Serial input pin, PORTC pin 4
#define SPI_CSN LATCbits.LATC2 // CSN output pin, PORTC pin 2
#define SPI_CE LATCbits.LATC1 // CE output pin, PORTC pin 1
#define SPI_IRQ PORTBbits.RB0 // IRQ input pin, PORTB pin 0
#define SPI_SCALE 4 // postscaling of signal
#define LED LATAbits.LATA0
#define PB PORTAbits.RA1

// Macros
#define nop() _asm nop _endasm

void main(void)
{
unsigned char status = 0;
unsigned char data[5];
int i;

// run internal oscillator at 8 MHz  
OSCCON = OSCCON | 0x70;  
while (OSCCONbits.IOFS == 0)  
    ;

OpenSPI(SPI\_FOSC\_16, MODE\_00, SMPMID); //open SPI1  
PORTA = 0x00;  
ADCON1 = 0x0F;      // set up PORTA to be digital I/Os  
TRISA = 0x02;       // PORTA<7.2,0> outputs PORTA<1> input  
TRISCbits.TRISC3 = 0;   // SDO output  
TRISCbits.TRISC5 = 0;   // SCK output  
TRISCbits.TRISC4 =1;  
TRISCbits.TRISC2 = 0;   // CSN output  
TRISCbits.TRISC1 = 0;   // CE output  
SPI\_CSN = 1;       // CSN high  
SPI\_SCK = 0;       // SCK low  
SPI\_CE = 0;        // CE low  
nop();

//write TX\_ADDRESS register  
SPI\_CSN = 0;           //CSN low  
spi\_Send\_Read(0x30);  
spi\_Send\_Read(0x11);  
spi\_Send\_Read(0x22);  
spi\_Send\_Read(0x33);  
spi\_Send\_Read(0x44);  
spi\_Send\_Read(0x55);  
SPI\_CSN = 1;           //CSN high

//read TX\_ADDRESS register  
//Check that values are correct using the MPLAB debugger  
SPI\_CSN = 0;           //CSN low  
status = spi\_Send\_Read(0x10);  
data\[0\] = spi\_Send\_Read(0x00);  // 0x11  
data\[1\] = spi\_Send\_Read(0x00);  // 0x22  
data\[2\] = spi\_Send\_Read(0x00);  // 0x33  
data\[3\] = spi\_Send\_Read(0x00);  // 0x44  
data\[4\] = spi\_Send\_Read(0x00);  // 0x55  
SPI\_CSN = 1;           //CSN high

// test PB and LED  
while(1)  
{  
    if (!PB)  
        LED = 1;  
    else  
        LED = 0;  
}  

}

unsigned char spi_Send_Read(unsigned char byte)
{
SSPBUF = byte;
while(!DataRdySPI())
;
return SSPBUF;
}