Vous êtes sur la page 1sur 6

Connecting Three Slaves To a Master Microcontroller

Introduction to SPI:
SPI stands for Serial Peripheral Interface, it allows high-speed synchronous data transfer
between the ATmega16 and peripheral devices (or between several AVR devices). It has the
following properties:

Full-duplex
Three-wire Synchronous Data Transfer
Master and Slave Operation

How It Works:

The Master initiates the communication cycle when pulling low the Slave Select SS pin.
Writing a byte to the Master Data Register (Master SPDR) starts the clock on the SCK
line.
After shifting one byte, the clock stops, and the flag SPIF is set.
If the SPI interrupt enable bit (SPIE) is set, an interrupt is requested, and the Master will
synchronize the Slave by pulling high the SS line.

Connection:
1. MOSI (PB5 in ATmega16): Master Output Slave Input. For master micro-controller this
pin is output and for slave micro-controller this pin is input.
2. MISO (PB6 in ATmega16): Master Input Slave Output. For master micro-controller this
pin is input and for slave micro-controller this pin is output.
3. SCK (PB7 in ATmega16): SPI clock. For master micro-controller this pin is output and for
slave micro-controller this pin is input.
4. SS (active low) (PB4 in ATmega16): Slave Select or Slave enable. For master microcontroller this pin is output and for slave micro-controller this pin is input.

The four pins of SPI communication is connected as the above figure.

Connecting More Than One Slave:


You can connect more than one slave SPI module to one Master module. You will have to add a
slave select line in the master module for every slave you add as in the following picture:

Testing:
In this test I have connected three SPI modules of ATmega16 as slaves to one master
SPI module of ATmega16. I used PB1 as slave enable for slave number 1, PB3 as slave
enable for slave number 2 and PB4 as slave enable fo slave number 3. I used 8 DIP
switches connected to PORTA for the master and the three slaves to change the data
to be sent between them. I used the three external interrupts of ATmega16 to select
which slave to send the data to (i.e. to send data from master to slave number one
press the button connected to INT0 and so on). The data sent is displayed on PORTC.
The SPI specifications used in the testing:
// SPI initialization
// SPI Clock Rate: 250.000 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First

Sample of the master code:


// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
PORTB.1=0; // enable slave no.1
SPDR=PINA; // read the data from PORTA and send it
}
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
// Place your code here
PORTB.3=0; // enable slave no.2
SPDR=PINA; // read the data from PORTA and send it
}

// External Interrupt 2 service routine


interrupt [EXT_INT2] void ext_int2_isr(void)
{
// Place your code here
PORTB.4=0; // enable slave no.3
SPDR=PINA; // read the data from PORTA and send it
}
// SPI interrupt service routine
interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
data=SPDR;
// Place your code here
PORTC=data; // dispaly data on PORTC
PORTB.4=1;PORTB.3=1;PORTB.1=1; // disable all the slaves
}
// Declare your global variables here
void main(void)
{
PORTA=0x00;
DDRA=0x00;
PORTB=0x1A;
DDRB=0xBA;
PORTC=0x00;
DDRC=0xFF;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: On
// INT1 Mode: Rising Edge
// INT2: On
// INT2 Mode: Rising Edge
GICR|=0xE0;
MCUCR=0x0F;

MCUCSR=0x40;
GIFR=0xE0;
// SPI initialization
SPCR=0xD0;
SPSR=0x00;
// Clear the SPI interrupt flag
#asm
in r30,spsr
in r30,spdr
#endasm
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
};
}

Sample of the Slave code:


// SPI interrupt service routine
interrupt [SPI_STC] void spi_isr(void)
{
unsigned char data;
data=SPDR;
// Place your code here
PORTC=data ;
}
void main(void)
{
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x40;

PORTC=0x00;
DDRC=0xFF;
// SPI initialization
SPCR=0xC0;
SPSR=0x00;
// Clear the SPI interrupt flag
#asm
in r30,spsr
in r30,spdr
#endasm
// Global enable interrupts
#asm("sei")
while (1)
{
// Place your code here
SPDR=PINA;
};
}

if you liked this tutorial visit us at :


http://all-about-embedded.blogspot.com/

Vous aimerez peut-être aussi