Forum: Mikrocontroller und Digitale Elektronik SPI-Synchronisations-Problem


von Jonas (Gast)


Lesenswert?

Hallo zusammen

Ich verwende untenstehende Routinen, welche das Ziel haben, Bytes vom 
SPI-Master an den SPI-Slave zu senden. Umgekehrt soll der Slave 
ebenfalls Bytes zurück an den Master senden, welche jeweils um 1 Byte 
verzögert auch ankommen. Das ganze habe ich auf 2 Atmega's (ATmega48 und 
128 getestet), wobei der 128er als SPI-Master eingesetzt wird und über 
UART angesteuert wird.

Nun zum Problem:

Testweise schiebe ich vom SPI-Slave die eingelesenen Bytes zurück an den 
Master, welche dann um 1 Byte verzögert ankommen sollten. Trotzdem 
funktioniert dies manchmal nicht (bei ca. jedem 15 byte, ziemlich 
willkürlich), d.h. es wird nicht ein Byte vom Slave zurückgeschickt, 
sondern das eingelesene Byte ist dann gerade dasjenige, welches ich 
geschickt habe.

Ich verstehe nun nicht, wieso diese Synchronisation nicht sauber 
funktioniert.

Vielen Dank für Lesen und ich hoffe auf einige Tips!

char SPI_MasterTransmit(char cData)
{
  uint8_t rc;

  PORTB &= ~(1<<0);  //SS low
  // Start transmission
  SPDR = cData;

  while(!(SPSR & (1 << SPIF)));
  rc = SPDR;

  // Wait for transmission complete
  PORTB |= (1<<0);  //SS high

  return (SPDR);
}

SPI_SlaveInit klar..

char SPI_SlaveReceive(char cData)
{
  SPDR=cData;

  /* Wait for reception complete */
  while (!(SPSR) & (1<<SPIF));

  return SPDR;
}

von Jonas (Gast)


Lesenswert?

Kann es sein, dass noch niemand so etwas probiert hat?

von holger (Gast)


Lesenswert?

>Kann es sein, dass noch niemand so etwas probiert hat?

Jede Menge Leute habe das schon gemacht. Dein Programm
ist einfach falsch.

von Peter D. (peda)


Lesenswert?

Jonas wrote:

> Testweise schiebe ich vom SPI-Slave die eingelesenen Bytes zurück an den
> Master, welche dann um 1 Byte verzögert ankommen sollten. Trotzdem
> funktioniert dies manchmal nicht (bei ca. jedem 15 byte, ziemlich
> willkürlich), d.h. es wird nicht ein Byte vom Slave zurückgeschickt,
> sondern das eingelesene Byte ist dann gerade dasjenige, welches ich
> geschickt habe.

Das Verhalten ist korrekt, weil das AVR-SPI als Slave einfach Mist ist.
Es hat nämlich keinen Sendepuffer. Deshalb schafft es der Slave nicht 
immer, genau zwischen 2 Bytes das Schieberegister zu füllen.


Es gibt 3 Lösungen:

1.
Man nimmt als Slave nen anderen MC mit SPI-Sendepuffer (z.B. 
AT89LP4052).

2.
Der Master wartet nach jedem Byte sehr sehr lange.

3.
Man nimmt ne extra Leitung für Handshake, womit der Slave sagen kann, 
daß er das nächste Byte in das Schieberegister gestellt hat.


Peter

von Jonas (Gast)


Lesenswert?

Hallo Peter

Besten Dank für die Lösungsansätze

von Ralph (Gast)


Lesenswert?

Variante 3 ist die sauberste Lösung
==> 5 Wire SPI

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.