• AVR Freaks

Hot!PIC24FJ64GB106 SPI interface

Author
shekhashoukath
New Member
  • Total Posts : 15
  • Reward points : 0
  • Joined: 2019/06/20 21:49:43
  • Location: 0
  • Status: offline
2020/02/11 03:44:34 (permalink)
0

PIC24FJ64GB106 SPI interface

hai ,
i am new to spi interface, how can we check the an spi communication has been established between master and slave. how to monitor the MISO line? how to read a slave device. my slave device is max3421e. i am confused whether the master and slave is working properly. 
 
 
 
unsigned char writeSPI1( unsigned char data )
{
SPI1BUF = data; // write to buffer for TX
while(!SPI1STATbits.SPITBF); // wait for transfer to complete
{
}
return SPI1BUF; // read the received value
}//writeSPI1
 
 
for example, status = writeSPI(0x21), will select a reg and the value in the reg will be returned back, which is smilar to a read operation. can some one tell me whether this assumption is right 
 
#1

14 Replies Related Threads

    ric
    Super Member
    • Total Posts : 27076
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC24FJ64GB106 SPI interface 2020/02/11 03:56:27 (permalink)
    5 (1)
    shekhashoukath
    ...
    for example, status = writeSPI(0x21), will select a reg and the value in the reg will be returned back, which is smilar to a read operation. can some one tell me whether this assumption is right 

    It sounds like you don't quite understand SPI transfers yet.
    EVERY SPI transfer is a simultaneous send and receive.
    What you receive is something that the Slave loaded into its data register before the transfer started, so it is never an immediate response to something you just asked for.
    You need to carefully read the datasheet of your Slave device to see what exactly you will get.
    Often you will send a command, then you have to send a dummy value to the Slave so it can send some data back to you.
    EVERY transfer is started by the Master writing a "byte to send" into its own data register. There is no such thing as a "read only" transfer. The Master ALWAYS sends "something" to trigger each transfer, even if it's only a dummy (= "don't care") value.
     
     
     
    post edited by ric - 2020/02/11 03:57:57

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #2
    mshalash5
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2020/02/04 00:29:40
    • Location: 0
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/11 07:00:22 (permalink)
    0
    I am using MCC generated code like this (8bit example):
    To send a byte:
    void SPI1_Write(uint8_t data){
    SPI1_Exchange8bit((uint8_t) data);
    }
    and to read a byte:
    uint8_t SPI1_Read(void){
        return SPI1_Exchange8bit(0x00);
    }
    for a buffer read (NRF24L01 example):
    void NRF24L01_ReadBuffer(uint8_t data, uint8_t *buffer, uint8_t bytes){
        uint8_t i;
        CSN_SetLow();
       SPI1_Write(data);
       for(i = 0; i < bytes; i++) {
          *buffer = SPI1_Read();
           buffer++;
      }
    *buffer = NULL;
    CSN_SetHigh();
    }
     
    to send a buffer:
    void NRF24L01_WriteBuffer(uint8_t data, uint8_t *buffer, uint8_t bytes){
       uint8_t i;
       CSN_SetLow();
        SPI1_Write(data);
       for(i = 0; i < bytes; i++) {
         SPI1_Write(*buffer);
         buffer++;
      }
       CSN_SetHigh();
    }
    I hope this helps
    #3
    jbroadwell81@gmail.com
    Super Member
    • Total Posts : 1449
    • Reward points : 0
    • Joined: 2005/11/02 13:58:11
    • Location: Indianapolis, Indiana
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/11 08:16:00 (permalink)
    0
    To build on what Ric said, you'll also need to assert (drive low) the chip select (SS on the MAX3421E) during an entire message.  Also, the code you've shown isn't sufficient.  I assume there's setup code for the SPI peripheral someplace else?
     
    There's a variety of good videos on youtube that give an introduction to the SPI bus.
     
    If you're going to be doing much bus work, also get yourself a cheap Logic analyzer.  There's one on Amazon for like 12 bucks that works fantastically for this kind of stuff, although you may need to slow your bus rate down during debugging to use it.

    http://www.serialwombat.com
    When someone asks you "Can't you just...", watch out.
    #4
    shekhashoukath
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2019/06/20 21:49:43
    • Location: 0
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/16 21:13:48 (permalink)
    0
    hai,
    in pic datasheet, spi interface between two processors is shown as  sdo line of master connected to sdi line of slave, and sdi line of master connected to sdo line of slave . when i search about spi interface in google, most of sites shows spi interface in which mosi of master connected to mosi of slave, miso line of master connected to miso line of slave. which is the correct one
    #5
    ric
    Super Member
    • Total Posts : 27076
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC24FJ64GB106 SPI interface 2020/02/16 21:22:13 (permalink)
    0
    They are both correct.
     
    MOSI = "Master Out Slave In"
    That is the SDO pin on the Master, and the SDI pin on the Slave.
     
    MISO = "Master In Slave Out"
    That is SDI on the Master and SDO on the Slave.
     
    You are assuming the SDO/SDI and MOSI/MISO are interchangeable terms. They are not.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #6
    shekhashoukath
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2019/06/20 21:49:43
    • Location: 0
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/26 03:22:42 (permalink)
    0
    HAI,
     
    i tried to implement spi interface between pic24f and max3421e,  given below is the code i have implemented . but i did not get any value on miso line, what should i do to perform a read from the slave, eventhough its given simultaneous read and write will occur on the same clk cycle, its not happening.

    void main(void)
    {

    SPI1Init();



    LATBbits. LATB14 =0 ; //SS = low
    writeSPI1(0x8A); //select R17 with write bit set
    delay(10);
    writeSPI1(0x14); // configure R17 for full duplex mode,INTLEVEL - edge active, POSINT- positive edge
    delay(10);
    LATBbits. LATB14 =1 ; //SS = high
    delay(10);
    LATBbits. LATB14 =0 ; //SS = low
    writeSPI1(0x88); //select R17 , with read bit set
    // delay(10);
    k=writeSPI1(0x00); // dummy value for read opearation
    delay(10);
    LATBbits. LATB14 =1 ; //SS = high
     
     
    while(1);
    }
     
     
    void SPI1Init(void)
    {
    /*--------------------------------------Configure RP pins --------------------------------------*/
    RPINR20bits.SDI1R = 17; //SPI Master input RP17
    RPOR5bits.RP10R = 7; //SPI Master output RP10 as MOSI
    RPOR14bits.RP29R = 8; //SPI clock output RP29
    TRISBbits.TRISB14 = 0; //Assigning RD1 as an output port for CS - slave select
    // LATBbits. LATB14 =1; //Slave select = low
    PORTBbits.RB14 =1;
    SPI1STATbits.SPIEN = 0 ; //Disable SPI module.The module must be disable before Control Registers are set
    SPI1CON1bits.DISSCK = 0;
    SPI1CON1bits.DISSDO = 0;
    SPI1CON1bits.MODE16 = 0;
    SPI1CON1bits.MSTEN = 1;
    SPI1CON1bits.SMP = 1;
    SPI1CON1bits.CKP = 0;
    SPI1CON1bits.CKE = 0; //Serial output data changes on transition from idle clock state to active clock state
    SPI1CON1bits.SSEN = 0; //SSx pin not used by module; pin controlled by port function
    //Prescaler settings for 500KHz for FCY = 16MHz
    //SPI1CON1bits.SPRE = SEC_PRESCAL_2_1;
    //SPI1CON1bits.PPRE = PRI_PRESCAL_16_1;
    SPI1CON1bits.SPRE = 4 ; //Prescaler settings for 1MHz for FCY = 16MHz
    SPI1CON1bits.PPRE = 2;
    SPI1CON2bits.FRMEN = 0;
    SPI1CON2bits.SPIBEN = 0;
    SPI1STATbits.SPIROV = 0;
    SPI1STATbits.SPISIDL = 0;
    IFS0bits.SPI1IF = 0;
    IEC0bits.SPI1IE = 0;
    //IPC2bits.SPI1IP = 7;
    // LATBbits. LATB14 =0;
    SPI1STATbits.SPIEN = 1 ; //Enable SPI module
    }
     

    void delay(unsigned int time)
    {
    for(i=0;i<time;i++)
    {
    }
    }
     
     
    unsigned char writeSPI1( unsigned char data )
    {
    SPI1BUF = data; // write to buffer for TX
    // while(!SPI1STATbits.SPITBF); // wait for transfer to complete
    while(!SPI1STATbits.SPIRBF);
    {
    }
    return SPI1BUF; // read the received value
     
    #7
    shekhashoukath
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2019/06/20 21:49:43
    • Location: 0
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/26 03:22:42 (permalink)
    0
    HAI,
     
    i tried to implement spi interface between pic24f and max3421e,  given below is the code i have implemented . but i did not get any value on miso line, what should i do to perform a read from the slave, eventhough its given simultaneous read and write will occur on the same clk cycle, its not happening.

    void main(void)
    {

    SPI1Init();



    LATBbits. LATB14 =0 ; //SS = low
    writeSPI1(0x8A); //select R17 with write bit set
    delay(10);
    writeSPI1(0x14); // configure R17 for full duplex mode,INTLEVEL - edge active, POSINT- positive edge
    delay(10);
    LATBbits. LATB14 =1 ; //SS = high
    delay(10);
    LATBbits. LATB14 =0 ; //SS = low
    writeSPI1(0x88); //select R17 , with read bit set
    // delay(10);
    k=writeSPI1(0x00); // dummy value for read opearation
    delay(10);
    LATBbits. LATB14 =1 ; //SS = high
     
     
    while(1);
    }
     
     
    void SPI1Init(void)
    {
    /*--------------------------------------Configure RP pins --------------------------------------*/
    RPINR20bits.SDI1R = 17; //SPI Master input RP17
    RPOR5bits.RP10R = 7; //SPI Master output RP10 as MOSI
    RPOR14bits.RP29R = 8; //SPI clock output RP29
    TRISBbits.TRISB14 = 0; //Assigning RD1 as an output port for CS - slave select
    // LATBbits. LATB14 =1; //Slave select = low
    PORTBbits.RB14 =1;
    SPI1STATbits.SPIEN = 0 ; //Disable SPI module.The module must be disable before Control Registers are set
    SPI1CON1bits.DISSCK = 0;
    SPI1CON1bits.DISSDO = 0;
    SPI1CON1bits.MODE16 = 0;
    SPI1CON1bits.MSTEN = 1;
    SPI1CON1bits.SMP = 1;
    SPI1CON1bits.CKP = 0;
    SPI1CON1bits.CKE = 0; //Serial output data changes on transition from idle clock state to active clock state
    SPI1CON1bits.SSEN = 0; //SSx pin not used by module; pin controlled by port function
    //Prescaler settings for 500KHz for FCY = 16MHz
    //SPI1CON1bits.SPRE = SEC_PRESCAL_2_1;
    //SPI1CON1bits.PPRE = PRI_PRESCAL_16_1;
    SPI1CON1bits.SPRE = 4 ; //Prescaler settings for 1MHz for FCY = 16MHz
    SPI1CON1bits.PPRE = 2;
    SPI1CON2bits.FRMEN = 0;
    SPI1CON2bits.SPIBEN = 0;
    SPI1STATbits.SPIROV = 0;
    SPI1STATbits.SPISIDL = 0;
    IFS0bits.SPI1IF = 0;
    IEC0bits.SPI1IE = 0;
    //IPC2bits.SPI1IP = 7;
    // LATBbits. LATB14 =0;
    SPI1STATbits.SPIEN = 1 ; //Enable SPI module
    }
     

    void delay(unsigned int time)
    {
    for(i=0;i<time;i++)
    {
    }
    }
     
     
    unsigned char writeSPI1( unsigned char data )
    {
    SPI1BUF = data; // write to buffer for TX
    // while(!SPI1STATbits.SPITBF); // wait for transfer to complete
    while(!SPI1STATbits.SPIRBF);
    {
    }
    return SPI1BUF; // read the received value
     
    #8
    rodims
    Super Member
    • Total Posts : 1557
    • Reward points : 0
    • Joined: 2009/02/10 11:08:59
    • Location: 51.9627, 7.6262
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/26 05:18:15 (permalink)
    0
    but i did not get any value on miso line

    How do you know ? What did you do for testing ?
    How do you connect the two chips ? Which pin is connected to which pin ?
     

    TRISBbits.TRISB14 = 0; //Assigning RD1 as an output port for CS - slave select
    // LATBbits. LATB14 =1; //Slave select = low
    PORTBbits.RB14 =1;
    ...
     
    // LATBbits. LATB14 =0;

     
    What should this do   ?
    You should frame your SPI transfer with an "active low" SS line, you must read your MAX3421E datasheet !
    a) do not use RB to set your output. You must use LAT (as you already did, but commented out).
    b) Your comment with RD1 is either completely wrong or your code is wrong
     
    [edit: I see, the improper handling of SS is only in the SPI init, but you should do it correct in all places. ]
    post edited by rodims - 2020/02/26 06:16:28
    #9
    Aussie Susan
    Super Member
    • Total Posts : 3709
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/26 18:35:03 (permalink)
    5 (1)
    Also that 'delay' function is almost certainly useless and, even without much optimisation, it will probably degenerate to a NOP and certainly no delay. Use the _delay() macros instead.
    Also you should be following the golden rule: read from the PORT; write to the LAT.
    Finally compare the SPI transition diagram in the max3421e data sheet with the diagrams in the MCU data sheet with regard to setting the CKP and CKE bits. These do NOT correspond directly to the CPOL and CPHA bit that the max3421e data sheet refers to.
    Susan
    #10
    shekhashoukath
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2019/06/20 21:49:43
    • Location: 0
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/27 22:15:35 (permalink)
    0
    hai,
    i changed port to lat, the comment on RD pin is wrong. i checked the sclk, ss, miso and mosi line usind DSo and Picoscope. in both case i am not able to read the data on miso. i tried to attach the image but i am not able to insert the images in image option
    #11
    ric
    Super Member
    • Total Posts : 27076
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC24FJ64GB106 SPI interface 2020/02/27 22:32:31 (permalink)
    0
    The "image" option in the "Quick Reply" box only works for an image that is hosted on a website somewhere.
    If you want to attach an image from your PC, you must click on "Open Full Version", then use the large "Attach Images" button over on the right.
     

    I also post at: PicForum
    Links to useful PIC information: http://picforum.ric323.co...opic.php?f=59&t=15
    NEW USERS: Posting images, links and code - workaround for restrictions.
    To get a useful answer, always state which PIC you are using!
    #12
    Gort2015
    Klaatu Barada Nikto
    • Total Posts : 3845
    • Reward points : 0
    • Joined: 2015/04/30 10:49:57
    • Location: 0
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/02/27 22:32:49 (permalink)
    0
                __
    Did the SS line change state?
     

    MPLab X playing up, bug in your code? Nevermind, Star Trek:Discovery will be with us soon.
    https://www.youtube.com/watch?v=Iu1qa8N2ID0
    + ST:Continues, "What Ships are Made for", Q's back.
    #13
    LdB_ECM
    Super Member
    • Total Posts : 359
    • Reward points : 0
    • Joined: 2019/04/16 22:01:25
    • Location: 0
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/03/01 03:19:11 (permalink)
    0
    Your prescale frequencies are wrong if you want 1Mhz .. you want 4:1 on both look at page 190 of datasheet
     
    As you haven't got it in enhanced buffer mode so you have only 1 byte buffer
    I suspect you have to wait on SPITBF to go low before you write and SPIRBF to go high before you read otherwise you overrun the 1 byte buffer (that is how I read datasheet anyhow)
    unsigned char writeSPI1( unsigned char data )
    {
       while (SPI1STATbits.SPITBF) {}; // wait for SPITBF flag to go low
       SPI1BUF = data; // write to buffer for TX
       while (!SPI1STATbits.SPIRBF) {}; // wait for SPIRBF to go high
       return SPI1BUF; // read the received value
    }

    post edited by LdB_ECM - 2020/03/01 03:20:44
    #14
    shekhashoukath
    New Member
    • Total Posts : 15
    • Reward points : 0
    • Joined: 2019/06/20 21:49:43
    • Location: 0
    • Status: offline
    Re: PIC24FJ64GB106 SPI interface 2020/03/02 03:15:42 (permalink)
    0
     
     
    bit 4-2 SPRE<2:0>: Secondary Prescale bits (Master mode)
    111 = Secondary prescale 1:1
    110 = Secondary prescale 2:1
    ...
    000 = Secondary prescale 8:1
     

    bit 1-0 PPRE<1:0>: Primary Prescale bits (Master mode)
    11 = Primary prescale 1:1
    10 = Primary prescale 4:1
    01 = Primary prescale 16:1
     
    as per the datasheet, to get 1MHz clk, primary prescale bits should be:4:1 ratio ie 2, and secondary prescale bits should be 4:1 ratio ie 100= 4
    #15
    Jump to:
    © 2020 APG vNext Commercial Version 4.5