SPI Library

mikroC PRO for 8051 provides a library for comfortable with SPI work in Master mode. The 8051 MCU can easily communicate with other devices via SPI: A/D converters, D/A converters, MAX7219, LTC1290, etc.

Library Routines

Generic Routines

Notes:

SPIx_Init

Prototype

// for ATMEL MCUs
void SPIx_Init();

// for Silicon Laboratories MCUs
void SPIx_Init(unsigned long clock);

Returns

Nothing.

Description

This routine configures and enables SPI module with the following settings:

  • master mode
  • clock idle low
  • 8 bit data transfer
  • most significant bit sent first
  • serial output data changes on idle to active transition of clock state
  • serial clock :
    • - for ATMEL MCU's serial clock = Fosc/128 (Fosc/64 in x2 mode)
    • - for Silicon Laboratories MCUs serial clock is acquired from the clock parameter
Requires

MCU must have SPI module.

Example
// Initialize the SPI module with default settings
SPI1_Init();

// Initialize the SPI module with the baud rate of 100000
SPI1_Init(100000);

SPIx_Init_Advanced

Prototype

// for ATMEL MCUs
void SPIx_Init_Advanced(unsigned short adv_setting);

// for Silicon Laboratories MCUs
void SPIx_Init_Advanced(unsigned long clock, unsigned short adv_setting);

Returns

Nothing.

Description

This routine configures and enables the SPI module with the user defined settings.

Parameters :

  • baud_rate sets the desired SPI clock speed
  • adv_setting: SPI module configuration flags. Predefined library constants (see the table below) can be ORed to form appropriate configuration value.

    Description Predefined library const
    SPI clock polarity:
    SPI clock idle level is low _SPI_CLK_IDLE_LO
    SPI clock idle level is high _SPI_CLK_IDLE_HIGH
    SPI clock phase:
    Data transmitted on idle to active edge _SPI_CLK_IDLE_2_ACTIVE
    Data transmitted on active to idle edge _SPI_CLK_ACTIVE_2_IDLE
    SPI clock speed:
    Sck = Fosc/1, Master mode _SPI_FCY_DIV1
    Sck = Fosc/2 (Fosc in x2 mode), Master mode _SPI_FCY_DIV2
    Sck = Fosc/4 (Fosc/2 in x2 mode), Master mode _SPI_FCY_DIV4
    Sck = Fosc/8 (Fosc/4 in x2 mode), Master mode _SPI_FCY_DIV8
    Sck = Fosc/16 (Fosc/8 in x2 mode), Master mode _SPI_FCY_DIV16
    Sck = Fosc/32 (Fosc/16 in x2 mode), Master mode _SPI_FCY_DIV32
    Sck = Fosc/64 (Fosc/32 in x2 mode), Master mode _SPI_FCY_DIV64
    Sck = Fosc/128 (Fosc/64 in x2 mode), Master mode _SPI_FCY_DIV128
    Output mode:
    Output set as quasi-bidirectional (8051) _SPI_OUTPUT_8051
    Output set as push-pull _SPI_OUTPUT_PUSH_PULL
    Output set as open-drain _SPI_OUTPUT_OPEN_DRAIN
Notes:
  • Some MCUs do not support advanced configuration of the SPI module. Please consult appropriate datasheet.
  • Advanced polarity and phase settings are supported by all MCU's, while output modes and SPI clock speeds by ATMEL MCU's.
    Bear in mind that not all of the SPI clock speeds are supported by all MCU's. Please, consult appropriate datasheet before using SPIx_Init_Advanced routine.

Requires

MCU must have SPI module.

Example
// SPI configuration for ATMEL MCU's: clock = Fosc/4 , clock IDLE state low, data transmitted at low to high clock edge and output mode 8051:
SPI1_Init_Advanced(_SPI_FCY_DIV4 | _SPI_CLK_IDLE_LO | _SPI_CLK_IDLE_2_ACTIVE | _SPI_OUTPUT_8051)

// SPI configuration for Silicon Laboratories MCU's: clock = 100000, clock IDLE state low and data transmitted at low to high clock edge:
SPI1_Init_Advanced(100000, _SPI_CLK_IDLE_LO | _SPI_CLK_IDLE_2_ACTIVE)

SPIx_Read

Prototype

unsigned short SPIx_Read(unsigned short buffer);

Returns

Received data.

Description

Reads one byte from the SPI bus.

Parameters :

  • buffer: dummy data for clock generation (see device Datasheet for SPI modules implementation details)

Requires

SPI module must be initialized before using this function. See SPIx_Init and SPIx_Init_Advanced routines.

Example
// read a byte from the SPI bus 
unsigned short take, dummy1;
...
take = SPI1_Read(dummy1);

SPIx_Write

Prototype

void SPIx_Write(unsigned short wrdata);

Returns

Nothing.

Description

Writes byte via the SPI bus.

Parameters :

  • wrdata: data to be sent

Requires

SPI module must be initialized before using this function. See SPIx_Init and SPIx_Init_Advanced routines.

Example
// write a byte to the SPI bus
char buffer;
...
SPI1_Write(buffer);

SPI_Set_Active

Prototype

void SPI_Set_Active(char (*read_ptr)(char), void(*write_ptr)(char));

Returns

Nothing.

Description

Sets the active SPI module which will be used by the SPI routines.

Parameters :

Requires

Routine is available only for MCUs with two SPI modules.

Used SPI module must be initialized before using this function. See SPIx_Init and SPIx_Init_Advanced routines.

Example
SPI_Set_Active(&SPI2_Read); // Sets the SPI2 module active 

SPI_Read

Prototype

unsigned short SPI_Read(unsigned short buffer);

Returns

Received data.

Description

Reads one byte from the SPI bus.

This is a generic routine which uses the active SPI module previously activated by the SPI_Set_Active routine.

Parameters :

  • buffer: dummy data for clock generation (see device Datasheet for SPI modules implementation details)

Requires

You need MCU with hardware integrated SPI.

SPI must be initialized and communication established before using this function. See SPIx_Init_Advanced or SPIx_Init.

Example
short take, buffer;
...
take = SPI_Read(buffer);

SPI_Write

Prototype

void SPI_Write(unsigned short data_);

Returns

Nothing.

Description

Writes byte via the SPI bus.

This is a generic routine which uses the active SPI module previously activated by the SPI_Set_Active routine.

Parameters :

  • wrdata: data to be sent

Requires

You need MCU with hardware integrated SPI.

SPI must be initialized and communication established before using this function. See SPIx_Init_Advanced or SPIx_Init.

Example
// write a byte to the SPI bus
char buffer;
...
SPI_Write(buffer);

Library Example

The code demonstrates how to use SPI library functions for communication between SPI module of the MCU and Microchip's MCP4921 12-bit D/A converter

// DAC module connections
sbit DAC_CS at P3_4_bit;
// End DAC module connections

unsigned int value;

// DAC increments (0..4095) --> output voltage (0..Vref)
void DAC_Output(unsigned int valueDAC) {
  char temp;

  DAC_CS = 0;                            // select MCP4921

  // Send High Byte
  temp = (valueDAC >> 8) & 0x0F;         // Store valueDAC[11..8] to temp[3..0]
  temp |= 0x30;                          // Define DAC setting http://ww1.microchip.com/downloads/en/DeviceDoc/21897B.pdf#page=18&zoom=100
  SPI1_Write(temp);                      // Send high byte via SPI

  // Send Low Byte
  temp = valueDAC;                       // Store valueDAC[7..0] to temp[7..0]
  SPI1_Write(temp);                      // Send low byte via SPI

  DAC_CS = 1;                            // deselect MCP4921
}

void main() {

  DAC_CS = 1;                            // deselect MCP4921
  SPI1_Init();                           // Initialize SPI module
  
  value = 2048;                          // When program starts, DAC gives
                                         //   the output in the mid-range

  while (1) {                            // Endless loop

    if ((!P0_0_bit) && (value < 4095)) { // If P0.0 button is pressed
      value++;                           //   increment value
    }
    else {
      if ((!P0_1_bit) && (value > 0)) {  // If P0.1 button is pressed
        value--;                         //   decrement value
      }
    }
    
    DAC_Output(value);                   // Send value to DAC chip
    Delay_ms(1);                         // Slow down key repeat pace
    
  }
}

HW Connection

SPI connection

SPI HW connection

Copyright (c) 2002-2013 mikroElektronika. All rights reserved.
What do you think about this topic ? Send us feedback!
Want more examples and libraries? 
Find them on LibStock - A place for the code