problemas de SPI con ATMEGA328 como maestro

0

Estoy tratando de conectar ATMEGA328p como maestro a X25020 EEPROM como esclavo.

aquí está mi código

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

La idea es escribir 0x01 para direccionar 0x20 en el chip esclavo, y leerlo, si se lee correctamente, enciende un LED en PC0.

De alguna manera no puedo ver por qué no funciona, verifiqué las conexiones del chip esclavo, parece estar bien.

siguió las instrucciones de la hoja de datos para hablar con el chip esclavo.

enlace

    
pregunta Abel Tom

1 respuesta

1

Debe agregar una escritura ficticia a su función RX para proporcionar el reloj (el reloj solo lo genera el maestro). A asuma que el código de inicio y el protocolo de comunicación eeprom son correctos.

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

   return Rx_char;
}
    
respondido por el P__J__

Lea otras preguntas en las etiquetas