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
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...
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".
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.
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.
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.
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.
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 ...
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.
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.
> 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.
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
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.
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...
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
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.
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.
Was soll ein CRC ? Eine normale SPI Verbindung ist auf der Leiterplatte und nur ein paar cm kurz. Da gibt es keine Stoerungen...
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.