In a previous module we looked at using one serial communication module on the PIC microcontroller which is the USART module. In this tutorial we look at using one of the other serial communication module of the PIC32 microcontroller, the SPI module.

PIC32 SPI Module

The serial peripheral interface or SPI module is another type serial communication protocol available on the PIC microcontroller. The SPI module is used when you want high speed and reliable communication on a PIC microcontroller with some device using the same protocol usually located on the same board as the microcontroller. Things such as SD cards and LCDs use the SPI protocol.

Unlike USART where a single device talks to another device, in SPI communications there is one device called a master which generates the clock signal and can communicate with multiple other devices called the slave.

The SPI module is a full-duplex communication system meaning it can both send and receive data at the same time. It is a synchronous communication protocol.

The SPI protocol uses 4 lines for communication. A line for clocking (SCK), one line for sending data out (SDO), one line for receiving data (SDI) and another line for selecting the slave device (SS).

Since the SPI protocol can access multiple slaves, it is able to do so by simply adding additional slave select lines to the master.

SPI can run at very fast speeds and for the PIC32 it is not uncommon to run the SPI bus at speeds of 20 or 25 MHz such as when interfacing with SD cards. Though lower speeds such as between 1 MHz and 10 MHz is more common.


Connections

The MCP4131 is connected to the SPI1 bus. The output of the digipot is connected to an LED.


C Program

/*
 * File: Main.c
 * Author: Armstrong Subero
 * Processor: PIC32MX270F256D w/Ext OSC @ 4MHz, PLL to 48 MHz, 3.3v
 * Program: 10_SPI
 * Compiler: XC32 (v1.44, MPLAX X v4.00)
 * Program Version: 1.0
 *                             
 * Program Description: This Program Allows PIC32MX270F256D to use SPI1 module
 *                      which is used to control a MCP4131 digital potentiometer
 * 
 * Hardware Description: An MCP4131 digipot is connected to SPI1
 * 
 * Change History:
 *
 * Author             Rev     Date          Description
 * Armstrong Subero   1.0     03/04/2018    Initial Release.
 * 
 *                      
 * Created April 3rd, 2018, 6:05 PM
 */

/*******************************************************************************
 Includes and defines
*******************************************************************************/
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include "PIC32MX270_STD.h"
#include "Delay.h"
#include "spi1.h"

#define LED LATBbits.LATB14


/*******************************************************************************
* Function Name: digiPot_write(uint8_t i)
*
* Specification: writes a  value to the digipot
*******************************************************************************/
void digiPot_write(uint8_t i)
{
    // Set SS Low
    LATBbits.LATB1 = 0;
    delay_ms(1);
    
    // Slave address
    SPI1_Exchange8bit(0x00);
    
    // Data
    SPI1_Exchange8bit(i);
    
    // Set SS High
    LATBbits.LATB1 = 1;
    delay_ms(1);
}



/*******************************************************************************
* Function Name: void initMain (void)
*
* Specification: initializes main
*
*******************************************************************************/
void initMain(void)
{  
    uc_init();                    // initialize microcontroller
    TRISBbits.TRISB1 = 0;         // set PINB1 as output
    
    // unlock PPS
    systemReg_Unlock();
    CFGCONbits.IOLOCK = 0;

    RPC5Rbits.RPC5R = 0x0001;     //RC5->UART1 TX
    RPB11Rbits.RPB11R = 0x0003;   //RB11->SDO1;

    // lock PPS
    CFGCONbits.IOLOCK = 1; 
    systemReg_Lock();
    
    SPI1_init();                  // initialize SPI
}


/*******************************************************************************
* Function Name: void main (void)
*
* Specification: main function
*
*******************************************************************************/
void main(void) {
    
    initMain();         // initializes main function
    int i;              // variable for digipot value
    
    while(1)
    { 
         for (i = 0; i <= 127; i++){ 
             digiPot_write(i);       // write value to digipot
             delay_ms(100);          // delay 100 ms
         } 
    }
}

The microcontroller connects to the MCP4131 and writes values from 0-127 of which the effect can be seen causing the LED gradually increase in brightness.


Link to Project

You can download the entire project here:

SPI Project

Leave a Reply

Your email address will not be published. Required fields are marked *