SPI refresher for PIC18F27J13

Discussion in 'Embedded Systems and Microcontrollers' started by spinnaker, Feb 11, 2018.

  1. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    It is been a while since I have worked with SPI and I need a refresher.

    Datasheet says:

    Each MSSP module consists of a Transmit/Receive
    Shift register (SSPxSR) and a Buffer register
    (SSPxBUF). The SSPxSR shifts the data in and out of
    the device, MSb first. The SSPxBUF holds the data that
    was written to the SSPxSR until the received data is
    ready. Once the 8 bits of data have been received, that
    byte is moved to the SSPxBUF register. Then, the Buffer
    Full (BF) detect bit (SSPxSTAT<0>) and the interrupt
    flag bit, SSPxIF, are set. This double-buffering of the
    received data (SSPxBUF) allows the next byte to start
    reception before reading the data that was just received.

    Any write to the SSPxBUF register during transmission
    or reception of data will be ignored and the Write
    Collision Detect bit, WCOL (SSPxCON1<7>), will be set.
    User software must clear the WCOL bit so that it can be
    determined if the following write(s) to the SSPxBUF
    register completed successfully.

    It says WCOL needs to be cleared. When? I assume this is before I transmit?
  2. JohnInTX


    Jun 26, 2012
    WCOL shouldn’t be set if you work the SPI correctly. The easiest way to.do that is check BF and read SSPxBUF before writing the next character. If you don’t and WCOL is set, clear it before you transmit again. A good SPI implementation will check the error flags after each byte anyway including WCOL. Any error flag should be taken as a failed communication.
  3. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    So I am transmitting only. Any tips there?
  4. JohnInTX


    Jun 26, 2012
    Unless there is a special TX only mode, I just write a byte to SSPxBUF, wait for BF or interrupt, read SSPxBUF and discard the received value if I don’t want it. Repeat.

    EDIT: a quick read of the datasheet confirms that you have to read SSPxBUF to clear BF and avoid WCOL and SSPOV errors. The procedure above should work. See Register 20-2 description and this on the next page:
    Last edited: Feb 11, 2018
  5. Picbuster

    Well-Known Member

    Dec 2, 2013
    here a working SPI Tx
    delays needed in my application due to SPI behave of connected devices

    Code (C):
    1. //SPI settings
    3. //  SSP1CON1 explain
    4. //bit 7  Wcol
    5. //bit 6  slave mode overrun
    6. //bit 5  SSpen 1 enable spi
    7. //bit 4  ckp clock polarity
    8. //bit 0-3  value
    9. //  SSPM=2;  //FOSC/64
    10. //  SSPM=1;  //FOSC/16
    11. //  SSPM=0;  //FOSC/4
    12.   SPEN1=1;
    13.    SYNC1=0;
    14.    BRGH1=0;
    15.   SPBRG1 =15;
    16.   SSP1STAT= 0b1000000;
    17.   SSP1CON1bits.CKP=0;
    18.   SSP1CON1bits.SSPM=2;
    20.   SSP1CON1bits.SSPEN=On;
    21.   PIE1bits.SSP1IE=On;
    22.   INTCONbits.GIE=On;
    23.   INTCONbits.PEIE=On;
    25. // data in FTDI_Msg
    27. void Send_SPI1(int Size)
    28. {
    29.   Ena_B_1=Yes;
    30.   __delay_ms(2);  // wait for ready
    31.   for (n=0;n<Size;n++)
    32.   {
    33.   char temp = SSP1BUF;  // clear buffer//------
    34.   while (SSP1CON1bits.WCOL)
    35.   {
    36.   SSP1CON1bits.WCOL=0;
    37.   __delay_us(2);
    38.   }
    40.   SSP1BUF =  FTDI_Msg[n];  // send
    41.   __delay_us(5);
    42.   }
    43.   __delay_ms(5);  // allow disconnect
    44.   Ena_B_1=No;
    45. }

    Moderators note : Please use code tags for pieces of code
    Last edited by a moderator: Feb 12, 2018