SPI For Multiprocessor Communication
SPI For Multiprocessor Communication
Multiprocessor
Communication
Lecture 6
SPI Protocol Introduction
◼ It is a Master-Slave communication protocol
where a master device can communicate with
number of slave devices
◼ Slave devices cannot communicate directly
with each other
◼ Slaves devices can only communicate with
each other via Master chip
3 / 50
SPI Features
◼ Full-duplex, Three-wire Synchronous Data
Transfer
◼ Master or Slave Operation
◼ LSB First or MSB First Data Transfer
◼ Seven Programmable Bit Rates
◼ End of Transmission Interrupt Flag
◼ Write Collision Flag Protection
◼ Double Speed (CK/2) Master SPI Mode
4 / 50
Interfaces - SPI
◼ The SPI bus is a synchronous serial data link
◼ Master generates clock, selects slave device using Select
Slave
◼ Data can be transferred in both directions simultaneously
5 / 50
Interfaces – SPI (Multiple Slaves)
◼ If multiple slave devices exist, the master generates
a separate slave select for each slave
6 / 50
Interfaces – SPI (Single Slave)
7 / 50
Interfaces – SPI (Multiple Slaves)
8 / 50
Associated PINs with SPI
9 / 50
SPI Protocol in Atmega16 (pins)
◼ SPI uses only two pins/lines for data transfer
MOSI(master out slave in) and MISO(master in slave
out)
10 / 50
Working of SPI
◼ SPI consists of two shift registers one in the
master and other in the slave side
11 / 50
Working of SPI (contd.)
◼ Serial out-pin of the master shift register is
connected to the serial in-pin of the slave register by
MOSI
◼ Serial in-pin of the master register is connected to
the serial out-pin of the slave register by MISO
12 / 50
Working of SPI (contd.)
13 / 50
Working of SPI (contd.)
Master Generates 7th clock pulse
14 / 50
Working of SPI
15 / 50
Working of SPI (contd.)
◼ Master clock generator provides the clock to the shift
registers in both master and slave
16 / 50
Working of SPI (contd.)
◼ After 8-clock pulses the data is transmitted to the other
shift register
17 / 50
Clock Polarity and Phase in SPI
◼ Master and slave(s) must agree on clock polarity and
phase with respect to data
◼ Freescale (Motorola) names these operations as
CPOL(clock polarity) and CPHA (clock phase) respectively
and Atmel has adopted this convention
18 / 50
Clock Polarity and Phase (Summary)
◼ At CPOL=0 base value of the clock is zero
◼ At CPOL=1 base value of the clock is one
◼ CPHA=0 means sample on the leading(first) edge
◼ CPHA=1 means sample on the trailing(second) edge
◼ If the base value of the clock is zero than leading(first) edge is a rising
edge
◼ If the base value of the clock is one than leading(first) edge is a falling
edge
23 / 50
SPI Programming in AVR(Fuse Bit)
◼ In AVR there is a bit associated for enabling/disabling
SPI peripheral in fuse bits
◼ It is 5th bit in the fuse high byte and by default it is set i.e.
SPI is enabled by default (for fuse bits by set we mean
that it is programmed zero since fuse bits works on
inverse logic)
25 / 50
SPI Programming in AVR(Registers)
◼ In AVR there are following three registers
associated with SPI
❑ SPCR (SPI Control Register)
❑ SPSR (SPI Status Register)
❑ SPDR (SPI Data Register)
26 / 50
SPI Registers
◼ SPCR(SPI Control Register)
}
27 / 50
SPCR(SPI Control Register) contd.
◼ SPCR(SPI Control Register)
29 / 50
SPI Registers
◼ SPCR(SPI Control Register)
30 / 50
SPI Clock Speed
31 / 50
SPCR(SPI Control Register)
32 / 50
SPI Registers
◼ SPSR(SPI Status Register)
33 / 50
SPI Registers
◼ SPDR (SPI Data Register)
Summary
❑ You cannot write to SPDR before last byte is not
transmitted completely, otherwise collision will
happen
❑ You can read the received data before another
byte is received completely
35 / 50
Master Mode (Settings) - STEPS
◼ Enable SPI by setting bit SPEN to one
◼ For master mode set MSTR bit in SPCR as one
◼ Set the SCK frequency by setting the values of
SPIX, SPR1 and SPR2
◼ Select the data order by controlling the value of
DORD
◼ Select the polarity of the clock
◼ Select the phase of the clock
◼ Enable the interrupt by setting SPIE as one if
you want to use interrupt
36 / 50
Master Mode (Exchanging data) - Tx
◼ Select the slave device by pulling its SS pin low
◼ Make MOSI Pin (PB.5) as output
◼ Write a byte to the SPI data register (SPDR), it
will start the data exchange by starting the SPI
clock generator
◼ After shifting the last bit, the SPI clock
generator stops and SPIF flag changes to one
◼ The byte in the master shift register and the
byte in slave shift register are exchanged after
the last clock
37 / 50
Master Mode (Exchanging Data) - Rx
◼ To get the received data, byte should be read
from SPDR before the next byte arrives
◼ We can use interrupt or pole the SPIF to
know when a byte is exchanged
◼ If we want to send multiple byte data , master
continues to shift next byte by writing it into
SPDR
38 / 50
Master Mode (SS Pin)
◼ When the SPI is configured as a Master (MSTR in
SPCR is set), the user can determine the direction
of the SS pin
◼ If SS is configured as an output, the pin is a general
output pin which does not affect the SPI system.
Typically, the pin will be driving the SS pin of the
SPI Slave.
◼ If SS is configured as an input, it must be held high
to ensure Master SPI operation
◼ If the SS pin is driven low when it is configured as
an input, the SPI system will clear the MSTR bit in
SPCR register. This is because the SPI system
interprets that it is being selected as slave by
another master and is about to send data.
39 / 50
Slave Mode (Setting) - STEPS
◼ Enable the SPI by setting the SPEN bit
◼ Set the MSTR bit to zero to make it a slave
◼ There is no need to set the SCK frequency since
the clock is generated by the master
◼ Set the SPI mode (clock polarity, clock phase) and
data direction to match the SPI mode and data
direction of the master
◼ When AVR is used as slave, the function of the
SPI interface depends on the SS pin.
40 / 50
Slave Mode (Setting) - STEPS
◼ Make MISO pin (PB.6) as output
◼ When the SS pin is driven low, the data
will be shifted by incoming clock pulses on
SCK pin
◼ SPIF changes to one when the last bit of a
byte has been shifted completely
41 / 50
Master Slave Connections
Master Slave
MOSI MOSI
MISO MISO
SCK SCK
SS SS
42 / 50
Master Multiple Slaves
Slave
MOSI
MISO
Master SCK
SS
MOSI
MISO
SCK
SS
SS 1 Slave
MOSI
MISO
SCK
SS
43 / 50
Associated PINs with SPI
44 / 50
Example Master Side
◼ Write an AVR program (without Interrupt) to initialize the SPI for the
Master, mode 0, with CLCK frequency=fck/16, and then transmit “G”
via SPI repeatedly. The received data should be displayed on Port A
#include <avr/io.h>
#define SS 4
#define MOSI 5
#define SCK 7
int main()
{ //DDRB=_BV(SS) | _BV(MOSI) | _BV(SCK); //~(_BV(bit));
DDRB=(1<<SS)|(1<<MOSI)|(1<<SCK); //SS, MOSI and SCK are output
DDRA=0xFF; //PORTA is output
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0); //enable SPI as master
PORTB&=0xEF; // Select SS 1110 1111
while(1) //do for ever
{
SPDR='G'; //start transmission
while(!(SPSR&(1<<SPIF))); //wait transfer finish
PORTA=SPDR; //move received data to PORTA
SPSR = SPSR | 1<< SPIF ; // clearing Flag
}
} AVR_SPI_Master_ExampleShort
45 / 50
Example Slave Side
◼ Write an AVR program to initialize the SPI for the slave, mode 0,
with CLCK frequency=fck/16, and then transmit “A” via SPI
repeatedly. The received data should be displayed on Port A
#include <avr/io.h>
#define MISO 6
int main()
{
DDRB=(1<<MISO); //MISO is output
DDRA=0xFF; //PORTA is output
SPCR=(1<<SPE); //enable SPI as slave
while(1) //do for ever
{
SPDR=‘A'; //start transmission
while(!(SPSR&(1<<SPIF))); //wait transfer finish
PORTA=SPDR; //move received data to PORTA
SPSR = SPSR | 1<< SPIF ; // clearing Flag
}
46 / 50
Assignment
MASTER:
◼ Write an AVR program to initialize the SPI for master mode 0,
with the CLCK frequency=Fosc/8.
❑ Read data from PORTD and transmit this data to slave if PIN0 of
PORTC is set.
❑ Received Data from slave should be displayed on PORTA using SSD.
❑ Use PIN1 of PORTC to refresh data
❑ Use interrupt to receive data.
SLAVE:
◼ Write an AVR program to initialize the SPI for slave mode 0.
❑ Read data from PORTC and transmit this data to master.
❑ Received Data from master Should be displayed on PORTA.
❑ Use Interrupt to receive data
47 / 50
ISIS
48 / 50
Master Code
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char x=0,data=0;
void main()
{ SREG|=0x80; //Enable Global Interrupt
SPCR=0xD1; //SPI,SPI interrupt and master enabled.
SPSR=0x01; //SPI2X set to double transfer speed
DDRB=0xB0; //SCK,SS and MOSI output
DDRA=0xFF;
DDRC=0x00;
DDRD=0x00;
PORTB|=0x10; //SS driven HIGH 0001 0000
while(1)
{
while(!(PINC&0x02));
while(!(PINC&0x01))
{
PORTA=PIND; // Receive data
}
PORTB&=0xEF; // Select SS 1110 1111 ISR(SPI_STC_vect)
data=PIND; {
SPDR=data; PORTA=SPDR;
} }
} 49 / 50
Slave Code
#include <avr/io.h>
#include <avr/interrupt.h>
unsigned char data=0;
void main()
{
SREG|=0x80; //Enable Global Interrupt
SPCR=0xC0; //SPI and SPI interrupt.
SPSR&=0xFE; //SPI2X set to double transfer speed
DDRB=0x40; //SCK,SS and MOSI input and MISO output
DDRA=0xFF;
DDRC=0;
PORTA=0;
while(1)
{
while(!(PIND&0x02));
while(!(PIND&0x01))
{
PORTA=PINC; ISR(SPI_STC_vect)
} {
data=PINC; PORTA=SPDR;
SPDR=data;
}
}
}
50 / 50