Forum: Mikrocontroller und Digitale Elektronik SPI Kommunikation Ablauf


von Michael N. (betonmicha)


Lesenswert?

Ich habe mich in letzter Zeit mit der SPI Kommunikation zwischen zwei 
Mikrocontrollern beschäftigt. In meinem Fall ein STM32F4 als Master und 
ein STM32F0 als Slave. Es werden noch 5 weitere Slaves folgen. Ich 
möchte über den Master die Slaves programmieren. Dazu möchte ich 1024 
Byte große Pakete verschicken.
Der SPI ist korrekt initialisiert und funktioniert auch soweit. Senden 
und empfangen klappt.

Wie sieht denn vorzugsweise der Ablauf bei so einer SPI Kommunikation 
aus? Ich würde jetzt die 1024 Byte an den Slave senden. Dieser 
verarbeitet sie und schickt dann ein OK oder NOK zurück. Das heißt nach 
dem ich das Paket an den Slave geschickt habe schickt der Master die 
ganze Zeit 0xFF raus bis er ein Paket empfangen hat? Oder wird sowas 
anders gelöst?

Gruß
Micha

von Christian (Gast)


Lesenswert?

Soweit ich weis, ist bei richtigen SPI gar kein Handshake vorgesehen...

Würde bedeuten:

Du schickst Deine Bytes raus, erhältst jedoch keine Quittierung ob die 
Bytes vom Slave empfangen wurden...

von Christian (Gast)


Lesenswert?

Was mir gerade auch noch einfällt ist:

Wenn Dein Master dann die ganze Zeit 0xFF rausschickt (Also nachdem dein 
Datenpaket gesendet wurde), wie soll dann der Slave (sofern er das 
überhaupt kann) ein OK senden?

Deine Datenleitung wäre ja durch den Master belegt... Wenn also dann 
noch Dein Slave senden würde, würden sich die Daten "zerstören".

von Michael N. (betonmicha)


Lesenswert?

Wenn ich jetzt aber ein Slave Device habe, z.B. ein Sensor und möchte 
die Daten abfragen, schicke ich doch einen "Befehl" hin und warte dann 
auf die Daten.

Bevor ich bei mir das nächste Paket schicke, möchte ich ja wissen ob das 
vorherige angekommen ist bzw. richtig verarbeitet wurde. Dazu brauch ich 
ja die Antwort des Slaves. Aber um Daten vom Slave zu bekommen muss man 
bei SPI ja "pollen" weil der Clock ja vom Master kommt. Vielleicht habe 
ich das auch alles falsch verstanden.

Mein "Handshake ist ja sozusagen das übergeordnete Protokoll das auf SPI 
aufsetzt.

Die Daten vom Master liegen ja auf MOSI und die vom Slave auf MISO. Hab 
vergessen zu schreiben, das es im Vollduplex mode läuft.

von Helper (Gast)


Lesenswert?

Christian schrieb:
> Deine Datenleitung wäre ja durch den Master belegt... Wenn also dann
> noch Dein Slave senden würde, würden sich die Daten "zerstören".

Wir sprechen hier von SPI.

MOSI & MISO.

von Walleby (Gast)


Lesenswert?

Es gibt z. B. bei A/D-Wandlern mit SPI-Schnittstelle eine Extraleitung 
(BUSY), die nach Ende der Konvertierung dies durch ein Interrupt 
signalisieren. Zusätzlich wird das Interrupt auch auf der Leitung MISO 
angezeigt.

D. h. du müsstest durch dein Slave ein Interrupt über z. B. MISO senden 
und dieses mit dem SPI-Master detektieren. Welcher Slave dann grade 
fertig bzw. bereit ist, weißt du ja über die gesendeten Daten.

von Christian (Gast)


Lesenswert?

Tut mir leid, ich glaube der Urlaub tut mir nicht gut :D

von Michael N. (betonmicha)


Lesenswert?

Das heißt ich "missbrauche die MISO Leitung als Interrupt Leitung. Würde 
also bedeuten der Master wartet dann z.B. auf ein High am MISO und 
startet dann die Abfrage des Slaves weil er fertig ist?
Die Möglichkeit hört sich ja schon besser an als die ganze Zeit zu 
Senden.

Hat ja Vor- und Nachteile das SPI keinen Standrad hat.

von uwe (Gast)


Lesenswert?

Kannst ja auch ein Protokoll benutzen z.B.
-Startbyte immer 0x02
-Länge der Daten als zwei Bytes 0x03FF damit weiß dann der empfänger 
wann er die Checksummer zurücksenden soll
-Checksumme kommt als zwei bytes 0xxxx vom Slave zum Masterr zurück der 
natürlich die 16 Clocks generiern muß
-Wenn Checksumme vom Master als richtig erkannt Datenübertragung 
erfolgreich und es wird ne 0x5F gesendet, ansonsten muß der Master dem 
Slave mit ner 0xFA Signalieren das die Übertragung wiederholt wird und 
er das zuvorgesendete Paket vergessen soll. Dann wieder...
-Startbyte immer 0x02
...

von Michael N. (betonmicha)


Lesenswert?

Hallo uwe,

Ja das Protokoll selbst ist nicht das Problem. Wenn das Paket an den 
Slave gesendet wurde und alles erfolgreich war, verarbeitet der Slave 
das Paket. In meinem Fall werden die 1024 Byte in den Flash geschrieben. 
Das dauert aber kurz und der Master muss warten, was er ja auch tut. Nur 
muss ihm der Slave dann signalisieren, das der Master das nächste Paket 
schicken darf.

Bei SPI kann ein Slave aber nur Daten senden, wenn er vom Master einen 
Clock bekommt. Und den Clock schickt der Master nur wenn er was sendet, 
so hab ich das bisher verstanden.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael N. schrieb:
> ganze Zeit 0xFF raus bis er ein Paket empfangen hat? Oder wird sowas
> anders gelöst?

 Warum ?
 Du weisst ja ungefähr wie lange die Paketverarbeitung dauert, oder ?
 Paket mit CRC senden, nachdem du CRC rausgeschickt hast, ein Dummy
 Byte zum Read - wenn CRC OK ist, kriegst du ACK zurück.
 Danach eine Mindestzeit warten, Anfrage schicken, wenn OK,
 weitermachen, wenn nicht, noch 5-10 Mal wiederholen, danach Slave
 reseten oder abschreiben.

Michael N. schrieb:
> Das heißt ich "missbrauche die MISO Leitung als Interrupt Leitung. Würde
> also bedeuten der Master wartet dann z.B. auf ein High am MISO und
> startet dann die Abfrage des Slaves weil er fertig ist?
> Die Möglichkeit hört sich ja schon besser an als die ganze Zeit zu
> Senden.

 Bin zu faul um jetzt nachzusehen, aber ich glaube dazu musstest du
 SPI ausschalten.

von uwe (Gast)


Lesenswert?

> Nur muss ihm der Slave dann signalisieren, das der Master das nächste
> Paket schicken darf.
Ja und deshalb schrieb ich ja das der Master 16 Takte für die Checksumme 
generiern muß (also 2 Dummy bytes schickt). Was der Master da schickt 
ist vollkommen schnurz. Und wenn der Master ann die Checksumme 
vergleicht isst dies das Signal welches dem Master dann Signalisiert ...
> Nur muss ihm der Slave dann signalisieren, das der Master das nächste
> Paket schicken darf.

von Michael N. (betonmicha)


Lesenswert?

Also einfach ein Timeout für den Slave. Ja die ungefähre Zeit bekomme 
ich raus. Ist natürlich besser als dauernd zu senden.

Mit dem ausschalten kann sein. Den Pin werde ich wohl nicht togglen 
können wenn er im AF mode ist. Ich werds mal ausprobieren.

@uwe
Aber wenn nach den ersten 16 Takten noch keine Rückmeldung kam, ist der 
Slave wohl noch nicht fertig. Und ich muss nochmal 16 Takte nachschieben 
usw. bis ich ne Antwort habe oder entscheide das Timeout ist.

: Bearbeitet durch User
von Gerald G. (gerald_g)


Lesenswert?

Ich würde einfach den slaves noch je einen zusätzlichen I/O spendieren. 
Nach der Prüfung kann der slave signalisieren dass er etwas zu senden 
hat. Im interrupt des Masters wird dann ein byte raus geschickt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael N. schrieb:
> Also einfach ein Timeout für den Slave. Ja die ungefähre Zeit bekomme
> ich raus. Ist natürlich besser als dauernd zu senden.

 Du kannst ja in der Zeit die anderen Slaves ansprechen. Nur halt in
 einer Tabelle merken welcher Slave was gerade macht - und dann
 round-robin den ganzen Tag lang...

von Dirk K. (dekoepi)


Lesenswert?

Vom Prinzip her verstehe ich nicht, warum das Polling so schlecht sein 
soll.

Master sendet sein Paket, der Client schickt ein "Danke" zurück. Nun 
müssen wir unbestimmte Zeit warten. Der Master kann etwa andere Clients 
versorgen. Und nach 0,5s schickt der Master den Befehl "Fertig?", und 
der Client antwortet "Nö" oder "Ja". Nach der Antwort entweder weiter 
warten und andere Clients versorgen, oder machen, was auch immer sonst 
anliegt.

Quasi wie beim Radio-Modul: Befehl "Seek" absetzen und alle paar hundert 
ms Register auslesen und prüfen, ob das schon erfolgreich war.

Dafür muss SPI Rx (oder der Pin !CE) halt in den Interrupt wandern und 
von dort aus Aktionen anstoßen. Da der STM32F0 ja eh Slave ist, sollte 
das Grundkonstrukt vorhanden sein.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Michael N. schrieb:

> Wie sieht denn vorzugsweise der Ablauf bei so einer SPI Kommunikation
> aus? Ich würde jetzt die 1024 Byte an den Slave senden. Dieser
> verarbeitet sie und schickt dann ein OK oder NOK zurück. Das heißt nach
> dem ich das Paket an den Slave geschickt habe schickt der Master die
> ganze Zeit 0xFF raus bis er ein Paket empfangen hat? Oder wird sowas
> anders gelöst?

Das Lustige an SPI (überhaupt den meisten im µC-Bereich relevanten 
Bussystemen) ist: Es gibt keinerlei Festlegungen zum logischen 
Protokoll. Du kannst das also handhaben, wie es dir für deine konkrete 
Anwendung sinnvoll erscheint.

Wenn z.B. der Ablauf so ist, daß ein 1k-Datenpaket übermittelt wird, 
dann könnte man z.B. schlicht im ersten Byte dieses Pakets die Quittung 
für das jeweils davor liegende Paket übermitteln, denn SPI ist ja 
Full-Duplex.

Das würde das Pollen einer Bestätigung für das aktuelle Paket ersparen, 
aber dafür auch eine möglicherweise sinnvolle Reaktion auf den 
NACK-Fall (nämlich die zeitnahe erneute Übertragung) erschweren.

Die Sache ist einfach die: es hängt von der konkreten Anwendung ab, was 
genau sinnvoll ist. Da die Vielfalt der Anwendungen nahezu unendlich 
ist, kann es auch keine Wichsvorlage für ein alleinseligmachendes 
logisches Protokoll geben.

Genau weil das so ist, gibt es halt auch bei anderen "Bus"-Systemen 
jeweils eine Vielfalt logischer Protokolle.

Im Prinzip läuft es immer darauf hinaus, einen für die konkrete 
Anwendung möglichst guten Kompromiss zwischen den sich prinzipielle 
widersprechenden Forderungen nach maximaler Bandbreite, minimaler Latenz 
und maximaler Störsicherheit zu finden. Alles gleichzeitig geht einfach 
nicht, jedenfalls nicht in unserem Universum.

von Michael N. (betonmicha)


Lesenswert?

Danke für die zahlreichen Anregungen und Ideen. :)

Im Moment benutze ich den Polling Modus, was auch gut funktioniert. Da 
die Controller momentan nichts anderes machen müssen während sie sich 
miteinander unterhalten hab ich auch keine Probleme.

Ich werde es aber später wohl so abändern, das der Master jede 
Millisekunde den Slave abfragt ob er fertig ist.

Jetzt ist mir SPI noch ein Stück klarer geworden. Veilleicht hilft es ja 
anderen auch mal weiter.

von Purzel H. (hacky)


Lesenswert?

Was soll ein CRC ? Eine normale SPI Verbindung ist auf der Leiterplatte 
und nur ein paar cm kurz. Da gibt es keine Stoerungen...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Siebzehn Zu Fuenfzehn schrieb:
> Was soll ein CRC ? Eine normale SPI Verbindung ist auf der Leiterplatte
> und nur ein paar cm kurz. Da gibt es keine Stoerungen...

 Warum 1024 Bytes senden ohne CRC ?
 2 Bytes tun da bestimmt nicht weh und auch 16 bit CRC kann man aus
 einer 256 Byte Lookup table lesen - braucht bei STM32F4 kaum Zeit.

von Michael N. (betonmicha)


Lesenswert?

In meinem Fall werden es ca. 30 cm über zwei Steckverbinder. Da finde 
ich es schon sinnvoll.
Bei einem 1k Paket hab ich 6 Byte Overhead. Das fällt nicht ins Gewicht. 
Und der STM32F4 brechnet mit seinen 168 MHz eine 16bit CRC praktisch "on 
the fly". Deswegen werde ich weiterhin eine CRC benutzen. Es darf 
natürlicher jeder selbst entscheiden.

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.