• AVR Freaks

Hot!PIC18F26K40 - Using SPI

Author
lukegalea16
New Member
  • Total Posts : 8
  • Reward points : 0
  • Joined: 2018/02/13 04:51:43
  • Location: 0
  • Status: offline
2019/06/17 13:22:51 (permalink)
0

PIC18F26K40 - Using SPI

I am trying to use SPI to control a MAX7221 (which is working fine when tested with an Arduino).
Could someone kindly have a look at the code and possibly note any errors in configuring the SPI please? Since this is my first time configuring the SPI - however I tried to thoroughly follow the data sheet.
 
//SPI Setup
SSP1STATbits.SMP = 1; //Slew Rate Control Bit
SSP1STATbits.CKE = 0; //Rising Edge Clock
SSP1CON1bits.SSPEN = 1; //Master Synchronous Serial Port Enable bit
//SCK, SDO, SDI, SS
SSP1CON1bits.CKP = 0; //Idle state for the clock is a low level
SSP1CON1bits.SSPM = 0b0010; //SPI Master mode: Clock = Fosc/64
SSP1CON3bits.BOEN = 1; //SSPxBUF is updated every time a new data byte is available, ignoring the BF bit
    
//SPI Setup - Pins
ANSELBbits.ANSELB1 = 0; //Set RB1 as output
TRISBbits.TRISB1 = 0;
RB1PPS = 0x10; //MSSP1 - SDO
ANSELBbits.ANSELB2 = 0; //Set RB2 as output
TRISBbits.TRISB2 = 0;
RB2PPS = 0x0F; //MSSP1 - SCK
ANSELBbits.ANSELB3 = 0; //RB3 as CS/SS set to LOW to select only MAX7221
TRISBbits.TRISB3 = 0;
LATBbits.LATB3 = 0;

//DISPLAY TEST (original line 0b0000011100000001)
SSP1BUF = 0b00000001;
SSP1BUF = 0b00001111;

 
Thanks in advance,
Kind regards
Luke
#1

8 Replies Related Threads

    ric
    Super Member
    • Total Posts : 23791
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC18F26K40 - Using SPI 2019/06/18 19:00:58 (permalink)
    +1 (1)
    You can't do two successive writes to SSP1BUF like this.
    SSP1BUF = 0b00000001;
    SSP1BUF = 0b00001111;

    You must wait for the first to complete before doing the second one.
    Before each transfer, clear the SSP1IF flag, then after writing to SSP1BUF, wait for SSP1IF to become set before continuing.
     
    Also, most devices need to see the CS pin go low before the transfer, then go high again at the end.
    You are just setting B3 low and leaving it low.
     
     
    post edited by ric - 2019/06/18 19:03:07

    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
    Aussie Susan
    Super Member
    • Total Posts : 3618
    • Reward points : 0
    • Joined: 2008/08/18 22:20:40
    • Location: Melbourne, Australia
    • Status: offline
    Re: PIC18F26K40 - Using SPI 2019/06/18 20:20:08 (permalink)
    +1 (1)
    Might not impact you now, but in general it is best to fully configure a module and then enable it (unless the data sheet tells you otherwise - Microchp UARTs are a classic case). Some implementations will not respond to configuration changes are the module is enabled.
    Are you seeing any pulses on the SCK and/or SDO pins?
    Susan
    #3
    tomsedlack
    Super Member
    • Total Posts : 164
    • Reward points : 0
    • Joined: 2010/01/14 09:01:53
    • Location: 0
    • Status: offline
    Re: PIC18F26K40 - Using SPI 2019/06/19 04:17:37 (permalink)
    0
    Like ric says:

     SSP1BUF=Cmd; // Put command into SPI buffer
    while (!SSP1STATbits.BF); // Wait for the transfer to finish

    #4
    ric
    Super Member
    • Total Posts : 23791
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC18F26K40 - Using SPI 2019/06/19 06:37:43 (permalink)
    +1 (1)
    That's a different way of doing it.
    If you use the BF flag, then you must do a dummy read of SSP1BUF after each transfer to clear BF.
     

    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!
    #5
    lukegalea16
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2018/02/13 04:51:43
    • Location: 0
    • Status: offline
    Re: PIC18F26K40 - Using SPI 2019/06/20 01:20:06 (permalink)
    0
    Hi, thank you all for your help!
    A few questions...
    1. Is the MSB shifted out first? 
      The MSSP consists of a transmit/receive shift register (SSPSR) and a buffer register (SSPxBUF). The SSPSR shifts the data in and out of the device, MSb first.
    2. Do I need to set the SSPxCLKPPS register the same as SCK?
      In Master mode the clock signal output to the SCK pin is also the clock signal input to the peripheral. The pin selected for output with the RxyPPS register must also be selected as the peripheral input with the SSPxCLKPPS register.
    3. I am writing to the SPI as shown below, I do not need to turn on interrupt flags right? If I'm reading the BF bit
    //DISPLAY TEST
     
    LATBbits.LATB3 = 0;
    SSP1BUF = 0b10000000;
    while(SSP1STATbits.BF == 0);
    result = SSP1BUF;
    SSP1BUF = 0b11110000;
    while(SSP1STATbits.BF == 0);
    LATBbits.LATB3 = 1;
    result = SSP1BUF;
    __delay_ms(100);

     
    post edited by lukegalea16 - 2019/06/20 01:30:18
    #6
    ric
    Super Member
    • Total Posts : 23791
    • Reward points : 0
    • Joined: 2003/11/07 12:41:26
    • Location: Australia, Melbourne
    • Status: online
    Re: PIC18F26K40 - Using SPI 2019/06/20 02:02:35 (permalink)
    +1 (1)
    1. The section you quoted has the answer.
    2. Again, the section you quoted has the answer.
    3. I think the code is ok.
     

    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!
    #7
    tomsedlack
    Super Member
    • Total Posts : 164
    • Reward points : 0
    • Joined: 2010/01/14 09:01:53
    • Location: 0
    • Status: offline
    Re: PIC18F26K40 - Using SPI 2019/06/20 04:24:15 (permalink)
    0
    ric
    That's a different way of doing it.
    If you use the BF flag, then you must do a dummy read of SSP1BUF after each transfer to clear BF.



    Since SPI is duplex, I read the MISO transfer in the routine (below). SPI_IN is a global unsigned char.

    void Send_SPI (unsigned char Cmd) {
    #if defined (_PIC18F46K22_H_)
      SSP1BUF=Cmd; // Put command into SPI buffer
      while (!SSP1STATbits.BF); // Wait for the transfer to finish
      SPI_IN=SSP1BUF;
    #else
      SSPBUF=Cmd; // Put command into SPI buffer
      while (!SSPSTATbits.BF); // Wait for the transfer to finish
      SPI_IN=SSPBUF; // Save the read values
    #endif
    }

    #8
    lukegalea16
    New Member
    • Total Posts : 8
    • Reward points : 0
    • Joined: 2018/02/13 04:51:43
    • Location: 0
    • Status: offline
    Re: PIC18F26K40 - Using SPI 2019/06/20 07:09:58 (permalink)
    0
    Hi, good news! grin: grin I got it to work. I started by comparing my SPI output to that of the Arduino and after adding some micro second delays, I found out that I had set the transmission incorrectly (i.e. it had to be set to transmit from a high to low state as I found out in the timing diagram of the MAX7221). I was also transmitting the data stream incorrectly as regards the order. Anyways, thank you all for your help! Much appreciated. Will upload the working code later on just in case anyone else is carrying out a similar project and needs help.
    #9
    Jump to:
    © 2019 APG vNext Commercial Version 4.5