Electrical Engineering Stack Exchange is a question and answer site for electronics and electrical engineering professionals, students, and enthusiasts. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

For a project I want to have two microcontrollers talk to each other via an SPI interface. I wrote the following code for the slave:

volatile uint8_t data;

void spi_init_slave (void)
 DDRB=(1<<PINB4);               //MISO as OUTPUT
 SPCR=(1<<SPE)|(1<<SPIE);       //Enable SPI && interrupt enable bit

uint8_t SPI_SlaveReceive(void)
  /* Wait for reception complete */
  while (!(SPSR & (1<<SPIF)))   ;
  /* Return data register */
  return    SPDR;

  uint8_t y = SPI_SlaveReceive();
  PORTD = y;

int main(void)
    DDRD = (1<<PIND0) | (1<<PIND1) | (1<<PIND2) | (1<<PIND3) | (1<<PIND4);
    spi_init_slave();                             //Initialize slave SPI



The master is sending a number which the slave displays using the LEDs attached to port D. I'm using an Atmega8P for this project.

share|improve this question
Above code is working now, fixed typo. – BoboProg Apr 19 '14 at 11:17
up vote 3 down vote accepted

The most apparent problem I can see is the following line:


Is missing a less than sign and should include (1<<SPIE) to enable the SPI interrupt. Note that the current expression (1<SPIE) will be equivalent to the boolean expression (1 < 7) which will result in a value of 1. So that also means at the moment you'll be setting SPR0 for a speed of fosc/16 on the master.

share|improve this answer
You've made my day. Thanks! Only the slave doesn't have to "match" the speed of the master. Quoted atmel datasheep pp 126: "Bits 1, 0 – SPR1, SPR0: SPI Clock Rate Select 1 and 0. These two bits control the SCK rate of the dev ice configured as a Master. SPR1 and SPR0 have no effect on the Slave." – BoboProg Apr 19 '14 at 11:15
Ahh yes good point of course I re-worded that part. – PeterJ Apr 19 '14 at 11:21

I know this is a year old, but I thought I would just point out that when I tried implementing your code, the interrupt routine was only firing every other SPI transfer.

I believe this is because of this line:

while (!(SPSR & (1<<SPIF)))   ;

when you actually want:

while ((SPSR & (1<<SPIF)))   ;

Hopefully that saves someone else some of the time I spent scratching my head.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.