nRF24L01 - Issue with SPI and config for PIC24F16KA102

Discussion on projects that are created by users and posted on mikroElektronika website.
Post Reply
Author
Message
pedraos
Posts: 13
Joined: 20 Aug 2011 01:29

nRF24L01 - Issue with SPI and config for PIC24F16KA102

#1 Post by pedraos » 06 Sep 2017 21:04

Hi,

I have downloaded from Mikroelektronika-libstock the project of "Allen Mulvey", thanks for showing how to setup this in easy way using a LCD 16x2. But that project is for the PIC16.

Since I bought the "Easy24-33 v6 board" and "EasyPIC Fusion v7 board" and their respective MiKROC Compilers I have been working with PIC24F16KA102 and PIC32MX795F512L; where you are going to find that main difference are configuration of the registers and some changes of the code.

For instance:

Meanwhile in PIC16 or mikroC Pro for PIC you set the pins:
sbit Irq_pin at PORTB.B0; sfr;

in mikroC Pro for dsPIC you set:
sbit Irq_pin at LATB14_bit; sfr;

(Pin configuration of PIC16 according to original project of Allen, pin configuration for PIC24F16KA102, selected by me) [project of PIC24 using HS+PLL, primary HS oscillator mode selected, and project set to 32MHz]

Another piece of code:
CMCON = 7; // Comparators off in PIC16

CM1CONbits.CON = 0; // Comparator 1 off in PIC24
//CM1CONbits.CREF = x; // not clear in data sheet
//CM1CONbits.CCH = xx; // not clear in data sheet
CM2CONbits.CON = 0; // Comparator 2 off in PIC24
//CM2CONbits.CREF = x; // not clear in data sheet
//CM2CONbits.CCH = xx; // not clear in data sheet

ADCON1 = 0x04; // digital not analog in PIC16
AD1PCFG = 0xFFFF; // digital not analog in PIC24

Those 3 parts were the only ones that I found in error after compile the project. After change those I got “Project Linked Successfully” finished without any error.

However when I test in the circuit, there is not communication between the two nRF24L01 modules.

There is an interesting phrase of Allen, where he says:

“June 30, 2014
The code as posted seems to work well at oscillator speeds up to 20 MHZ. Today I attempted to run it on a PIC18F46K22 at 32 MHX (8 MHZ x 4). I had to use the advanced SPI initialization to accomodate the faster clock. This is what I used: SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);

where if I change to:

//SPI1_Init();
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
I got erros, because SPI advance options change to MikroC DsPIC.

So, my set was:

SPI1_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_6, _SPI_PRESCALE_PRI_4, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_IDLE_2_ACTIVE);

After testing, I only got the display of the LCD without the message of testing “Test Message”.

According to your experience, what could be the problem?,

Do yo see any error in the code??

Code: Select all

/*================================================================================
*
*   nRF24L01+ using no libraries
*   PIC16F877A migration to PIC24F16KA102
*
*   Allen Mulvey May 2014 original file modified
*
*   Pull up resistors on PORTC pins 1-5  <= apparently not necessary
*
================================================================================*/

#define TX_mode                  // define TX_mode or RX_mode
//#define chn 83
#include "nRF24L01.h"

const char test[] = "Hi nRF24L01";

// Pipe Addresses
// adr0 should be unique
// adr1 through adr5 must differ only in the lowest significant byte
// Bytes are arranged lowest to highest
const char adr0[] = {0x78,0x78,0x78,0x78,0x78};    // LSB first
const char adr1[] = {0xf1,0xb4,0xb5,0xb6,0xb3};
const char adr2[] = {0xb3,0xb4,0xb5,0xb6,0xb3};
const char adr3[] = {0x83,0xb4,0xb5,0xb6,0xb3};
const char adr4[] = {0xcf,0xb4,0xb5,0xb6,0xb3};
const char adr5[] = {0x75,0xb4,0xb5,0xb6,0xb3};

char Data_In[21], Data_Out[21], stat;
short dataLength = 20;

// You can change these pins as long as your microcontroller supports SPI on the required pins
sbit Irq_pin   at LATB14_bit; sfr;
//sbit Mosi_pin  at LATB13_bit; sfr;
sbit Ce_pin    at LATB12_bit; sfr;
//sbit Sclk_pin  at LATB11_bit; sfr;
sbit Csn_pin   at LATB9_bit; sfr;
//sbit Miso_pin  at LATB10_bit; sfr;

sbit Irq_tris  at TRISB14_bit; sfr;
//sbit Mosi_tris at TRISB13_bit; sfr;
sbit Ce_tris   at TRISB12_bit; sfr;
//sbit Sclk_tris at TRISB11_bit; sfr;
sbit Csn_tris  at TRISB9_bit; sfr;
//sbit Miso_tris at TRISB10_bit; sfr;

// LCD module connections
sbit LCD_RS at LATA0_bit;
sbit LCD_EN at LATA1_bit;
sbit LCD_D4 at LATB3_bit;
sbit LCD_D5 at LATB4_bit;
sbit LCD_D6 at LATA4_bit;
sbit LCD_D7 at LATB5_bit;

sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB3_bit;
sbit LCD_D5_Direction at TRISB4_bit;
sbit LCD_D6_Direction at TRISA4_bit;
sbit LCD_D7_Direction at TRISB5_bit;
// End LCD module connections

// I use a procedure for any delay that is used more than once
void Comm_Delay() {Delay_us(10);}       // You can experiment with this delay
void Delay_10()   {Delay_ms(10);}
void Delay_100()  {Delay_ms(100);}
void Delay_500()  {Delay_ms(500);}

void Clear_Data(char dat[]){
     char i;
     for(i=0;i<dataLength;i++)dat[i] = ' ';
}

void toggleCSN(){
     Csn_pin = 1;
     Delay_us(20);                      // You can experiment with this delay
     Csn_pin = 0;
     Comm_Delay();
}

char Get_Status(){
     char s;
     Ce_pin = 0;
     toggleCSN();
     SPI1_Write(STATUS);
     Comm_Delay();
     s = SPI1_Read(NOP);
     Comm_Delay();
     Csn_pin = 1;
     return s;
}

char *getConst(char dest[], const char source[]){
    int i = 0;
    while (source[i])                  // while (source[i] != '\0')
    {dest[i] = source[i]; i++;}
    dest[i] = '\0';
    return dest;
}

char Get_FIFO_Flags(){
     char s;
     Ce_pin = 0;
     toggleCSN();
     SPI1_Write(FIFO_STATUS);
     Comm_Delay();
     s = SPI1_Read(NOP);
     Comm_Delay();
     Csn_pin = 1;
     return s;
}

void makeMsg(){                        // Put your data in here
     Clear_Data(Data_Out);
     getConst(Data_Out, test);
}

char readBuffer(){
     char i, s;
     Ce_pin = 0;
     Clear_Data(Data_In);
     s = Get_FIFO_Flags();
     if((s & 2) != 0){
         toggleCSN();
         SPI1_Write(R_RX_PAYLOAD);
         for(i=0; i < dataLength; i++){Comm_Delay(); Data_In[i] = SPI1_Read(0);}
         Comm_Delay();
     }
     Csn_pin = 1;
     Ce_pin = 1;
     return s;
}

void sendBuffer(){
     char i, j;
     do{
         toggleCSN();
         SPI1_Write(STATUS | W_REGISTER);
         Comm_Delay();
         SPI1_Write(0xff);            //clear flags
         Comm_Delay();
         toggleCSN();
         SPI1_Write(FLUSH_TX);
         Comm_Delay();
         toggleCSN();
         SPI1_Write(W_TX_PAYLOAD);
         for(i = 0; i < dataLength; i++) {Comm_Delay(); SPI1_Write(Data_Out[i]);}
         Comm_Delay();
         Csn_pin = 1;
         Ce_pin = 1;
         Delay_10();
         j = (Get_Status() & 0x20);                     // keep trying until ack is received
     }while(j==0);
}

char init_Radio(){
       char i;
       Ce_pin = 0;                                      // must be in standby or power down to write
       Comm_Delay();
       toggleCSN();
       SPI1_Write(CONFIG | W_REGISTER);
       Comm_Delay();

       #ifdef RX_mode
       SPI1_Write(PRIM_RX + PWR_UP + CRCO + EN_CRC);    // Receiver

       toggleCSN();
       SPI1_Write(EN_AA | W_REGISTER);
       Comm_Delay();
       SPI1_Write(ENAA_P0 + ENAA_P1 + ENAA_P2 + ENAA_P3 + ENAA_P4 + ENAA_P5);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(EN_RXADDR | W_REGISTER);
       Comm_Delay();
       SPI1_Write(ERX_P0 + ERX_P1 + ERX_P2 + ERX_P3 + ERX_P4 + ERX_P5);
       Comm_Delay();
       #endif

       #ifdef TX_mode
       SPI1_Write(PWR_UP + CRCO + EN_CRC);              // Transmitter
       Comm_Delay();

       toggleCSN();
       SPI1_Write(EN_AA | W_REGISTER);
       Comm_Delay();
       SPI1_Write(ENAA_P0);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(EN_RXADDR | W_REGISTER);
       Comm_Delay();
       SPI1_Write(ERX_P0);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_ADDR_P0 | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr0[i]);} // This is the pipe in use by this transmitter
       Comm_Delay();
                                                            // The addresses above and below must be the same
       toggleCSN();                                         // Choose any of the 6 addresses used by the receiver
       SPI1_Write(TX_ADDR | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr0[i]);} // This is the pipe in use by this transmitter
       Comm_Delay();
       #endif

       toggleCSN();
       SPI1_Write(SETUP_AW | W_REGISTER);
       Comm_Delay();
       SPI1_Write(AW5);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(SETUP_RETR | W_REGISTER);
       Comm_Delay();
       SPI1_Write(0xfaf);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RF_CH | W_REGISTER);
       Comm_Delay();
       SPI1_Write(83);                                      // Set your channel here. Obviously it must be the same for TX and RX.
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RF_SETUP | W_REGISTER);
       Comm_Delay();
       SPI1_Write(RF_PWR + LNA_HCURR);
       Comm_Delay();

       #ifdef RX_mode
       toggleCSN();
       SPI1_Write(RX_ADDR_P0 | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr0[i]);}
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_ADDR_P1 | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr1[i]);}
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_ADDR_P2 | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr2[i]);}
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_ADDR_P3 | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr3[i]);}
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_ADDR_P4 | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr4[i]);}
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_ADDR_P5 | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr5[i]);}
       Comm_Delay();

       toggleCSN();
       SPI1_Write(TX_ADDR | W_REGISTER);
       for(i=0;i<5;i++){Comm_Delay(); SPI1_Write(adr0[i]);}
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_PW_P1 | W_REGISTER);
       Comm_Delay();
       SPI1_Write(dataLength);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_PW_P2 | W_REGISTER);
       Comm_Delay();
       SPI1_Write(dataLength);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_PW_P3 | W_REGISTER);
       Comm_Delay();
       SPI1_Write(dataLength);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_PW_P4 | W_REGISTER);
       Comm_Delay();
       SPI1_Write(dataLength);
       Comm_Delay();

       toggleCSN();
       SPI1_Write(RX_PW_P5 | W_REGISTER);
       Comm_Delay();
       SPI1_Write(dataLength);
       Comm_Delay();
       #endif

       toggleCSN();
       SPI1_Write(RX_PW_P0 | W_REGISTER);
       Comm_Delay();
       SPI1_Write(dataLength);
       Comm_Delay();

       Csn_pin = 1;
       i = Get_Status();
       return i;
}

// =============================================================================
// =============================================================================

void main(){
       char txt[5], dat1;
       AD1PCFG = 0xFFFF;                           // digital not analog
       CM1CONbits.CON = 0;                               // Comparators off
       //CM1CONbits.CREF = ;
       //CM1CONbits.CCH = ;
       CM2CONbits.CON = 0;                               // Comparators off
       //CM2CONbits.CREF = ;
       //CM2CONbits.CCH = ;

       //PORTA = 0;
       //TRISA = 0;                               // outputs
       Csn_tris = 0;
       Csn_pin = 1;
       Ce_tris = 0;
       Ce_pin = 0;                              // 1 = listen or transmit

       //SPI1_Init();
       //SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);   //config for PIC16
       SPI1_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_6, _SPI_PRESCALE_PRI_4, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_IDLE_2_ACTIVE);
       
       Delay_ms(200);
       stat = init_Radio();

       #ifdef TX_mode
       Clear_Data(Data_Out);
       #endif

       Lcd_Init();                              // Initialize LCD
       Lcd_Cmd(_LCD_CLEAR);
       Lcd_Cmd(_LCD_CURSOR_OFF);
       Lcd_Out(1, 1, "nRF24L01+");
       ByteToHex(stat, txt);
       Lcd_Out(2, 1, txt);
       Delay_500();

       do {
           dat1 = 0;
           Lcd_Cmd(_LCD_CLEAR);                     // Clear display

           dat1 = Get_Status();
           ByteToHex(dat1, txt);
           Delay_10();
           Lcd_Out(1, 6, txt);
           dat1 = Get_FIFO_Flags();
           ByteToHex(dat1, txt);
           Delay_10();
           Lcd_Out(1, 11, txt);

           #ifdef TX_mode
           Lcd_Out(1, 1, "TX");
           Lcd_Out(2, 1, Data_Out);
           Delay_100();
           makeMsg();
           sendBuffer();
           Delay_100();
           #endif

           #ifdef RX_mode
           Ce_pin = 1;
           Lcd_Out(1, 1, "RX");
           dat1 = readBuffer();
           ByteToHex(dat1, txt);
           Delay_10();
           Lcd_Out(1, 11, txt);
           if((dat1 & 2) != 0) Lcd_Out(2, 1, Data_In);
           Delay_500();
           #endif
       }while(1);
}
Attachments
Connections.png
Connections.png (142.65 KiB) Viewed 2488 times
circuits.JPG
circuits.JPG (312.49 KiB) Viewed 2488 times
project.png
project.png (24.55 KiB) Viewed 2488 times
Last edited by pedraos on 07 Sep 2017 16:24, edited 1 time in total.
Best regards / Mit freundlichen Gruessen

Luis Pedraos

pedraos
Posts: 13
Joined: 20 Aug 2011 01:29

Re: nRF24L01 - PIC16F877A migration to PIC24F16KA102

#2 Post by pedraos » 06 Sep 2017 21:05

More images
Attachments
PIC24F Circuit.JPG
PIC24F Circuit.JPG (393.76 KiB) Viewed 2487 times
Connections2.png
Connections2.png (80.58 KiB) Viewed 2487 times
comparators off, from datasheet.png
comparators off, from datasheet.png (48.35 KiB) Viewed 2487 times
Best regards / Mit freundlichen Gruessen

Luis Pedraos

Post Reply

Return to “User Projects”