Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[PIC] SPI on dsPic33f dont get answer

Status
Not open for further replies.

bestrider14

Member level 1
Joined
Feb 27, 2015
Messages
39
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
300
Hi,

I try do make a SPI communication between my dspic33fj128mc802 and nrf24l. i made it whit a 18f2550 all is good but on my dspic the spi dont work well i think.

Code:
sbit Irq_pin   at PORTA.B4; sfr;
sbit Mosi_pin  at PORTB.B5; sfr;
sbit Ce_pin    at PORTB.B6; sfr;
sbit Sclk_pin  at PORTB.B9; sfr;
sbit Csn_pin   at PORTB.B8; sfr;
sbit Miso_pin  at PORTB.B7; sfr;

sbit Irq_tris  at TRISA.B4; sfr;
sbit Mosi_tris at TRISB.B5; sfr;
sbit Ce_tris   at TRISB.B6; sfr;
sbit Sclk_tris at TRISB.B9; sfr;
sbit Csn_tris  at TRISB.B8; sfr;
sbit Miso_tris at TRISB.B7; sfr;

....
....
...

PPS_Mapping(7, _INPUT, _SDI1);
PPS_Mapping(9, _OUTPUT, _SCK1OUT);
PPS_Mapping(5, _OUTPUT, _SDO1);


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

SPI1_Init();

i dind not get aswer from my nrf24. all a get it 00 and 00. thanks you

complet code
Code:
/*================================================================================
*
*   nRF24L01+ using no libraries
*   PIC16F877A
*
*   Allen Mulvey May 2014
*
*   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[] = "Test message.";

// 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 PORTA.B4; sfr;
sbit Mosi_pin  at PORTB.B5; sfr;
sbit Ce_pin    at PORTB.B6; sfr;
sbit Sclk_pin  at PORTB.B9; sfr;
sbit Csn_pin   at PORTB.B8; sfr;
sbit Miso_pin  at PORTB.B7; sfr;

sbit Irq_tris  at TRISA.B4; sfr;
sbit Mosi_tris at TRISB.B5; sfr;
sbit Ce_tris   at TRISB.B6; sfr;
sbit Sclk_tris at TRISB.B9; sfr;
sbit Csn_tris  at TRISB.B8; sfr;
sbit Miso_tris at TRISB.B7; sfr;

// LCD module connections
sbit LCD_RS at LATA0_bit;
sbit LCD_EN at LATA1_bit;
sbit LCD_D4 at LATB0_bit;
sbit LCD_D5 at LATB1_bit;
sbit LCD_D6 at LATB2_bit;
sbit LCD_D7 at LATB3_bit;

sbit LCD_RS_Direction at TRISA0_bit;
sbit LCD_EN_Direction at TRISA1_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_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;

       AD1PCFGL = 0xFFFF;                           // digital not analog
       CMCON = 7;
        
        PPS_Mapping(7, _INPUT, _SDI1);
        PPS_Mapping(9, _OUTPUT, _SCK1OUT);
        PPS_Mapping(5, _OUTPUT, _SDO1);



       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);
           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);
}
 

horace1

Advanced Member level 5
Joined
Nov 18, 2008
Messages
2,123
Helped
596
Reputation
1,188
Reaction score
573
Trophy points
1,393
Location
Norwich, UK
Activity points
13,071
Hi,

I try do make a SPI communication between my dspic33fj128mc802 and nrf24l. i made it whit a 18f2550 all is good but on my dspic the spi dont work well i think.
have you tried putting an oscilloscope on the SPI clock and data lines to check that it is attempting to communicate?
This will also enable you check that you have the SPI clock frequency etc correct

it is also worth looking at Microchip's code examples
https://www.microchip.com/CodeExamplesByFunc.aspx
 
Last edited:

Aussie Susan

Advanced Member level 4
Joined
Jan 5, 2015
Messages
1,247
Helped
377
Reputation
754
Reaction score
375
Trophy points
83
Activity points
13,503
The dsPIC33 families have LAT registers so you should apply the "golden rule" of 'read from the PORT, write to the LAT' (even though the hardware does help you get around the RMW problem).
The most common causes of always reading 0's are:
- not making the pins 'digital' (you are OK there)
- not using the PPS mapping correctly (I assume you are OK there as I don't know the library you are using)
- not initialising the SPI peripheral correctly
and it is the last one that I can't tell as you call the 'SPI1_Init' function but don't show what it is. However, looking at Figure 33 in(what I think is) the data sheet for the nrf24l and Figure 3-2 of the SPI section in the FRM for your MCU, you will want CKP = 0, CKE = 1 and SMP = 1.
The SPI peripheral is very simple to set up and use (I have never bothered with any library functions as they I find they almost never work the way I expect such as blocking when you don't need them to etc.)
I assume that the numerous calls to the delay functions are required by the radio chip as they are certainly not needed by the SPI peripheral (as long as you are using it correctly).
Susan
 

bestrider14

Member level 1
Joined
Feb 27, 2015
Messages
39
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
300
I dont have scope to tcheck my clock but with a led on my 18f2550 i can see it and on my ds33 nothing. i know its not the best methode to tcheck it
 

bestrider14

Member level 1
Joined
Feb 27, 2015
Messages
39
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
300
After some try i finaly get it. but i got some noise. i need to touche the pin whith my finger. just a little touch, no pression on it. i try a cap between the vss and vss it seem to be better but always need to touch it
 

Aussie Susan

Advanced Member level 4
Joined
Jan 5, 2015
Messages
1,247
Helped
377
Reputation
754
Reaction score
375
Trophy points
83
Activity points
13,503
Check Figure 2-1 ("Recommended Minimum Connection") in your dsPIC data sheet and make sure that you have all of the bypass capacitors in place and the Vcap capacitor.
Based on what you have said, I'm not sure that the MCU is actually working at all so I suggest that you write a small "flash a LED" program using a timer to flash the LED at (say) 1Hz so that you can clearly see it. If that works then the MCU itself is running - if it doesn't then you have more fundamental issues with your circuit that you need to get sorted.
Susan
 

bestrider14

Member level 1
Joined
Feb 27, 2015
Messages
39
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
300
my pic work well, i have a lcd on it but its my nrf24 i need to touch pin. its like i have noise in my spi or something else
 

Aussie Susan

Advanced Member level 4
Joined
Jan 5, 2015
Messages
1,247
Helped
377
Reputation
754
Reaction score
375
Trophy points
83
Activity points
13,503
Just trying to understand what you have tried and what works and what doesn't:
- PIC18f2550 and the NRF24l via SPI - works which implies that the NRF24l is stable and working OK and the SPI connection is OK
- dspic33fj128mc802 and a local LCD - works which implies the MCU is working
- dspic33fj128mc802 and the (assumed) same NRF24l via the (assumed) same SPI - problems
Firstly, can you confirm or correct the assumptions?
If they are correct, then it would imply that the code in the MCU is wrong. Can you please address the questions I asked about the initialisation of the SPI in my first response?
Looking at the data sheet, I see that RP9 also has the JTAG TDO function on it - I can't see the config settings so have you turned off the JTAG?
Have you tried to read from the NRF24l registers and does the reply make sense?
Susan
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top