SPI sincronización de comunicación

0

Estoy tratando de transmitir datos de un microcontrolador (frecuencia de reloj predeterminada ATMega8A) a otro microcontrolador (ATMega16 16MHz-cristal).

He configurado ATMega16 como maestro con

DDRB |= (1 << DDB7) | (1 << DDB5); //Set MOSI, SCK as Output
SPCR |= (1 << SPE) | (1 << MSTR) | (1<<SPIE) | (1 << SPR0);//Enable SPI, Set as Master

Tengo una función de recepción

 unsigned char ReceiveData(unsigned char Data)
 {
     SPDR = Data;
     while(!(SPSR & (1<<SPIF) ));
     return(SPDR);
}

El pin SS' de ATMega8A (esclavo) está conectado a PB3 y en el bucle principal tengo

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

En el dispositivo esclavo que tengo

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

El led no se enciende en el módulo maestro, pero sí en el módulo esclavo. ¿Podría sugerirme qué he hecho mal aquí? Puede ser que el maestro y el esclavo no estén sincronizados.

  1. ¿Debo marcar 'while (! (SPSR & (1 & lt & ltSPIF)))' en el esclavo o 'SPDR = Data; retorno (SPDR); Es suficiente en el esclavo.
  2. ¿Cómo sabe el maestro cuando el esclavo está enviando datos? Entonces, ¿cuándo debería el maser comprobar 'while (! (SPSR & (1 & lt & ltSPIF)));'?

P.S: En el futuro planeo usar esclavos múltiples y un solo maestro.

Editar : corregí de DDRB |= (1 << DDB3) | (1 << DDB5);

    
pregunta Prakash Gautam

1 respuesta

1

El único problema que puedo encontrar es la inicialización del puerto SPI en el Maestro, más el uso de ReceiveData.

En el Maestro, usted está configurando B3 y B5 como salidas. Pero de acuerdo con este documento para ATmega16, SS = PB4, MOSI = PB5, MISO = PB6, y SCK = PB7 y tu SS es PB3. Entonces deberías tener:

DDRB |= (1 << DDB3) | (1 << DDB5) | (1 << DDB7);

Y de acuerdo con este documento para el ATmega8, SS = PB2, MOSI = PB3, MISO = PB4 y SCK = PB5. Debes tener PB4 configurado como una salida para MISO, y así es.

No estoy seguro de para qué está utilizando PB0, si es para sincronizar los dos procesadores es innecesario.

Su método para enviar y recibir datos en ReceiveData es correcto y debe usarse para ambos el Maestro y el Esclavo (de la transmisión anterior).

Recuerde que cada vez que envía un byte, obtiene un byte del otro extremo.

    
respondido por el tcrosley

Lea otras preguntas en las etiquetas