# SPI Communication synchronization

I am trying to transmit data from one Microcontroller (ATMega8A default clock frequency) to another Microcontroller (ATMega16 16MHz-crystal).

I have setup ATMega16 as master with

DDRB |= (1 << DDB7) | (1 << DDB5); //Set MOSI, SCK as Output
SPCR |= (1 << SPE) | (1 << MSTR) | (1<<SPIE) | (1 << SPR0);//Enable SPI, Set as Master


 unsigned char ReceiveData(unsigned char Data)
{
SPDR = Data;
while(!(SPSR & (1<<SPIF) ));
return(SPDR);
}


The SS' pin of ATMega8A (slave) is connected to PB3 and in the main loop I have

for(;;)
{
PORTB &= ~(1<<PB3); //clear SS' of slave
Data = ReceiveData(0x05); //sending dummy 0x08 to slave;
if(Data == 0x08)
//TOGGLE(SOME_PORT,SOMEPINWITHLED); toggle #defined
_delay_ms(200);
PORTB |= (1<<PB3);
}


In the slave device I have

int main() // slave main module
{
DDRB |= (1<<DDB4); //MISO as OUTPUT
SPCR |= (1<<SPE); //Enable SPI
DDRB |= (1<<DDB0);
char Data = 2, SendValue = 8;
for(;;)
{
TOGGLE(PORTB,PB0); // #define'd TOGGLE(A,B) A ^= (1<<B);

Data = SendData(SendValue); // exact same as ReceiveData() on master.
}
return 0;
}


The led doesn't toggle at the master module but does at the slave module. Could you suggest me what have I done wrong here. May be the master and slave are not synchronized.

1. Should I check while(!(SPSR & (1 <<SPIF) )); on the slave or SPDR = Data; return (SPDR); is sufficient on the slave.
2. How does the master know when the slave is sending data? So, when should maser check while(!(SPSR & (1 <<SPIF) ));?

P.S: In the future I plan to use multiple slaves and a single master.

Edit : I corrected from DDRB |= (1 << DDB3) | (1 << DDB5);

• Suggest reading atmel.com/images/doc2585.pdf and checking out the associated example code – vicatcu Sep 5 '15 at 23:29
• Thank your for the document @vicatcu. I wonder if this is due to the difference of clock frequency of the two Microcnotrollers. – pranphy Sep 8 '15 at 17:05

The only problem I can find is the initialization of the SPI port on the Master, plus the use of ReceiveData.

On the Master, you as setting B3 and B5 as outputs. But according to this document for the ATmega16, SS = PB4, MOSI = PB5, MISO = PB6, and SCK = PB7 and your SS is PB3. So you should have:

DDRB |= (1 << DDB3) | (1 << DDB5) | (1 << DDB7);


And according to this document for the ATmega8, SS = PB2, MOSI = PB3, MISO = PB4, and SCK = PB5. You should have PB4 configured as an output for MISO, and you do.

I'm not sure what you're using PB0 for, if it is to synchronize the two processors its unneeded.

Your method of sending and receiving data in ReceiveData is correct and should be used for both the Master and Slave (from the previous transmission).

Remember every time you send a byte, you get a byte back from the other end.

• I realized that the bits I set high in DDRB are wrong, thanks for pointing out. I corrected it. – pranphy Sep 8 '15 at 17:07