Learning how to build a master and slave device using SPI

I was going through the Gammon Forum and came across some doubts relevant to the code for the slave device. In the section"How to make a SPI slave" I have the followings doubts:

  1. Is the line SPI.transfer (c) only meant for one side transmission? i.e. from master (MOSI) to the slave?. If so how do I check If my slave is receiving data from master using the serial monitor in arduino IDE?

  2. In the slave code, what is this "SPCR |=_BV(SPE)" & how does it symbolize the slave mode being ON?. I understand that SPCR is the control register and SPE is the bit used to enable the SPI. But what is the operation of "|=" and "_BV".?

  3. What is this routine "ISR(SPI_STC_vect)", where can I learn about these and how to use them?

I am newbie into arduino and embedded systems as a whole. Totally confused and fully filled with doubts. So, any advise, direction or suggestions regarding these would be helpful. Looking forward to it. Thanks.

PS - I am using two arduino unos, one as master and the other as slave.

SPCR |=_BV(SPE)

how does it symbolize the slave mode being ON?

You need to read up on how C works. That sets that bit, which turns slave mode on. _BV is equivalent to:

SPCR |= 1 << SPE;

Thank you. That cleared it.

Brief - I am using two arduino Uno's. One acts as a master and the other as slave using Arduino IDE. Below is the Master Code:

// Sample Taken from Nick Gammon's Forum//

#include "SPI.h"
#include"pin_arduino.h"
int ss = 10;
void setup()
  {
    pinMode(ss,OUTPUT);
    Serial.begin(9600);
    Serial.println();
    digitalWrite(ss,HIGH);
    SPI.begin();
    SPI.setClockDivider(SPI_CLOCK_DIV8);
   }
byte transferAndWait(const byte what)
 {
   byte a = SPI.transfer(what);
   delayMicroseconds(20);
   return a;
 }
void loop()
 {
   byte a,b,c;
   digitalWrite(ss,LOW);
   transferAndWait('a');
a = transferAndWait(17);
b =  transferAndWait(33);
c = transferAndWait(0);
digitalWrite(ss,HIGH);
Serial.println(a,DEC);
Serial.println(b,DEC);
Serial.println(c,DEC);
delay(1000);
 }

Before I go into the details of the results I obtained and the problem, below is the Slave code:

//Taken from Nick Gammon's Forum//

#include "SPI.h"
#include "pins_arduino.h"
int slave = 10;
int miso = 11;
byte command = 0;
void setup()
  {
    pinMode(miso,OUTPUT);
    pinMode(slave,INPUT);
    Serial.begin(9600);
    SPR|= BV_(SPE);
    SPR|= BV_(SPIE);
 }
ISR(SPI_STC_vect);
 {
   byte c = SPDR;
  switch(command)
    {
      case 0:
      command = c;
      SPDR = 0;
      break;

     case 'a':
     SPDR = c + 15;
     break;
   }
  void loop(void)
   {
     if(digitalRead(slave)==HIGH)
     command = 0;
   }

My Results : After dumping the master and slave codes into their respective arduino uno's, then when I open the serial monitor of the master code, It displays the number 17, 33, 0 and the same goes with the slave, meaning that the data is being sent to the slave and received back successfully, and hence I presume the SPI bus is working properly!. But why isn't the slave performing the add operation?

Problem: Now the problem is, when the command 'a' is sent from the master to the slave, the slave has to interpret this 'a' command as Addition command and perform the addition of a number 15 to the incoming byte from the master as shown in the slave code, and return the results to the master, which should display the addition results in the masters serial monitor. I am having problem performing this task and looking forward to suggestions on how to test or where I am doing wrong or make changes to the code or methods in order to get this working.Thanks

My code:

  // turn on SPI in slave mode
  SPCR |= _BV(SPE);

  // turn on interrupts
  SPCR |= _BV(SPIE);

Your code:

  SPR|= BV_(SPE);
  SPR|= BV_(SPIE);

What is SPR?

Is is necessary to enable the interrupts in the SPI slave in order to send data back to the master? With the interrupts turned off, can a statement like the following be used to return a byte of data from the slave back to the master? In this case the numeral five is returned to the master.

  SPDR = 5; // this statement is included in the slave code

Will 5 be returned to the master when the slave receives the next byte from the master?