Sie sind auf Seite 1von 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:

Data Transfer  Master and Slave Operation How It Works:  The Master initiates the communication

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.

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:

module for every slave you add as in the following picture: Testing: In this test I

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)

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;

PORTB.4=1;PORTB.3=1;PORTB.1=1; // disable all the slaves

// dispaly data on PORTC

}

// 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/