SPI no funciona, ATmega328 solo envía 1 byte

1

Estoy intentando que SPI funcione en un ATmega328. Este es mi código:

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#define ACK 0x7E
#define LONG_TIME 10000

//Initialize SPI Master Device
void spi_init_master (void)
{
    DDRB = (1<<PORTB5)|(1<<PORTB3);              //Set MOSI, SCK 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)
{
    PORTC = 1<<PORTC2;
    PORTC = 0<<PORTC2;

    SPDR = data;                       //Load data into the buffer
    while(!(SPSR)&(1<<SPIF));
    return(SPDR);                      //Return received data
}


//Main
int main(void)
{
    DDRC= 0XFF; 
    spi_init_master();
    spi_tranceiver(6); 
    //spi_tranceiver(6);
    //spi_tranceiver(6); 


}

Esta es la salida del analizador lógico:

Observeesasdoslíneasdecomentarios.spi_tranceiver(6);Sieliminoesoscomentarios,deberíaobtenerlosdelanalizadorlógico:

  • 3veceslacantidaddepulsosderelojparalacapaazul.
  • 3veceslacantidaddedatosenviados,y;
  • 3veceslacantidaddetacosPORTC2.

Estenoeselcaso.Mesaleelsiguiente:

El dispositivo con el que estoy tratando de SPI no está configurado correctamente. ¿Esto importa?

    
pregunta dgamma3

1 respuesta

4

Parece que tienes las paréntesis en el lugar equivocado mientras esperas a que se complete la transacción SPI. Debido a que el operador ! tiene una prioridad más alta que & , intentará hacer un bit a bit no del registro SPSR primero. En su lugar quieres algo como esto:

while (!(SPSR & (1<<SPIF)))
    ;

En este momento, presumiblemente, la espera se está devolviendo inmediatamente, por lo que el registro SPDR se establece tres veces en una sucesión rápida sin el tiempo suficiente para que se transfieran los datos.

    
respondido por el PeterJ

Lea otras preguntas en las etiquetas