This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

SPI source code

Hi,

Does any one have a C source code for a master-SPI communication?
I am NOT using any SPI hardware in my uC.

Avital Bar-Shlomo

Parents
  • What's the difficulty here? SPI is dead simple. You select the device to talk to via the chip select line, you drive the data on to the data pin, you clock that data pin to the selected device, and finally you de-select that device. E.g.

    sbit r_spiClk = 0x90; // Port 1.0
    sbit r_spiDat = 0x91; // Port 1.1
    sbit r_spiCs0 = 0x92; // Port 1.2 - Slave Device 1
    sbit r_spiCs1 = 0x93; // Port 1.3 - Slave Device 2
    sbit r_spiCs2 = 0x94; // Port 1.4 - Slave Device 3
    
    typedef unsigned char U8;
    typedef bit           Bool;
    typedef enum Slaves { SLAVE_DEV_1, SLAVE_DEV_2, SLAVE_DEV_3, NUM_SLAVES } Slaves;
    
    // _____________________________________________________________________________
    // _____________________________________________________________________________
    //
    // Function:  sendSpiMsg
    //
    // Description:
    // ------------
    // Sends <len> bytes of <pMsg> to <slave>.
    //
    // Design Notes:
    // -------------
    // Returns true for any failure, zero for no failures.
    //
    // UNTESTED!
    // _____________________________________________________________________________
    //
    Bool sendSpiMsg(U8 *pMsg, U8 len, Slaves slave)
    {
        if (slave >= NUM_SLAVES) return 1;
    
        switch (slave)
        {
            case SLAVE_DEV_1: r_spiCs0 = 0; break;
            case SLAVE_DEV_2: r_spiCs1 = 0; break;
            case SLAVE_DEV_3: r_spiCs2 = 0; break;
        }
    
        while (len--)
        {
            U8 currentByte = *pMsg++;
            U8 bitCount    = 8;
    
            while (bitCount--)
            {
                r_spiClk = 1;
    #ifdef LSBIT_FIRST
                r_spiDat    = currentByte & 1;
                currentByte = currentByte >> 1 & 0x7F;
    #else // MSBit first
                r_spiDat      = currentByte & 0x80;
                currentByte <<= 1;
    #endif
                r_spiClk = 0;
            }
        }
    
        // Leave bus in safe state. Chip selects low active.
        r_spiClk = 1;
        r_spiDat = 1;
        r_spiCs0 = 1;
        r_spiCs1 = 1;
        r_spiCs2 = 1;
    
        return 0;
    }

    - Mark

Reply
  • What's the difficulty here? SPI is dead simple. You select the device to talk to via the chip select line, you drive the data on to the data pin, you clock that data pin to the selected device, and finally you de-select that device. E.g.

    sbit r_spiClk = 0x90; // Port 1.0
    sbit r_spiDat = 0x91; // Port 1.1
    sbit r_spiCs0 = 0x92; // Port 1.2 - Slave Device 1
    sbit r_spiCs1 = 0x93; // Port 1.3 - Slave Device 2
    sbit r_spiCs2 = 0x94; // Port 1.4 - Slave Device 3
    
    typedef unsigned char U8;
    typedef bit           Bool;
    typedef enum Slaves { SLAVE_DEV_1, SLAVE_DEV_2, SLAVE_DEV_3, NUM_SLAVES } Slaves;
    
    // _____________________________________________________________________________
    // _____________________________________________________________________________
    //
    // Function:  sendSpiMsg
    //
    // Description:
    // ------------
    // Sends <len> bytes of <pMsg> to <slave>.
    //
    // Design Notes:
    // -------------
    // Returns true for any failure, zero for no failures.
    //
    // UNTESTED!
    // _____________________________________________________________________________
    //
    Bool sendSpiMsg(U8 *pMsg, U8 len, Slaves slave)
    {
        if (slave >= NUM_SLAVES) return 1;
    
        switch (slave)
        {
            case SLAVE_DEV_1: r_spiCs0 = 0; break;
            case SLAVE_DEV_2: r_spiCs1 = 0; break;
            case SLAVE_DEV_3: r_spiCs2 = 0; break;
        }
    
        while (len--)
        {
            U8 currentByte = *pMsg++;
            U8 bitCount    = 8;
    
            while (bitCount--)
            {
                r_spiClk = 1;
    #ifdef LSBIT_FIRST
                r_spiDat    = currentByte & 1;
                currentByte = currentByte >> 1 & 0x7F;
    #else // MSBit first
                r_spiDat      = currentByte & 0x80;
                currentByte <<= 1;
    #endif
                r_spiClk = 0;
            }
        }
    
        // Leave bus in safe state. Chip selects low active.
        r_spiClk = 1;
        r_spiDat = 1;
        r_spiCs0 = 1;
        r_spiCs1 = 1;
        r_spiCs2 = 1;
    
        return 0;
    }

    - Mark

Children
No data