Advanced Microcontrollers: Using chipKIT Pro MX7

Project 0: MPLAB® X Integrated Development Environment

Using chipKIT™ Pro and MPLAB X

This project introduces you to the synthesis and analysis tools for producing microprocessor C code using the MPLAB® X integrated development environment (IDE) on the chipKIT™ Pro MX7 processor board.

Project 1: chipKIT™ Pro and I/O Control

Digital Input and Output

The purpose of this project is to familiarize you with the methods of reading from and writing to the input and output (I/O) pins of the PIC™32 microcontroller.

Project 2: chipKIT™ Pro and Delays

Software Timing Delays

The purpose of this project is to investigate methods of creating software time delays to pace processor operations.

Project 3: Using chipKIT™ Pro with Stepper Motors

Software-Based Finite State Machines

The purpose of this project is to investigate the application of software-based state machines to controlling the speed, direction of rotation, and operational mode of stepper motors.

Project 4: Using chipKIT™ Pro with Stepper Motors

PIC™32 Timers

The purpose of this project is to understand the operation of PIC™32 timers so that they can be used to implement a synchronized multi-rate periodic control system by polling the timer interrupt flag.

Project 5: chipKIT™ Pro and Interrupts

Process Speed Controls Using Interrupts

Explore detecting events using interrupts or by using preemption that implements a nested interrupt management scheme.

Project 6: Using chipKIT™ Pro to Control LCDs

Handshaking and LCD Control

Investigate concepts involving parallel communications and handshaking.

Project 7: chipKIT™ Pro and Serial Communication

Asynchronous Serial Communications

Learn about asynchronous communications and communicate with a microcontroller using a terminal emulation program to implement a point to point serial link between the chipKIT™ PRO MX7 and a PC.

Project 8: chipKIT™ Pro and Serial Communications

Synchronous I2C Serial Communications

Investigate concepts involving synchronous communications using a basic master-slave multi-drop network communications and use the I2C protocol to communicate with the 24LC256 I2C™ CMOS Serial EEPROM.

Project 8a: chipKIT™ Pro and Serial Communications

Synchronous SPI Serial Communications

Investigate synchronous communications with the SPI master-slave serial bus

Project 9: Controlling a DC Motor

PWM Using Timer Compare

Generate a proportional output using the output compare resource on the PIC®32MX processor to implement digital-to-analog conversion with pulse width modulation (PWM), thus controlling the speed of a DC motor.

Project 10: Using chipKIT™ Pro and DC Motors

Frequency Measurement Using Input Capture

Use the PIC™ 32 input capture to measure frequency to determine the speed of a DC motor.


Project 8a: chipKIT™ Pro and Serial Communications

Synchronous SPI Serial Communications

Using MPLAB® X Integrated Development Environment and chipKIT™Pro

Project 8a: Synchronous SPI Serial Communications


The purpose of this project is to investigate synchronous communications with the SPI master-slave serial bus. The project uses the Digilent® PmodJSTK™ joy stick module that has two LED outputs and three button inputs as well as a two axis joystick. Project 8a provides an alternative or supplement to Project 8 that investigates the I2C serial protocol.

Before you begin, you should:


Qty Description
1 Digilent chipKIT™Pro MX7 processor board with USB cable
1 Microchip MPLAB® X IDE
1 Microchip MPLAB® XC32 Compiler
1 Digilent PmodCLP™ Parallel Character LCD
1 Digilent PmodJSTK 2-axis joystick with buttons and LEDs
1 Digilent PmodTPH™ 6-pin test header
1 Logic analyzer (Digilent Analog Discovery™)

Synchronous Serial Communications

As discussed in Project 7, serial communications involve sending data one bit at a time as opposed to Project 6 where eight bits of data was sent at a time to the LCD. One of the biggest motivations for implementing serial communications is to minimize the number of processor pins and wires needed to pass data between two points. The longer the physical distance between the end points, the more expensive the communications media becomes.

This project will focus on the Serial Peripheral Interface (SPI) protocol, which is only one out of a list of many interfaces. As supplemental information for project 8, the Serial Protocols list provides a partial list of the available serial protocols. You may ask, “Why so many serial protocols?” The simple answer is that the protocols are optimized for data rates, physical media, physical distance, and connectivity. Some protocols are strictly for point-to-point communications, such as the asynchronous serial communications used in Project 7. Other protocols are for multi-drop applications where many senders can be connected to many receivers—an Ethernet network is an example.

As the term implies, a transmitter communicates between a sender and a receiver using a synchronizing clock. The synchronizing clock can be a separate signal or a transition embedded into the data waveform.

The handshaking theory behind asynchronous and synchronous communication is essentially the same: Point B needs to know when a transmission from Point A begins, when it ends, and if it was processed correctly. However, the difference lies in how the transmission is broken down. Think of the difference in terms of a friendly chat. With asynchronous communication you would need to stop after every word to make sure the listener understood your meaning, and knew that you were about to speak the next word. With synchronous communication, you would establish with your listener that you were speaking English, that you will be speaking words at measured intervals, and that you would utter a complete sentence, or paragraph, or extended soliloquy, before pausing to confirm understanding. Further, you would establish with your listener beforehand that any extraneous noises you make during the speech or between speeches (coughing, burping, hiccupping, etc.) should be ignored. Clearly, the second approach is much faster, even though initializing communication may take slightly longer. In fact, by replacing the start, stop, and parity bits around individual words as used for asynchronous communications with start, stop, and control (processing instructions and error checking) sequences around large continuous data blocks, synchronous communication is about 30% faster than asynchronous communication, before any other factors are considered. See the Synchronous Serial Communication Overview1 for more information.

There are two kinds of operating modes for multi-drop or network configurations; master–slave and peer-to-peer. Master-slave operates similarly to the microprocessor-LCD communication considered in Project 6. The microprocessor is the master and it dictates the data direction and the timing of the data exchange between the master and slave units. I2C (inter-integrated circuit communications—also sometimes written as I2C) and SPI are examples of master-slave networks supported directly by hardware in many microprocessors. I2C is a half-duplex scheme where the slave devices are enabled or selected by encoding data in a message sent by the master. SPI uses master-controlled dedicated device select signals along with separate data send and receive signals to enable simultaneous communications (full-duplex) between the master and a specific slave device.

Peer-to-peer communications on the other hand allows data exchange at any time and between any two communications nodes. Full-duplex UART communications is one example of peer-to-peer communications. RS-232, CAN, and Ethernet communications are additional examples of peer-to-peer communications.

The SPI Protocol

The SPI serial protocol has a higher data rate than does I2C because it can generally operate higher clock rates and is not limited to 8-bits per word. Although I2C requires only two wires (thus conserving processor pins—see Project 8) rather than four wires required by SPI, I2C has bandwidth overhead due to the time required for device selection by sending the ID as a serial byte. Unlike I2C, SPI has no device acknowledge capability.

SPI is a full-duplex synchronous serial communications bus protocol developed by Motorola, and it has become a de facto standard that has not been adopted by any national or international standards organizations. The SPI bus implements a master-slave communications scheme where the master device alone controls data that is exchanged with slave devices. The master device has exclusive control of the serial clock (SCK) signal that is used to clock the data to and from a slave device.

SPI requires four wires for full-duplex operation and supports only one master but multiple slave devices. The master writes data to the slave using the master-out-slave-in (MOSI) line. The slave devices are able to send data to the master over the master-in-slave-out (MISO) line. Other than the clock signal, all handshaking is handled by an explicit slave select (SS) or chip select (CS) signal.

Figures 1 and 2 illustrate the two common SPI bus connection configurations. Figure 1 shows that the multiple slave devices share SCK, MOSI, MISO signals. For this connection configuration, the slave devices are explicitly selected by multiple dedicated SS microprocessor outputs. This is the more common SPI connection configuration.

Figure 2 shows a daisy-chain configuration where slave devices share the SCK and SS signals. However, the MOSI and MISO signals are routed through a series of slave devices. Using this configuration, data intended for the last device in the chain must be clocked through the preceding slave devices. Data that is to be read from the first slave device in the chain must also be clocked through the slave devices that follow it in the chain. This additional data transfer time is the cost of conserving processor I/O pins used for enabling slave devices. Due to the excessive data transfer time for systems with many slave devices, this configuration is seldom used.

Figure 1. Parallel multiple slave SPI bus configuration with individual device select signals.
Figure 2. Daisy chain multiple slave SPI bus configuration with a common device select signal.

When the microprocessor is connected to a slave device that has both input and output capability using SPI, as data is clocked out of the master, data is clocked in from the slave device. This results in efficient data transfers for some slave devices. The loosely defined SPI interface does require careful consideration of the slave clock-data timing as well as using a microprocessor that can be configured to support various timing requirements. Figure 3 shows the clock-data time timing for the four SPI operating modes. The clock polarity (CPOL) controls the idle level of the SCK output from the master. If CPOL is high then the idle level of SCK is high. The clock phase (CPHA) specifies when the data is to be changed or written to MOSI by the master and MISO by the slave device. When CPHA is low, the data signal (MISO for master and MOSI for the slave) is sampled by the receiving device when SCK makes a transition from the idle level to the active level.

Table 1 provides to correlation between the conventional definitions of SPI mode CPHA and CPOL to the PIC®32 settings for clock edge (CKE) and clock polarity (CKP). It is important to match the master processor operation to what the slave device is expecting. For some designs, it is possible for different slave devices to expect the master to operate in modes that are not the same. The PIC32 operations modes can be changed during program execution but the modes should not be changed when the processor is actively clocking data on the SPI bus.

Figure 3. SPI timing modes.

Table 1. SPI SCK operational modes.

SPI Mode Active Level Sample Transition CPOL CPHA PIC32 CKP PIC32 CKE
0 (or 0,0) HIGH Idle to Active 0 0 0 1
1 (or 0,1) HIGH Active to Idle 0 1 0 0
2 (or 1,0) LOW Idle to Active 1 0 1 1
3 (or 1,1) LOW Active to Idle 1 1 1 0

SPI master-slave communications can be operated in either simplex or full-duplex modes. Simplex communications occur when the slave device can only send or receive data. Regardless of which device, master or slave, is sending the data, the master always provides the SCK signal. Although the phase and sample timing can differ between devices using SPI, the data is always active high (a high level represents a logical 1).

Data is sent and received by transferring the most significant bit (MSB) on the first clock pulse. We will define a transfer transaction as the exchange of data while the SS signal is continuously asserted in the active state (usually a low level.) For a specific transaction, if multiple bytes are to be transferred, the byte counter in the slave device is reset when the SS signal is asserted. There is no start and stop sequence or byte acknowledge like used with I2C. Data can be transferred as 8-, 16-, or 32-bit words. There is no limit to how much data can be transferred in a single transaction.

A data bit is shifted into the receiving device at the same time as the data bit is shifted out. Hence, once a word of data has been sent, the device has also received the next word. The SPI uses SCK clock edges to implement each bit transfer. At one SCK edge, each data sends a bit of data on the send line. The opposite clock edge a half of SCK clock cycle later, a data bit on the receive line is clocked into the receiving device. The specific clock edges are specified by the SPI mode of operation. The SCK signal can be asymmetrical as long as the period of the high or low state is greater than the inverse of two times the maximum data rate.

SPI Bus Hardware

We will be using the C32 peripheral library functions to set up the SPI hardware in the PIC32 processor. The SPI control register will be initialized for the case when the PIC32 is the master processor and the PmodJSTK is the slave device. The hardware configuration for this design is shown in Fig. 7 of the first tab on the right. The pin assignment uses SPI channel 1. A picture and functional block diagram of the PmodJSTK joystick module are shown in Figs. 8 and 9 of the orange tab as well as the pin assignments listed in Table 7. The PmodJSTK provides access to a two-axis joystick with a switch that is activated when the joystick control is pressed as well and two momentary contact push buttons. The joystick position is indicated with a 10-bit reading, where a value of roughly 512 indicates the center joystick position. There are two LEDs provided on the PmodJSTK that can be used to output status indication.

Reading the joystick positions and button status of the PmodJSTK requires a 5-byte data exchange, as shown in Table 2. The joystick position for the X and Y axis is indicated by combination of the low byte with the least significant two bits of the high byte. The status of the three buttons provided by the fifth byte is assigned to the bit positions shown in Table 3. The LEDs can be controlled with a single byte data exchange by setting the bits of the LED control byte, as shown in Table 4. Note that the most significant bit of the LCD Control byte is always set to a one.

Table 2. The SPI data format for reading and writing to PmodJSTK.

Byte Number 1 2 3 4 5
Read Byte X axis — low byte X axis — high byte Y axis — low byte Y axis — high byte Button Status
Write Byte LED Control Not Used Not Used Not Used Not Used

Table 3. PmodJSTK button status byte.

Bit number 7 6 5 4 3 2 1 0
Assignment 0 0 0 0 0 BTN2 BTN1 Joystick

Table 4. PmodJSTK LED control byte.

Bit number 7 6 5 4 3 2 1 0
Assignment 1 0 0 0 0 0 LED2 LED1

The reference manual for the PmodJSTK suggests that the clock speed be restricted to less than 1 MHz. The PmodJSTK byte counter is reset each time the SS signal is asserted low. The manual also suggests that there be a 15 μs delay inserted after the SS signal is asserted and when the SCK begins to clock the data transfer. It also suggests that a 10 μs delay be used between transferring data bytes.

PIC32 SPI Programming

As discussed above, a microprocessor must be able to support numerous SPI mode configurations. Although it is possible and frequently done, the SPI protocol can be implemented by any microprocessor using the method of bit-banging I/O pins. The PIC32 processor provides a hardware implementation of the SPI protocol that results in reduced software and faster data transfers. The SPIxCON register controls the SPI functionality where “x” ranges from 1 to 4, indicating the SPI channel. For this project, we will focus only on the SPI channel 1 configuration where the PIC32 processor is the SPI master.

The reader is referred to the Section 23 of the PIC32 reference manual for a complete description of the PIC32 SPI operation. The approach to configuring the SPI control register will be to identify the control bits that need to be set to configure the PIC32 processor as the SPI master for 8-bit operation. Neither SPI interrupts nor SPI extended buffers will be used. The SPI control register bit definitions mnemonics are listed in the ppic32mx.h system header file, as shown in Table 5. Shaded rows in Table 5 are not used in the configuration for this design. After reset, the default state of all SPIxCON bits is zero.

Table 5. SPIxCON control bit definitions.

Functionality Mnemonic
SPI CPU select
0 — CPU is Slave : 1 — CPU is Master
SPI clock polarity
0 — Low idle state : 1 — High idle state
Slave Select Enable SPICON_SSEN
SPI clock edge select for data change
0 — idle to active state : 1 — active to idle state
Input sampled time relative to data output time
0 — middle of interval : 1 — end of interval
[Mode16:Mode32] [00]–8 bit, [10]–16 bit, [01]-32 bit SPICON_MODE16
[Mode16:Mode32] [00]–8 bit, [10]–16 bit, [01]-32 bit SPICON_MODE32
Stop SPI when CPU is idle SPICON_SIDL
Freeze SPI operation for CPU exception SPICON_FRZ
SPI peripheral On/Off control
0 — OFF : 1 — ON
Frame Sync pulse edge SPICON_SPIFE
Frame Sync polarity active high SPICON_FRMPOL
Frame Sync pulse input control on SS pin SPICON_FRMSYNC
Frame Support enable SPICON_FRMEN

The C32 peripheral library documentation specifies three arguments to be passed by the SpiChnOpen function. The first argument selects the SPI channel and is set to either 1 or 2. The second argument is a 32-bit value that programs the SPI1CON register to select the SPI operating mode. The configuration argument is generated using the mnemonics listed in Table 5 that are joined with the logical OR operation. Including the mnemonic in the configuration declaration sets the associated bit position to a one. The last argument is a value that is divided into the PIC32 peripheral clock to set the SPI clock rate. An example statement to open SPI channel 1 is:

Brg = PBCLK/(2 * MAX_SPI_CLOCK); // SPI bit rate generator - PBCLK = peripheral bus clock
SpiChnOpen(1, config, Bgr);

For this example, config equals (SPICON_ON | SPICON_MSTEN)|(SPICON_ON | SPICON_MSTEN) and brg is the peripheral bus clock divider for twice the maximum SPI clock rate. The SPI configuration explicitly turns on SPI1 operation as a SPI master. By default, the SPI setting is for 8-bit data transfers, SPI mode 1 (Table 1), data is sampled at the middle of to the transmission period, and the SDO (MOSI) pin is enable.

Exchanging data between the PIC processor and the slave device requires two C instructions: one instruction to send the data word out on the MOSI signal line and one C instruction to recover the data word just clocked in on the MISO signal. The C program code in Listing 1 shows one method to exchange data with the PmodJSTK. The DelayUs instruction is a call to a microsecond software delay function needed to implement a 10 μs delay as recommended in the joystick reference manual. The C instruction, SpiChnPutC(1),(BYTE) data_out), sends the single byte of data that is passed to this function by the calling function. It will wait until the data byte has been completely sent before returning to the JSTK_xfer function. Thus, the data that was shifted in from the MISO line is waiting to be read by the SpiChnGetC(1) function. The argument shown as “1” in both functions indicates SPI channel 1.

Listing 1. SPI single data byte exchange function for the PmodJSTK.

int JSTK_xfer(int data_out)
    SpiChnPutC(1,(BYTE) data_out);
    return SpiChnGetC(1);

The JSTK_xfer function would need to be called five times, as shown in Listing 2, to exchange all five bytes needed to read the PmodJSTK position and button status. Note that the SS signal, named JSTK_SEL, is asserted low followed by a 15 μs delay before transferring the first data byte. The byte sent to the PmodJSTK for the first exchange contains the LED setting control as described in Table 4. The value of the bytes sent on successive exchanges is not important as that data is ignored by the joystick controller.

Listing 2. SPI five data byte exchange function for the PmodJSTK.

void JSTK_getAll(int ledSt, BYTE *recv)
    JSTK_SEL = 0;
    *recv++ = JSTK_xfer(ledSt | 0x80);
    *recv++ = JSTK_xfer(0);
    *recv++ = JSTK_xfer(0);
    *recv++ = JSTK_xfer(0);
    *recv++ = JSTK_xfer(0);
    JSTK_SEL = 1;

Figure 5 is a screen capture of the first of the five-byte SPI communications with the joystick controller. Since the PIC32 was programmed to operate in SPI mode 1, the MISO signal line is sampled on the negative SCK transitions. This byte is sent to set the joystick LED 2 on and read the X-axis low byte as 0xF2.

Figure 5. Screen capture of the SPI SS, MOSI, MISO, and SCK signals for a single byte data exchange.

Project Tasks

Project Specifications

  1. Write a program the will read the PmodJSTK module and display the readings on the PmodLCP™ LED module. The specific requirements are:
    1. Program the SPI for a maximum clock speed of 100 kHz.
    2. Initialize the SPI channel 1 for master mode 1 operation.
    3. Display the values returned for the X and Y positions of the joystick on the top line of the LCD.
    4. Display the values of the three buttons on the bottom line of the LCD. Use 1 to indicate that the button is pressed.
    5. Each 205 ms, increment a counter from zero to three. Use the PmodJSTK LEDs to display a binary representation of the count. For example, if the count is two, LED 1 will be off and LED 2 on.
  2. Capture an SPI transaction that displays the SPI signals SS, MOSI, MISO, and SCK.

Project Testing

  1. Run code to verify that the joystick LEDs light correctly.
  2. Move the joystick and observe the changes in values displayed on the LCD. Record the values display for the joystick in the positions listed in Table 6.

    Table 6. X- and Y-axis position values.

    X-axis position X-axis value Y-axis position Y-axis value
    Center   Center  
    Up   Right  
    Down   Left  
  3. Connect the logic analyzer to the PmodTPH pins 1 through 4 to display the four SPI signals SS, MOSI, MISO, and SCK.
  4. Capture the logic analyzer display for a 5-byte transaction with the PmodJSTK, as shown in Fig. 6.
  5. Figure 6. Screen capture of the SPI SS, MOSI, MISO, and SCK signals for a five byte data exchange.

    The above screenshots are of Digilent WaveForms running on Microsoft Windows 7.

Try It on Your Own!

  1. List the strengths of SPI communications over I2C.

    1. Widespread support and IP available.
    2. Full-duplex communication.
    3. Higher throughput than I2C or SMBus.
    4. Complete protocol flexibility for the bits transferred (i.e., not limited to 8-bit words).
    5. Simple protocol to implement and understand.
    6. Typically no external circuitry required (like pull-up resistors for I2C).
    7. System clocked by a master meaning that precision oscillators and PLL not needed.
    8. Addressing not needed (decreases complexity and helps throughput by not sending an address for each communication).
    9. Transceivers are not needed.
    10. Serial protocol uses fewer physical connections than parallel interfaces.
    11. Mostly shared lines for multiple devices (except the separate SS lines for each device).
  2. List the weaknesses of SPI communications.

    1. No standards body governs SPI as an official protocol.
    2. The more devices you have, the more pins and connections necessary.
    3. No hardware flow control.
    4. No hardware slave acknowledgment (the master could be “talking” to nothing and not know it).
    5. Does not support a multi-master architecture.
    6. Only handles relatively short distances (meant for on-PCB communication mostly).
  3. Why is SPI considered a communications bus and not a network?

    1. There is no capability to communicate between two devices that each can operate at the bus master.
    2. There is no mechanism to detect a bus conflict if different masters attempt to simultaneously acquire the bus.
  4. Why does SPI normally have higher data transfer rates?

    1. No overhead to select the slave device.
    2. Full-duplex operation.
    3. Higher maximum SCK speeds.
    4. No ACK bit for each 8 data bits.
  5. Is it necessary for the SPI SCK signal to have a 50% duty cycle?

    • ANSWER: No. However, the minimum duty cycle is constrained to be greater than the period of 2 times the maximum SPI clock rate.
  • Other product and company names mentioned herein are trademarks or trade names of their respective companies. © 2014 Digilent Inc. All rights reserved.