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
I have a receive function
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.
- Should I check `while(!(SPSR & (1 <<SPIF) ));` on the slave or `SPDR = Data; return (SPDR);` is sufficient on the slave.
- 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);
Best Answer
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:
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.