Catching a Bus: Basic Serial Communication Part 2, SPIFollow article
The modules I used to make a wireless remote-control unit for a mobile robot. In all, four types of serial bus are involved: UART and SPI for peripheral module-to-processor links; USB for communication with a PC during firmware development, and RF wireless for driving the robot.
Most modern peripheral device chips, such as sensors and motor drivers, communicate with a controller via a serial data bus. Microcontrollers usually support one or more of three basic types: UART, SPI and I2C. How do they work and which to choose? Last time, in Part 1 we looked at one of the earliest ‘digital’ asynchronous technologies initially developed for telegraphic communication; later adapted for linking teletypewriters to computers.
Serial Peripheral Interface (SPI)
For many years UART/RS-232 serial communication was the technology of choice for low-speed short-distance operation between computer processor units and peripherals such as printers. When the first microprocessor chips appeared, it became obvious that it was too slow and inefficient to meet the need for high-speed transfer of bulk data between devices. In the mid-1980s telecommunications company Motorola introduced the Serial Peripheral Interface or SPI. The SPI features synchronous clocking which means that the transmitter clock signal is supplied to the receiver via a separate wire. That alone accounts for a much-improved data rate relative to a UART-based link:
- No Start and Stop bits accompanying every transmitted data byte to allow the receiver to achieve ‘character-sync’.
- Much higher bit-clock speeds are possible because the receiver does not have to synchronise its clock with that of the transmitter.
The SPI port is also a lot less complex than a UART in terms of hardware. Despite this, it too offers full-duplex operation (simultaneous transmission and reception). Because the Master controls the data flow with the clock (SCLK), there is rarely any need for additional ‘hand-shaking’ signals such as RTS/CTS as defined in the RS-232 standard. Two UARTs usually operate in Master-Master mode and as each has completely independent send and receive circuits, their full-duplex operation is also independent. Now we can see from Fig.1 that SPI operation is not quite so flexible. A UART has separate transmit and receive shift registers, but the SPI makes do with one handling both send and receive functions.
One end of the link provides the clock for both transmission and reception so it becomes the Master, while the other end is, naturally enough, a Slave. It’s this common clock which enables a single shift register to both transmit a byte of serialised data from the MOSI pin and simultaneously receive a byte via the MISO pin. Both registers are clocked by the same signal: SCLK, and after eight pulses the Slave contains the byte from the Master and vice versa.
The timing diagram in Fig.2 provides a bit more detail on the relationship between the various signals as two bytes of data are exchanged between Master and Slave. A key feature to note is that data is ‘sampled’ or latched in by the receiver on one edge of a clock pulse (rising or falling) and changes on the other (falling or rising). It doesn’t matter which is used as long as one edge is not used for both actions. The other option available is to select the idle state of the clock (high or low). There are four permutations of these two setup parameters, each defining one mode of operation: Mode 0, 1, 2, and 3. Both Master and Slave must of course be set to use the same mode!
Generally, it will be the mode used by the Slave device, as set by the manufacturer which will determine how the Master’s SPI port is configured.
A Master with many Slaves
An embedded system is likely to control more than one sensor or actuator. A UART/RS-232 serial bus is really unsuitable for handling more than one device, and while modern MCUs often feature multiple UART channels, there are seldom enough. Most peripheral devices such as accelerometers, display panels and the like, may also need high-speed links too, perhaps with megabits per second speeds rather than kilobits. An SPI Slave device features a tri-state SDO pin which can be ‘turned-off’- made high-impedance - by taking its Select (SS) pin high. Any number of Slaves can operate with their SDO pins wired together providing the Master only activates (takes low) one SS signal at a time (Fig.3). The select signals from the Master MCU are provided by ordinary GPIO pins, one per Slave, driven by the SPI driver firmware programmed in by the user. The drawback with this scheme is that a large number of Slaves requires the same number of GPIO pins to be available. This could be a problem when you’re using a small format MCU chip with limited pins.
There is an alternative way of wiring the Slaves to a Master which doesn’t require a GPIO pin for each Slave. It involves connecting all the Slave data lines together in a ‘daisy-chain’: the MCU MOSI output is linked to the first Slave’s SDI whose SDO then goes to the second’s SDI pin and so on. The last SDO then returns to the MCU MISO pin. Sending a byte of data to the third device say, requires three bytes from the Master leaving the first and second Slaves with new data too. Not all chips with SPI ports can work this way of working though – datasheets will need to be examined closely.
Driver code for an MCU SPI port
The tiny fragment of dsPIC33E assembler code below transmits via MOSI, a byte of data held in register w0. At the same time a byte of data from the Slave is clocked in via MISO. Hence the receiver buffer-full flag is used to sense when both transmission and reception are complete.
UART v SPI
Asynchronous serial communication via a UART when both the data rate and the volume of data that needs to be transferred are both low. The classic situation is a Human-Machine Interface (HMI) where commands are entered via a keyboard and responses returned to a simple character display. If the channel is a few centimetres long between two chips on a board, then the two devices may be directly connected together. Otherwise, the addition of RS-232 buffer chips will allow a cable connection of a few metres (See Part 1).
The SPI port was developed only for inter-chip communication. Its hardware is very simple, it’s capable of very high speeds and is thus suitable for the movement of high volumes of data. A familiar application is when it’s used - in four-channel or QSPI form - as the conduit for transferring picture files from a digital camera to a removable SD Flash memory card.
The next part of this series will feature the construction of a twin-joystick wireless remote-control unit based on a selection of MikroElektronika Click modules and a dsPIC33E Clicker 2 MCU board running FORTHdsPIC (See heading photo). I’ll show how much extra code beyond the basic driver above is necessary to connect the Master (MCU) to one Slave (RF module) using an SPI link. In addition, a separate SPI channel will serve two Slaves (the joysticks).
Part 4: I2C communication interface
If you're stuck for something to do, follow my posts on Twitter. I link to interesting articles on new electronics and related technologies, retweeting posts I spot about robots, space exploration and other issues.