Hallo zusammen! Ich arbeite im Moment an meiner Projektarbeit für die Technikerschule. Inhalt dieses Projekt ist es u.a., eine Datenmenge durch ein System zu senden, das kaskadierbar ist. Wir haben uns dazu folgendes überlegt: Einen SPI-Bus im Stern aufzubauen und erstmal über drei Bits im gesendeten Byte (die anderen 5 Bits stellen die Information dar, die verarbeitet werden soll) eine Adressierung vorzunehmen (ergäbe für den Anfang 8 Teilnehmer). Jetzt aber die Preisfrage: Kann man überhaupt mehr als zwei Controller via SPI Bus miteinander verbinden? Die Literatur die wir besitzen (Günter Schmitt, µC-Technik mit Controllern der Atmel AVR-RISC-Familie), sagt eindeutig, dass man das machen kann. Es finden sich aber nirgends wirklich Beispiele, wo das schonmal praktiziert worden ist. Also: Jeht dat? Und wer hat da Erfahrung mit und kann mir Tipps geben? Beste Grüße, Dennis
im Prinzip gibt es da 2 Möglichkeiten für dein Vorhaben. 1. Das ist die SPI SPEC Variante Verbinde bei allen µC die Signale MISO, MOSI, CLOCK und zusätzlich vom Master ein einzelnes Signal zu jedem µC um ihn anzusprechen(Chipselect). Somit kann immer nur EIN µC angesprochen werden. Skalierbar ist das nur soweit wie Pins für Chipselect verfügbar sind. 2. Variante Die SPI ist nichts anderes als ein Schieberegister. Schalte die µC in Reihe hintereinander. Dann legts du im Ram 2 Stukturen an, die die Größe hat von "Anzahl der µC" * "Registergröße" also zb 8µC mal 8 Bit(1 Byte) = 8 byte. Stuktur 1 ==> TX ; Stuktur 2 ==> RX . Somit kannst du dann über die Adressierung des Bytes den anzusprechenden µC auswählen und mit Senden der vollständigen Struktur die Daten durchschieben. Skalierbarkeit ist Begrenzt durch die maximale Größe der TX und RX Struktur und die benötigte Übertragungszeit. Diese Strukturgröße ist Abhängig vom verfügbaren RAM.
Variante 1 läßt sich mit Hardwareschieberegistern für das Chipselect ewig weiter ausbauen ;-). Das geht, wie auch Variante 2, auf Kosten des effektiven Datendurchsatzes.
>Wir haben uns dazu folgendes überlegt: Einen SPI-Bus im Stern aufzubauen >und erstmal über drei Bits im gesendeten Byte (die anderen 5 Bits >stellen die Information dar, die verarbeitet werden soll) eine >Adressierung vorzunehmen (ergäbe für den Anfang 8 Teilnehmer). Das geht leider nicht. Dazu müssten alle SPI Slaves per Chip Select gleichzeitig aktiviert werden. Das dumme an der Geschichte ist, das dann alle SPI Slaves ihren Ausgang (MISO) aktivieren und keiner mehr durchkommt weil die sich gegenseitig kurzschliessen. Wenn keine Rückmeldung vom Slave erforderlich ist könnte es aber so funktionieren.
Slaves ohne Rückmeldung sind doch eigentlich relativ sinnfrei. Statt des SPI könnte man auch das UART nutzen, dort kann man duch geschicktes Verschalten im Vollduplex über nur 2 oder im Halbduplex über nur eine Leitung gegenüber Masse senden und empfangen. Die Geschwindigkeit wäre hier maximal 1/8 Controller-Takt. Das Adressieren kann man über das 9-te Bit machen, hierbei kann der MultiprocessorCommunicationMode verwendet werden.
SPI als Interprozessorkommunikationsbus ist machbar. Einer muss den Master spilen und den clock (SCK) vorgeben. Alle Schieberegister sind in Serie. Dh Miso auf Mosi. Sinnvollerweise laufen eh alle CPUs am selben clock. Nachteil des SPI ist dass er keinerlei Puffer hat. Mit zunehmend schnellem Takt wird das Timing hart fur die CPU.
Hallo! :) OK, also den Stern dann nicht. Alles in Serie. Ist auch OK. Aber jetzt zur Steuerung: Wenn die alle in Serie geschaltet sind, aber nur EINER der µC das Datenpaket erhalten soll, kann man doch wie schon von mir angedeutet, eine Adressierung über Bits des verschickten Paketes machen, oder? Das Ganze soll folgendermaßen funktionieren: Ein Micrcontroller (immer derselbe) erhält eine Anfrage (Taster an Portpin). Insgesamt sind 8 Taster an ihm angeschlossen. Je nachdem, über welchen Taster eine Anfrage gemacht wird, braucht er von einem bestimmten Controller ein Meßergebnis. Wie steuer ich dann den Bus? wann muss wer Slave sein und wann Master oder ändert sich das nie? Und kann ich dann überhaupt nur EIN Byte versenden? weil jedes Mal, wenn ein Controller was empfängt, schickt er doch gleichzeitig was in den Bus zurück, oder? Also wären dann ja schon zwei Bytes unterwegs, oder? Klärt mich mal bitte auf. Die SAche ist mir trotz Literatur noch nicht ganz klar! Besten Dank für Eure bisherige Hilfe! Take care, DEnnis
Na, du kannst mit dem chipselect ja signalisieren welcher nun dran ist. Du kannst zB 8 bytes durchschieben und dann allen gleichzeitig den chipselect geben. Dann hat jeder sein Byte empfangen.
Der Chipselect ist jeweils das Latch signal. Das im Schieberegister liegende wird reingelatcht.
Ah so! Ja klar! Klingt ja einfach! Also könnte ich ja quasi einen Master definieren und die anderen Controller als Slaves laufen lassen. Wenn der Master eine Info benötigt, signalisiert er das über den Chipselect, läßt sich die 8Bytes seiner Slaves schicken und selektiert dann selber, welches er davon benötigt. Habe ich das nun richtig verstanden? :) DANK!!! Dennis
Ich glaube, SPI ist für diese Anwendung letzlich nur ein Gewürge: viel Aufwand mit zweifelhaftem Resultat. Ein Bussystem per UART (z.B. RS485) ist einfacher zu erstellen und zu erweitern. Die Erfahrungen damit lassen sich später auch für andere Anwendungen nutzen.
Genau. Das Problem bei SPI, daß man auf das Rausschieben des Bytes warten muß, bevor ein nächstes geschoben werden kann, ist beim UART eleganter gelöst und der Controller hat mehr freie Zeit.
Wenn über das Bussystem im allgemeinen nachgedacht wird, dann würde ich eher CAN empfehlen.
CAN ist in dem Falle sicher mit Kanonen auf Spatzen geschossen. Der Datenoverhead für das CAN-Protokoll könnte störend sein.
Bei SPI verlaesst man die Leiterplatte nicht, resp ueberschreitet 20cm nicht, wohingegen ein UART bei diesen kurzen distanzen uebertrieben ist. Ein UART nimmt man fuer externe Anbindungen Auch ein UART generiert ein Interrupt pro Byte und das muss man holen bevor das Naechste kommt.
> wohingegen ein UART bei diesen kurzen distanzen uebertrieben ist.
Warum?
>Auch ein UART generiert ein Interrupt pro Byte und das muss man holen >bevor das
Naechste kommt.
Wobei ich immer das Problem habe, das es so lange dauert, bis das
nächste Byte kommt :-)
UART nehme ich auch auf Leiterplattenebene, da die Übertragung nicht
blockiert werden kann, wie es z.B. bei IIC allein schon durch ein
korruptes Handshake passieren kann. Und da selbst kleine ATtiny2313
schon den Multiprozessormodus unterstützen, ist auch die Belastung durch
UART-Interrupts gering; nur der adressierte Teilnehmer muß die Daten
empfangen und auswerten.
holger wrote: > Das geht leider nicht. Dazu müssten alle SPI Slaves > per Chip Select gleichzeitig aktiviert werden. Das dumme an der > Geschichte > ist, das dann alle SPI Slaves ihren Ausgang (MISO) aktivieren > und keiner mehr durchkommt weil die sich gegenseitig kurzschliessen. Das geht nur bei den AVRs nicht. Bei den Atmel AT89LP4052 geht das, die können nämlich MISO abschalten und nach dem Adreßbyte schaltet nur der adressierte MC sein MISO ein. Man kann natürlich nicht innerhalb eines Bytes umschalten. Außerdem haben sie einen Sendepuffer und Interruptprioritäten. D.h. der Master kann Fullspeed die Daten empfangen. Bei den AVRs muß der Master nach jedem Byte lange warten oder ne extra Handshakeleitung abfragen. Peter
Hallo :) Also wir werden das auf jeden Fall über SPI machen. Die Controller haben eh nicht viel zu tun, also ist das Warten auf das Ende einer Übertragung in diesem Fall völlig schnurz :) Aber eine kleine Sache noch: Die Übertragung wird durch den Master dadurch gestartet, in dem er den SS-Portpin auf LOW zieht. Wenn ich aber wie in unserem Fall mehrere Slaves habe, dann könnte ich doch einfach eine Adressierung der anderen Slaves dadurch vornehmen, in dem ich die SS-Portpinne der Slaves mit anderen unbelegten Portpinnen des Masters verbinde, oder? So kann ich doch über Code bestimmen, welchen Portpin der Master auf LOW zieht und damit einem bestimmten Slave signalisieren, dass nun eine Übertragung startet. Weil die Controller haben ja nur einen SS-Pin ... Übrigens danke für Eure Anregungen. Aber es hat mehrere Gründe, warum wir das mit SPI machen. Dass es einfachere und schnellere Varianten gibt, ist klar. :) Grüße, Dennis
hehe..das Letzte könnt Ihr stornieren :-D Dann wäre das ja wieder Stern! Hab mich vertan!
@Dennis Gensauso wie du es im Post von 12:49 beschrieben hast funktioniert das. MISO, MOSI, SCLK von allen Slaves und Master miteinander verbinden; Das ist keine Serienschaltung sondern Parallel. Und dazu die Chipselect, oder SS, im Stern vom Master zu den einzelnen Slaves. Dazu benötigst du am Master für jeden Slave einen eigenen Portpin der am Slave als Chipselect funktioniert. Der "Stern" ist NUR für die Chipselselect,SS Die Übertragung startet aber nicht mit Chipselect. Dieser Pin ist nur um das SPI interface des Slave aktiv zuschalten und das der Slave informiert wird, sein Datenbyte in den Ausgangspuffer legt. Die Übertragung startet mit dem ersten Clock vom Master.
Ja okay. Das habe ich nun verstanden :) Danke! Laut Holger (03.1. 22:14) sind die MISO zwangsgesteuert. Im Datenblatt steht aber was anderes. Da steht drin, dass man per Software bestimmen kann, welchen Zustand die Ausgänge haben (Seite 66 unten: "When the SPI is enabled as a Slave, the data direction of this pin is controlled by DDB6" Also lässt sich das doch im Code anhand des Zustands vom Slave-Select Pin abfragen, oder? Und weil die Übertragung mit dem Clock-Signal startet und dieses mindestens 4mal langsamer ist als der Prozessortakt, kann man diese Pinne doch ohne Probleme über DDb6 steuern, oder? Kann ich nun Stern bauen oder nicht? ;)
Warum eigentlich nicht TWI einsetzen? das ist doch für bis zu 127 Teilnehmer ausgelegt...
>Warum eigentlich nicht TWI einsetzen? das ist doch für bis zu 127 >Teilnehmer ausgelegt... Les doch einfach mal das Topic ganz durch. Er hat es doch schon mehrfach gesagt. Es soll definitiv per SPI gemacht werden also erübrigt sich die Diskussion darüber welchen Bus man nehmen sollte und welcher besser sein könnte usw.
Trotzdem eine berechtigte frage. aber warum einfach wenn schwierig auch geht :-=
Hey :) Es ist keine berechtigte Frage. Wie Du gelesen hast, ist das meine Projektarbeit. Und wenn das eine gewählte Vorgabe ist, dann ist das halt so, gell ;) Aber ich bin immer noch keinen Schritt weiter was die Verbindung betrifft.
@Dennis MISO, MOSI, SCLK werden von SPI interface in Hardware gesteuert. Configuriere diese PINS (an Master und Slave) und den SS (nur an den slave) für SPI Funktionalität, NICHT als IO Pins und ansonsten lass die Finger von diesen Pins, es sei denn du willst die SPI in Software darstellen. Chipselect oder auch SS genannt werden VOR der Kommunikation vom Master auf Aktiv gesetzt. In der Regel ist das LOW signal, muss aber nicht. Und nach dem letzten Takt des letzten Bytes auf der SCLK Leitung wieder auf Passiv gesetzt. Wenn also zu einem Slave zb 5 Bytes gesendet werden sollen, dann ist folgenden Ablauf: 1. Chicselect auf Passiv für alle Slave ( sollte Immer so sein, wenn keine Kommunukation läuft) 2. Chipselect auf Aktiv für den ausgewählten Slave 3. Master und Slave legen Byte 1 in den Ausgansbuffer. 4. Der Master taktet das Byte über SCLK raus. 5. Master und Slave lesen Byte 1 aus dem Eingangsbuffer 6. Master und Slave legen Byte 2 in den Ausgansbuffer 7. Der Master taktet das Byte über SCLK raus. 8. Master und Slave lesen Byte 2 aus dem Eingangsbuffer 9. Master und Slave legen Byte 3 in den Ausgansbuffer 10. Der Master taktet das Byte über SCLK raus. 11. Master und Slave lesen Byte 3 aus dem Eingangsbuffer 12. Master und Slave legen Byte 4 in den Ausgansbuffer 13. Der Master taktet das Byte über SCLK raus. 14. Master und Slave lesen Byte 4 aus dem Eingangsbuffer 15. Master und Slave legen Byte 5 in den Ausgansbuffer 16. Der Master taktet das Byte über SCLK raus. 17. Master und Slave lesen Byte 4 aus dem Eingangsbuffer 18. Chipselect für den ausgewähten Slave auf Passiv 19. ENDE
@Ralph: Jau danke! Das hat mir weitergeholfen! Da Du über Chipselect einen Slave anwählst, kann der Bus nur in Stern geschaltet sein. Also geht das so! Und der Ablauf ist mir nun auch klar! Vielen Dank! ;)
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.