Вы находитесь на странице: 1из 44

AVR SPI Protocol for

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

* SCLK — Serial Clock (output from master)


* MOSI/SIMO — Master Output, Slave Input (output from master)
* MISO/SOMI — Master Input, Slave Output (output from slave)
* SS — Slave Select (active low; output from master)

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)

◼ It has a SS(slave select) pin. In master controller this pin


is not used. In slave controller this pin is connected with
master controller and is set low when master wants to
initiate communication

10 / 50
Working of SPI
◼ SPI consists of two shift registers one in the
master and other in the slave side

◼ A clock generator in the master generates the


clock for the shift registers

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.)

Master Generates 1st clock pulse

Master Generates 2nd clock pulse

13 / 50
Working of SPI (contd.)
Master Generates 7th clock pulse

Master Generates last (8th) 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

◼ Clock input of the shift register can be falling or rising


edge triggered (will be discussed shortly)

◼ Shift registers are 8-bit, it means that after 8 clock


pulses, the content of the two shift registers is
interchanged

◼ When a master wants to transmit 8-bit data it places the


data in the shift register and generates 8 clock pulses

16 / 50
Working of SPI (contd.)
◼ After 8-clock pulses the data is transmitted to the other
shift register

◼ When the master wants to receive the data, the slave


side should place the data on to the shift register and
after 8 clock pulses data will be received by the master
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

❑ At CPOL = 0 base value of the clock is zero


❑ At CPOL = 1 base value of the clock is one
❑ At CPHA = 0 means sample on the leading (first) edge
❑ At CPHA = 1 means sample on the trailing (second) edge

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)

❑ Bit 7 – SPIE: SPI Interrupt Enable


This bit causes the SPI interrupt to be executed if SPIF bit in the
SPSR Register is set and if the global interrupt enable bit in
SREG is set

Vector name for ISR of SPI Interrupt.


ISR(SPI_STC_vect) //Serial Transfer Complete
{

}
27 / 50
SPCR(SPI Control Register) contd.
◼ SPCR(SPI Control Register)

❑ Bit 6 – SPE: SPI Enable


When the SPE bit is written to one, the SPI is enabled. This bit must
be set to enable any SPI operations

❑ Bit 5 – DORD: Data Order


◼ When the DORD bit is written to one, the LSB of the data word is transmitted first.
◼ When the DORD bit is written to zero, the MSB of the data word is transmitted first.

❑ Bit 4 – MSTR: Master/Slave Select


This bit selects Master SPI mode when written to one, and Slave SPI
mode when written logic zero
28 / 50
SPCR(SPI Control Register) contd.

❑ Bit 3 – CPOL: Clock Polarity


When this bit is written to one, SCK is high when idle. When
CPOL is written to zero, SCK is low when idle

❑ Bit 2 – CPHA: Clock Phase


The settings of the Clock Phase bit (CPHA) determine if data is
sampled on the leading (first) or trailing (last) edge of SCK

29 / 50
SPI Registers
◼ SPCR(SPI Control Register)

❑ Bits 1, 0 – SPR1, SPR0: SPI Clock Rate Select 1 and 0


These two bits control the SCK rate of the device configured as a
Master. SPR1 and SPR0 have no effect on the Slave

◼ SPSR(SPI Status Register)

❑ Bit 0 – SPI2X: Double SPI Speed Bit


When this bit is written logic one the SPI speed (SCK Frequency) will
be doubled when the SPI is in Master mode

30 / 50
SPI Clock Speed

31 / 50
SPCR(SPI Control Register)

32 / 50
SPI Registers
◼ SPSR(SPI Status Register)

❑ Bit 7 – SPIF: SPI Interrupt Flag


◼ When a serial transfer is complete, the SPIF Flag is set
◼ An interrupt is generated if SPIE in SPCR is set and global
interrupts are enabled
◼ SPIF is cleared when executing the corresponding interrupt
handling vector
❑ Bit 6 – WCOL: Write Collision Flag
◼ The WCOL bit is set if the SPI Data Register (SPDR) is written
during a data transfer

33 / 50
SPI Registers
◼ SPDR (SPI Data Register)

◼ SPDR is a read/write register


◼ Writing to the register initiates data transmission
◼ The system is single buffered in the transmit direction
and double buffered in the receive direction.
◼ This means that bytes to be transmitted cannot be
written to the SPI Data Register before the entire shift
cycle is completed.
◼ When receiving data, however, a received character
must be read from the SPI Data Register before the next
character has been completely shifted in. Otherwise, the
first byte is lost.
34 / 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

Вам также может понравиться