SPI Library

The SPI module is available with all PIC32 MCUs. mikroC PRO for PIC32 provides a library for initializing the Slave mode and initializing and comfortable work with the Master mode. The PIC32 can easily communicate with other devices via SPI: A/D converters, D/A converters, MAX7219, LTC1290, etc.

  Important :

Library Routines

Generic Routines

SPIx_Init

Prototype

void SPIx_Init();

Description

Configures and initializes the SPI module with default settings.

Default settings:

  • Master mode.
  • 8-bit data mode.
  • Serial clock set to System clock/64.
  • Slave Select disabled.
  • Input data sampled in the middle of interval.
  • Clock idle state low.
  • Serial output data changes on transition from idle clock state to active clock state

Parameters

None.

Returns

Nothing.

Requires

MCU must have the SPI1 module.

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

SPI library routines require you to specify the module you want to use. To select the desired SPI module, simply change the letter x in the routine prototype for a number from 1 to 3.

Number of SPI modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

Switching between the SPI modules in the SPI library is done by the SPI_Set_Active function (both SPI modules have to be previously initialized).

SPIx_Init_Advanced

Prototype

void SPIx_Init_Advanced(unsigned master_mode, unsigned data_mode, unsigned clock_divider, unsigned slave_select, unsigned data_sample, unsigned clock_idle, unsigned edge);

Description

Configures and initializes the SPI module with user defined settings.

Parameters

Parameters master_mode, data_mode, clock_divider, slave_select, data_sample, clock_idle and determine the working mode for SPI.

The master_mode parameter determines the working mode for SPI module.

Master/Slave mode
Description Predefined library const
Master mode _SPI_MASTER
Slave mode _SPI_SLAVE

The parameter data_mode determines the data length mode, which can be 8-bits (per transmitions cycle), 16-bits or 32-bits.

Data Length Mode
Description Predefined library const
32-bit mode _SPI_32_BIT
16-bit mode _SPI_16_BIT
8-bit mode _SPI_8_BIT

The parameter clock_divider determines the value of the SPI clock speed. Used only in the Master Mode.

Clock Divider Value
Valid values from 2 to 1024

The parameter slave_select determines whether the Slave Select (SS) pin is used in communication. Valid in the Slave Mode only.

Slave Select Enable/Disable
Description Predefined library const
SS used for the Slave mode _SPI_SS_ENABLE
SS not used for the Slave mode _SPI_SS_DISABLE

The parameter data_sample determines the sample moment (phase) of input data.

Data Sampling Moment
Description Predefined library const
Data sampled in the middle of data output time _SPI_DATA_SAMPLE_MIDDLE
Data sampled at end of data output time _SPI_DATA_SAMPLE_END

The parameter clock_idle determines the behaviour of the SPI clock (CLK) line in IDLE phase.

Clock Polarity
Description Predefined library const
IDLE state is Lo, ACTIVE state is Hi _SPI_CLK_IDLE_LOW
IDLE state is Hi, ACTIVE state is Lo _SPI_CLK_IDLE_HIGH

The parameter edge determines on which clock edge data is considered to be valid.

Clock Edge
Description Predefined library const
Data is valid on ACTIVE-to-IDLE transition _SPI_ACTIVE_2_IDLE
Data is valid on IDLE-to-ACTIVE transition _SPI_IDLE_2_ACTIVE
Returns

Nothing.

Requires

MCU must have the SPI module.

Example
// Set SPI1 to the Master Mode, data length is 16-bit, clock = Fcy (no clock scaling), data sampled in the middle of interval, clock IDLE state high and data transmitted at low to high clock edge:
SPI1_Init_Advanced(_SPI_MASTER, _SPI_16_BIT, 1, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE);
Notes

SPI library routines require you to specify the module you want to use. To select the desired SPI module, simply change the letter x in the routine prototype for a number from 1 to 3.

Number of SPI modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

SPIx_Read

Prototype

unsigned SPIx_Read(unsigned long buffer);

Description

Reads one double word, word or byte (depending on mode set by init routines) from the SPI bus.

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

Received data.

Requires

Routine requires at least one SPI module.

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

Example
// read a byte from the SPI bus 
char take, buffer;
...
take = SPI1_Read(buffer);
Notes

SPI library routines require you to specify the module you want to use. To select the desired SPI module, simply change the letter x in the routine prototype for a number from 1 to 3.

Number of SPI modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

SPIx_Write

Prototype

void SPIx_Write(unsigned long data_out);

Description

Writes one double word, word or byte (depending on mode set by init routines) via the SPI bus.

Parameters
  • data_out: data to be sent
Returns

Nothing.

Requires

Routine requires at least one SPI module.

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

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

SPI library routines require you to specify the module you want to use. To select the desired SPI module, simply change the letter x in the routine prototype for a number from 1 to 3.

Number of SPI modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

SPI_Set_Active

Prototype

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

Description

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

Parameters

Parameters :

Returns

Nothing.

Requires

Routine is available only for MCUs with multiple SPI modules.

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

Example
SPI_Set_Active(SPI1_Read, SPI1_Write); // Sets the SPI1 module active
Notes

Number of SPI modules per MCU differs from chip to chip. Please, read the appropriate datasheet before utilizing this library.

SPI_Read

Prototype

unsigned SPIx_Read(unsigned long buffer);

Description

Reads one double word, word or byte (depending on mode set by init routines) 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)
Returns

Received data.

Requires

Routine requires at least one SPI module.

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

Example
// read a byte from the SPI bus 
char take, buffer;
...
take = SPI1_Read(buffer);
Notes

None.

SPI_Write

Prototype

procedure SPI_Write(data_out : dword);

Description

Writes one double word, word or byte (depending on mode set by init routines) via the SPI bus.

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

Parameters
  • data_out: data to be sent
Returns

Nothing.

Requires

Routine requires at least one SPI module.

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

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

None.

Library Example

The code demonstrates how to use SPI library functions for communication between SPI2 module of the MCU and MCP4921 DAC chip.

Copy Code To ClipboardCopy Code To Clipboard
// DAC module connections
sbit Chip_Select at LATF0_bit;
sbit Chip_Select_Direction at TRISF0_bit;
// End DAC module connections

unsigned int value;

void InitMain() {
  TRISB0_bit = 1;                        // Set RB0 pin as input
  TRISB1_bit = 1;                        // Set RB1 pin as input
  Chip_Select = 1;                       // Deselect DAC
  Chip_Select_Direction = 0;             // Set CS# pin as Output
  SPI2_Init();                           // Initialize SPI2 module
}

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

  Chip_Select = 0;                       // Select DAC chip

  // Send High Byte
  temp = (valueDAC >> 8) & 0x0F;         // Store valueDAC[11..8] to temp[3..0]
  temp |= 0x30;                          // Define DAC setting, see MCP4921 datasheet
  SPI2_Write(temp);                      // Send high byte via SPI

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

  Chip_Select = 1;                       // Deselect DAC chip
}

void main() {

  CHECON = 0x32;
  AD1PCFG = 0xFFFF;                      // Configure AN pins as digital

  InitMain();                            // Perform main initialization

  value = 2048;                          // When program starts, DAC gives
                                         //   the output in the mid-range

  while (1) {                            // Endless loop

    if ((RB0_bit) && (value < 4095)) {   // If RB0 button is pressed
      value++;                           //   increment value
    }
    else {
      if ((RB1_bit) && (value > 0)) {    // If RB1 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-2012 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