SPI Library

The SPI module is available with all dsPIC30/33 and PIC24 MCUs. mikroC PRO for dsPIC30/33 and PIC24 provides a library for initializing the Slave mode and initializing and comfortable work with the Master mode. The dsPIC30/33 and PIC24 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
  • secondary prescaler 1:1
  • primary prescaler 64:1
  • Slave Select disabled
  • input data sampled in the middle of interval
  • clock idle state low
  • Serial output data changes on transition from active clock state to idle 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 mode16, unsigned sec_prescaler, unsigned pri_prescaler, 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, mode16, sec_prescaler, pri_prescaler, 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 mode16 determines the data length mode, which can be 8-bits (per transmitions cycle) or 16-bits.
Data Length Mode
Description Predefined library const
16-bit mode _SPI_16_BIT
8-bit mode _SPI_8_BIT
The parameter sec_prescaler determines the value of the secondary SPI clock prescaler. Used only in the Master Mode.
Secondary SPI Clock Prescaler Value
Description Predefined library const
Secondary Prescaler 1:1 _SPI_PRESCALE_SEC_1
Secondary Prescaler 1:2 _SPI_PRESCALE_SEC_2
Secondary Prescaler 1:3 _SPI_PRESCALE_SEC_3
Secondary Prescaler 1:4 _SPI_PRESCALE_SEC_4
Secondary Prescaler 1:5 _SPI_PRESCALE_SEC_5
Secondary Prescaler 1:6 _SPI_PRESCALE_SEC_6
Secondary Prescaler 1:7 _SPI_PRESCALE_SEC_7
Secondary Prescaler 1:8 _SPI_PRESCALE_SEC_8
The parameter pri_prescaler determines the value of the primary SPI clock prescaler. Used only in the Master Mode.
Primary SPI Clock Prescaler Value
Description Predefined library const
Primary Prescaler 1:1 _SPI_PRESCALE_PRI_1
Primary Prescaler 4:1 _SPI_PRESCALE_PRI_4
Primary Prescaler 16:1 _SPI_PRESCALE_PRI_16
Primary Prescaler 64:1 _SPI_PRESCALE_PRI_64
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, _SPI_PRESCALE_SEC_1, _SPI_PRESCALE_PRI_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 buffer);

Description

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

Parameters
  • data_out: 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 data_out);

Description

Writes one 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 SPI_Read(unsigned buffer);

Description

Reads one 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
  • data_out: 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 = SPI_Read(buffer);
Notes

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

SPI_Write

Prototype

void SPI_Write(unsigned data_out);

Description

Writes one 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;
...
SPI_Write(buffer);
Notes

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

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
  SPI1_Init();                           // Initialize SPI 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
  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
  
  Chip_Select = 1;                       // Deselect DAC chip
}

void main() {

  ADPCFG = 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-2018 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