SPI entre ATmega32 y ATmega328 no funciona

1

He estado tratando de lograr la conexión de ATmega32 y ATmega328 mediante SPI

Conexiones de hardware:

ATmega328     ATmega32 
master        slave
------------------
 MISO    ->   MISO
 MOSI    ->   MOSI
  SCK    ->   SCK
   SS    ->   SS

He agregado algún código para parpadear los LED después de cada paso para reconocer si un paso en particular se ha completado.

Cuando está conectado, el LED conectado al maestro parpadea una vez, mientras que el LED conectado al esclavo no parpadea en absoluto.

¿Qué he hecho mal?

Gracias por cualquier consejo.

Código para atmega328 como maestro

#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>

//Initialize SPI Master Device
void spi_init_master (void)
{
    DDRB = (1<<PORTB5)|(1<<PORTB3)|(1<<PORTB2);   // Set MOSI, SCK , SS as Output
    SPCR = (1<<SPE)|(1<<MSTR);                    // Enable SPI, Set as Master
}

//Function to send and receive data
unsigned char spi_tranceiver (unsigned char data)
{
    PORTB &= ~(1<<PINB2); //sending low signal to activate slave
    SPDR = data;                         // Load data into the buffer

    while(!((SPSR)&(1<<SPIF)));          // wait till transmission complete

    PORTC |= (1<<PINC4);
    _delay_ms(1000);
    PORTC &= ~(1<<PINC4);
    _delay_ms(1000);

    return(SPDR);                        // Return received data
}


//Main
int main(void)
{
DDRC |= (1<<PINC4);
spi_init_master();
unsigned char t = spi_tranceiver(6);
for(unsigned char i=1;i<=t;i++){
    PORTC = (1<<PINC4);
    _delay_ms(500);
    PORTC &= ~(1<<PINC4);
    _delay_ms(500);
}
}

Código para ATmega32 como esclavo

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>

void spi_init_slave (void);
unsigned char spi_tranceiver (unsigned char data);

unsigned char lo; 

int main(void)
{
    DDRD |= (1<<PD7);
    spi_init_slave();
    while (1) 
    {
        lo = spi_tranceiver(3);
        for(unsigned char i=1;i<=lo;i++) {
            PORTD |= (1<<PD7);
            _delay_ms(100);
            PORTD &= ~(1<<PD7);
            _delay_ms(100);
       }
    }
}

// Initialize SPI Slave Device
void spi_init_slave (void)
{
    DDRB &= ~(1<<PINB5);   // Set MOSI as input
    DDRB |=  (1<<PINB6);   // Set MISO as output
    DDRB &= ~(1<<PINB4);   // SS as input
    SPCR  =  (1<<SPE);     // Enable SPI
}

unsigned char spi_tranceiver (unsigned char data)
{
// Load data into the buffer
SPDR = data;
//Wait until transmission complete
while(!(SPSR & (1<<SPIF) ));
PORTD |= (1<<PD7);
_delay_ms(100);
PORTD &= ~(1<<PD7);
_delay_ms(100);
// Return received data
return(SPDR);
}
    
pregunta pavindu

2 respuestas

0

Después de publicar mi problema en AVR Freaks , pude para resolver el problema. No había configurado SCK en el esclavo como entrada y la velocidad de reloj SPI no estaba configurada correctamente. Configuré la frecuencia de reloj en f / 64, donde f se refiere a la frecuencia de la CPU del maestro. Me gustaría mencionar un par de cosas aquí para que sean anotadas por futuros visitantes.

  • Si su SPI no funciona, primero verifique cuál es la frecuencia de reloj de SPI. Si es demasiado rápido o lento, no funcionará.
  • Compruebe si ha declarado correctamente los pines del módulo SPI en el maestro y el esclavo. MISO debe configurarse en entrada y el resto en salida en el maestro. En el esclavo, MISO debe configurarse como salida y el resto como entrada.
  • Si estos dos no funcionan para ti, entonces enfócate en cosas más avanzadas como CPOL, CPHA. El uso de un analizador lógico para depurar ayudará en este caso.
respondido por el pavindu
0

SS debe ser LOW para que el hardware SPI Slave esté activo. No veo que establezca esta E / S en su código maestro en absoluto.

    
respondido por el Turbo J

Lea otras preguntas en las etiquetas