Remember the master controls the transmission (provides the clock), however it can be done. For example:
Master
// master
#include <SPI.h>
void setup (void)
{
Serial.begin (115200);
Serial.println ("Starting");
digitalWrite(SS, HIGH); // ensure SS stays high for now
// Put SCK, MOSI, SS pins into output mode
// also put SCK, MOSI into LOW state, and SS into HIGH state.
// Then put SPI hardware into Master mode and turn SPI on
SPI.begin ();
// Slow down the master a bit
SPI.setClockDivider(SPI_CLOCK_DIV8);
} // end of setup
void loop (void)
{
char buf [20];
// enable Slave Select
digitalWrite(SS, LOW);
SPI.transfer (1); // initiate transmission
for (int pos = 0; pos < sizeof (buf) - 1; pos++)
{
delayMicroseconds (15);
buf [pos] = SPI.transfer (0);
if (buf [pos] == 0)
{
break;
}
}
buf [sizeof (buf) - 1] = 0; // ensure terminating null
// disable Slave Select
digitalWrite(SS, HIGH);
Serial.print ("We received: ");
Serial.println (buf);
delay (1000); // 1 second delay
} // end of loop
In this example the master initiates a transmission by sending 0x01 to the slave. Then it gets bytes back until a 0x00 byte (signifying the end of the string). The delayMicroseconds
is there to give the slave time to respond.
Slave
// Slave
void setup (void)
{
// have to send on master in, *slave out*
pinMode(MISO, OUTPUT);
// turn on SPI in slave mode
SPCR |= bit(SPE);
// turn on interrupts
SPCR |= bit(SPIE);
} // end of setup
volatile char buf [20] = "Hello, world!";
volatile int pos;
volatile bool active;
// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR;
if (c == 1) // starting new sequence?
{
active = true;
pos = 0;
SPDR = buf [pos++]; // send first byte
return;
}
if (!active)
{
SPDR = 0;
return;
}
SPDR = buf [pos];
if (buf [pos] == 0 || ++pos >= sizeof (buf))
active = false;
} // end of interrupt service routine (ISR) SPI_STC_vect
void loop (void)
{
} // end of loop
The slave does everything inside the ISR. The arrival of the 0x01 byte makes it reset its "pointer" to the start of the buffer. After that it responds with another byte from the buffer until it has reached the terminating 0x00 byte.