0
\$\begingroup\$

I am trying to connect ATMEGA328p as master to X25020 EEPROM as slave.

here is my code

void spi_master_init()
{
   DDRB = ( (1<<PB2) | (1<<PB3)  | (1<<PB5) );   // /SS as output, MOSI and SCK as output
   SPCR = ( (1<<SPE) | (1<<SPR1) | (1<<MSTR)); //SPI Enable, fosc/64, Master mode
}


void spi_slave_init()
{
   DDRB = 0<<PB4;     //MOSI as input
   SPCR = 1<<SPE ;
}


void SPI_Tx(char data)
{
   SPDR=data;
   while( !(SPSR & (1<<SPIF)) );   //wait until SPIF flag is set, to indicate transmission is complete
}

char SPI_Rx()
{
   char Rx_char;   
   while( !(SPSR & (1<<SPIF)) );
     Rx_char= SPDR;

   return Rx_char;
}

void write_to_slave()
{
   PORTB|=1<<PB2;    //take /CS on slave LOW
   SPI_Tx(0x06);  //WREN write enable command
   PORTB&=0<<PB2;    //take /CS on slave HIGH

   PORTB|=1<<PB2;    //take /CS on slave LOW
   SPI_Tx(0x02);  //WRITE instruction
   SPI_Tx(0x20);  //Address to write data to
   SPI_Tx(0x01);  //Data to be written
   PORTB&=0<<PB2;    //take /CS  on slave HIGH
}

char read_from_slave()
{
   char recvd_char;
   PORTB|=1<<PB2;    //take /CS on slave LOW
   SPI_Tx(0x03);  //READ instruction
   SPI_Tx(0x20);  //Address to be read from

   recvd_char = SPI_Rx();
   return recvd_char;
}

int main (void)
{
   DDRC=0xff;   //PORTC as output


   char recvdchar=0;

   spi_master_init();
   spi_slave_init();

   write_to_slave();

   recvdchar=read_from_slave();

   if(recvdchar==0x01)
    PORTC=1<<PC0;
}

The idea is to write 0x01 to address 0x20 on the slave chip, and read it back, if successfully read light up an LED on PC0.

Somehow i cant see why it does not work, I checked connections of slave chip, seem to be fine.

followed datasheet instructions to talk to the slave chip.

http://pdf.datasheetcatalog.com/datasheets/70/290256_DS.pdf

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

You need to add a dummy write to your RX function to provide the clock (clock is only generated by the master). A assume that the your init code and the eeprom communication protocol is correct.

char SPI_Rx()
{
   char Rx_char;   
   SPI_Tx(0);
   while( !(SPSR & (1<<SPIF)) );
     Rx_char= SPDR;

   return Rx_char;
}
\$\endgroup\$
4
  • \$\begingroup\$ Clock is generated by default when SCK is connected from Master to SCK of slave, right? \$\endgroup\$
    – Abel Tom
    Jun 3, 2017 at 10:50
  • 1
    \$\begingroup\$ Actually I do not understand what you mean: "by default". But "by default" clock is not generated. Clock is only generated when master transmits. So you cant receive anything without the concurrent transmit. \$\endgroup\$ Jun 3, 2017 at 11:28
  • \$\begingroup\$ Oh okay Thanks, i did not know that. I tried what you suggested but it still did not work! And yea i called write_to_slave() before reading so in the initial SPI_Tx() call the clock must have been generated right? \$\endgroup\$
    – Abel Tom
    Jun 3, 2017 at 12:26
  • 1
    \$\begingroup\$ Clock is only generated when master transmits and only as many ticks as data bits. You need to connect an analyser (even a $10 Chinese one), to see what your problem is. \$\endgroup\$ Jun 3, 2017 at 13:10

Your Answer

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

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