SPI Communication
Basic Operation
In Serial Peripheral Interface (SPI) Communication there is a master device and one or more slave devices. The microcontroller can be configured as either a master or a slave device.
The serial clock (SCK) signal is generated by the master. The clock line is also referred to as the SCLK or CLK line. The master receives data from the slave on the Master-Input-Slave-Output (MISO) line. The master sends data to the slave on the Master-Output-Slave-Input (MOSI) line. At any one time there is communication between the master and one slave. The master communicates with a slave by pulling the slave-select (SS) line of the slave low. The slave-select (SS) pin is sometimes also referred to as the chip-select (CS) pin. At the end of the communication the master pulls the SS line high.
The following SPI specifications can be used:
"SELECT" | select a slave |
"DESELECT" | deselect a slave |
"READ" | read from SPI device to input channel |
"WRITE" | write from output channel to SPI device |
"data" | write data to SPI device |
Only the master device specifies "SELECT" and "DESELECT". "READ" is used by input channels, "WRITE" by output channels, and data can be used by both input and output channels.
The specifications for the SPI devices that the microcontroller needs to communicate with can be given in the "SPI" option as "SPI"->{name1->{spec11,spec12,…},name2->{spec21,spec22,…},…}. The namei of the SPI device can take the following values:
name | microcontroller mode |
slave-select (SS) connection
|
"pin" | master | microcontroller's pin to SS on SPI device |
"label" | master | no connection, "SELECT" and "DESELECT" are not used |
"Master" | slave | microcontroller's SS pin to appropriate pin on master SPI device |
Possible names of SPI devices connected to the microcontroller.
The microcontroller's SPI channels:
Input and output SPI channels.
In an input channel, the suboption "Conversion" specifies how the data coming in needs to be converted and assigned to the input.
In an output channel, the suboption "Conversion" specifies how the output needs to be converted and sent out.
Example
The example is going to use an Arduino in master mode that both sends and receives data over the SPI bus. We will have an Arduino in slave mode that also sends and receives data. Thus the example covers both receiving and transmitting in both master and slave modes.
A potentiometer and a LED is connected to both the master and the slave. The master transmits its potentiometer value to the slave. The slave set the brightness of its LED based on this value. The master receives the potentiometer value of the slave and set the brightness of its LED using that value.
Pin or any other pin on the master can be used to select the slave. There must be no change in the other connections.
When the slave select (SS) line goes low, how does the slave know if the master is sending or requesting data to be sent? To disambiguate this, the first byte after the SS goes low is used to indicate if the master is going to read from the slave or write to the slave.
The potentiometer reads a value between and V. We are going to convert that to a value between and and send it over the SPI bus.
When the microcontroller receives the data byte which is in the range from to , we are going to convert it to a value between and before setting it as the LED's brightness.
There is no real need to convert from the value range to the range and then back again. It is done here to demonstrate how to specify the conversion, so that it can be adapted as needed.
Next let's specify the exchange sequence that the slave will see on the SPI bus. If it sees a writeToSlave byte it needs to read the next byte, and if it sees a readFromSlave byte, in loads the byte to the SPI bus for the master to read.
The master talks to one slave whose slave select pin is connected to pin on the master. To read or write, the master first selects the slave, sets up to either read or write data, does the operation, and deselects the slave.
Now we can specify up the input and output channels of the slave and embed its code.
Next we move on to the master.