0
\$\begingroup\$

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.

  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);

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

1 Answer 1

1
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ I realized that the bits I set high in DDRB are wrong, thanks for pointing out. I corrected it. \$\endgroup\$
    – pranphy
    Commented Sep 8, 2015 at 17:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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