Gemeinsamen Bus als ODER fungieren lassen

10

Für die Ungeduldigen können Sie den Hintergrund überspringen.

Hintergrund

Ich programmiere eine Reihe von Mikrocontrollern, die mit SPI kommunizieren. Es gibt einen Master und nSlaves, die sich den Bus teilen. Es gibt keine Chipauswahl. (Es ist kein schlechtes Design, aber ngroß und es gibt nicht genug Platz für nzusätzliche Linien).

Es liegt daher in der Verantwortung der Sklaven, ihr MISO in hoher Impedanz zu halten und höchstens einer von ihnen spricht. Dies erfolgt, indem nur geantwortet wird, wenn ihre ID abgefragt wird.

Jetzt möchten wir eine erste Erkennungsphase haben, in der der Master Slaves mit den damit verbundenen IDs erkennt. Um das Leben (in einigen Aspekten) einfacher zu machen, möchten wir, dass die ID eindeutig ist (und daher z. B. 32 Bit). Dies macht es dem Master unmöglich, die IDs einfach einzeln abzufragen und zu sehen, wer antwortet (es gibt zu viele Möglichkeiten).

Um dieses Problem zu lösen, habe ich eine Variante der binären Suche entwickelt, bei der die Slaves gemeinsam antworten und der Master die minimale ID schnell finden kann. Der Slave mit dieser ID wird angewiesen, nicht mehr teilzunehmen, und der Algorithmus wird wiederholt. (Details unwichtig).

Es gibt jedoch ein Problem. Die kollektive Antwort muss das logische ODER (oder logische UND) aller Antworten sein. Mir wurde gesagt, dass die Leitung so konfiguriert werden kann, dass der MISO-Bus als logisches ODER fungieren kann. Was mir gesagt wurde ist:

  • Stellen Sie MISO am Master als Pull-up und ein
  • Stellen Sie MISO auf jedem Slave als Open-Drain ein.

Ich habe es versucht, aber mit nur einem einzigen Slave funktioniert diese Konfiguration nicht (das Oszilloskop zeigt eine konstante Null auf der Leitung). Wenn ich MISO am Master als hochohmigen Eingang konfiguriere, kann ich mit dem Oszilloskop sehen, dass die Spannung auf die Hälfte abfällt, wenn sich die Bits der Ausgänge von zwei Slaves unterscheiden (im Grunde genommen nehme ich einen Kurzschluss an).

Hinweis: Wenn Sie MISO auf dem Master als hochohmig und Slaves als Push-Pull konfigurieren, kann ich mit jedem einzeln sprechen, auch wenn sich viele von ihnen auf demselben Bus befinden. Ich meine, ich bezweifle, dass es ein Problem der Leitung selbst ist.

Frage

Meine Frage ist, ob dies überhaupt möglich ist und wenn ja, wie kann ich die Eingangs- und Ausgangspins des Masters und der Slaves so konfigurieren, dass die gemeinsam genutzte MISO-Leitung als logisches ODER (oder logisches UND) fungiert?


Bearbeiten

  1. Es stellte sich heraus, dass es ein ODER mit negativ-wahrer Logik wird (im Grunde ein UND).

  2. Das Problem mit einem einzelnen Slave wurde behoben, indem 1 in den Pull-up-Pin des Masters geschrieben wurde. Zuvor hatte es einen Anfangszustand von 0.

Bearbeiten 2

Es stellte sich heraus, dass der ST-Slave meine GPIO-Konfiguration von MISO als Open-Drain überschreibt und sie beim Schreiben auf High erzwingt. Ich habe mich entschlossen, SPI zum Schweigen zu bringen und MISO in diesem speziellen Fall manuell auszugeben.

Shahbaz
quelle
Ich würde ungern fragen, weil ich sicher bin, dass Sie darüber nachgedacht haben, aber haben Sie darüber nachgedacht, I2C oder CAN zu verwenden? Sie sind für n Geräte konzipiert, während SPI für die Verwendung mit einer Chipauswahl für jedes Gerät konzipiert ist.
Bob
@ Bob, ja. Sie sind zu langsam. Wenn die Antwort auf meine Frage "Es ist unmöglich" lautet, müssten wir nur ein bisschen Handarbeit leisten, aber das Endprodukt ist mit SPI immer noch viel besser.
Shahbaz
1
Es ist schade, dass Sie 32 Bit als Adresse verwenden, denn wenn Sie 24 Bit (16.772.216 Variationen) verwenden, könnten Sie einen "Entdeckungs" -Befehl senden und 16.772.216 Uhren warten, und Sie könnten alle Ihre Slave-Informationen haben. Bei 10 Mbit / s würde dies weniger als 2 Sekunden dauern und es müssten keine Konflikte auftreten. Hey ho - du hast mich dazu gebracht, so +1 dafür zu denken.
Andy aka
@Andyaka, 24 Bit können auch nicht schlecht sein (aber 32 Bit sind sicherlich besser). Wenn ich dich richtig verstanden habe, meinst du, jeder Slave antwortet bei seiner ID-Uhr mit einer 1 und der Master schaut, welche Uhren eine Eins erzeugt haben? Das ist nicht schlecht, außer dass die Slaves in Bytes antworten. Jeder Slave antwortet also mit 8 Bits, und wenn ich den Bus nicht als ODER fungieren lassen kann, geht die Antwort eines Slaves innerhalb der Antworten des anderen Slaves "verloren" (die 1 von einem Slave wird von den 0en von allen heruntergezogen der Rest).
Shahbaz
@Shahbaz Wenn Sie die Kontrolle über den Code des Slaves haben, können Sie dies zu einem "Special" machen, bei dem der Slave zum zugewiesenen Zeitpunkt nur mit 1 Bit antwortet. Ja, Sie haben den Kern meiner Überlegungen verstanden.
Andy aka

Antworten:

5

Ihr SPI ohne Auswahl wird von Microchip für die MCP23017-Chips (und andere) verwendet. An diesem Ansatz ist nichts auszusetzen.

Ja, was Sie wollen, ist möglich, aber Sie müssen dafür sorgen, dass die Slaves offen sind. Sie könnten schummeln, indem Sie eine (Schottky-) Diode mit jedem Ausgang in Reihe schalten, wenn Sie nicht erreichen können, dass sie sich wie Open-Drain verhalten.

Ihr Aufzählungsansatz ist der gleiche wie der, den der Dallas One-Wire-Bus für die Aufzählung und der CAN-Bus für die Arbitrierung verwenden.

Ein schwerwiegender Nachteil Ihres Ansatzes ist jedoch, dass die Geschwindigkeit jetzt durch die Anstiegszeit begrenzt ist, die vom Pull-up-Widerstand angetrieben wird. Dies ist langsamer als bei einem Push-Pull-Ausgang und begrenzt wahrscheinlich die Geschwindigkeit, mit der Sie den Bus betreiben können.

Wenn Sie zwei Pins für jeden Slave übrig haben, können Sie sie verketten und ein Aufzählungsschema erstellen, das auf ihrem Platz in der Verkettung basiert.

Wouter van Ooijen
quelle
Ja, ich habe vergessen zu erwähnen, dass mir auch gesagt wurde, ich müsse die Geschwindigkeit reduzieren (was ich um das 20-fache getan habe (von 4 Mpbs auf 128 Kbps)). Das ist allerdings eine Anfangsphase und mein Algorithmus kann mit der langsameren Geschwindigkeit umgehen (sie ist immer noch ziemlich schnell). Leider bezweifle ich, dass wir die Hardware jetzt neu gestalten würden. Die Kosten sind mehr als nur das Ignorieren dieser Phase und das Teilen des Masters mit den zu erwartenden IDs.
Shahbaz
Zurück zur Frage, ich habe die Slaves bereits als Open-Drain konfiguriert. Wie soll ich den Master konfigurieren?
Shahbaz
1
Am MISO-Pin des Masters gibt es nichts Besonderes, außer dem Pullup. Ich bezweifle, dass Sie mit einem Pull-up-Design 128 Kbit / s erreichen werden, aber YMMV. Das Lesen einiger detaillierter I2C-Dokumente kann hilfreich sein, dh ein Draht- oder Pull-up-Bus. Daher kann Ihnen jeder dort angewendete Trick helfen.
Wouter van Ooijen
Danke vielmals. Ich werde versuchen, den Bus noch langsamer zu machen, um zu sehen, was passiert. Ich denke, ich muss endlich studieren und verstehen, was diese Pull-up-, Open-Drain- und andere eigentlich bedeuten. (Software-Ingenieur hier!)
Shahbaz
1
Setzen Sie ein Oszilloskop in den Bus und überprüfen Sie, was passiert. Die Anstiegszeit ist möglicherweise zu langsam, es kann jedoch auch ein Klingeln auftreten.
Wouter van Ooijen
4
  • Stellen Sie MISO am Master als Pull-up und ein
  • Stellen Sie MISO auf jedem Slave als Open-Drain ein.

Ich habe es versucht, aber mit nur einem einzigen Slave funktioniert diese Konfiguration nicht (das Oszilloskop zeigt eine konstante Null auf der Leitung).

Sie müssen überprüfen, wie hoch der äquivalente Widerstand des Master-E / A-Pins im Pull-up-Modus ist.

Typischerweise hat der Pull-up-Modus einen sehr hohen Widerstand, möglicherweise 50 kOhm oder höher. Es ist beabsichtigt, zu verhindern, dass der Pin aufgrund von EMI oder anderen Störungen fehlerhaft wird, oder einen Standard für sehr langsame Steuersignale festzulegen und gleichzeitig nicht zu viel Strom zu verschwenden.

Wie Wouter betonte, wird in einem Open-Drain-Bus die Geschwindigkeit durch den Pull-up-Widerstand begrenzt. Höhere Widerstandswerte verlangsamen den Bus. Typische Werte in I2C (die 100 oder 400 kHz erreichen) sind 1 bis 5 kOhm. Sie möchten einen ähnlichen Pull-up-Widerstand, um eine ähnliche Geschwindigkeit zu erreichen.

Ich denke, Sie müssen einen externen Pull-Up-Widerstand (von 1 bis 5 kOhm oder so) anstelle des I / O-Pin-Pull-Ups des Masters verwenden, damit dieses Schema funktioniert.

Das Photon
quelle
Danke für die Hinweise. Ich bin kein Elektronik-Typ, aber ich muss meinen Kollegen bitten, sich Ihren Vorschlag anzusehen. Ich brauche das Kabel oder nur für eine Anfangsphase des Programms und in der normalen Phase ist der Pin nicht als Pull-Up konfiguriert. Ein externer Widerstand ist also wahrscheinlich keine Option.
Shahbaz
Wenn Sie einen freien E / A-Pin am Master-Mikro haben, können Sie ihn beispielsweise über 5 kOhm an den Bus anschließen. Schalten Sie es dann während der Busaufzählung hoch und während der normalen Kommunikation hoch-Z.
Das Photon
1

Damit ein Kabel- und ein Bus funktionieren, müssen die Knoten auf dem Bus offen sein, dh sie müssen senden

  • die Logik niedrig durch starkes Herunterziehen, und
  • die Logik hoch durch Trennen vom Bus.

Außerdem muss der Bus schwach hochgezogen werden.

Das eigentümliche Verhalten, das Sie bei einem einzelnen nicht sendenden Master und einem einzelnen sendenden Slave sehen, kann entweder dadurch erklärt werden, dass der Master stark nach oben oder der Slave schwach nach unten zieht.

Sie müssen feststellen, welche der oben genannten Aktionen ausgeführt werden.

Versetzen Sie den Slave in den hochohmigen Modus und verbinden Sie den Bus über einen 10k-Widerstand mit Masse. Wenn sich die Netzspannung nicht wesentlich ändert, zieht der Master stark an und Sie müssen das beheben. Andernfalls gehen Sie genauso mit dem Slave vor (diesmal verbinden Sie den Widerstand mit Vcc). Wenn die Netzspannung deutlich ansteigt, zieht der Slave schwach nach unten (beheben Sie das). Suchen Sie andernfalls nach Zeit-Raum-Verzerrungen in der Umgebung.

Avakar
quelle
Entschuldigen Sie meine Unkenntnis in der Elektronik, aber wenn der Slave stark nach unten zieht, fungiert der Bus dann nicht als UND? Ich sage, da die Sklaven, die hoch wollen, die Verbindung trennen und diejenigen, die niedrig wollen, nach unten ziehen, also ist das Gesamtergebnis unten, nein?
Shahbaz
@ Shahbaz, mein schlechtes, natürlich wird der Bus verkabelt - und ich habe die Antwort korrigiert. Wenn Sie verkabelt oder möchten, kehren Sie einfach die Polaritäten um (Master zieht schwach nach unten, Slaves ziehen stark nach oben).
Avakar
Als ich in Wikipedia las, wurde mir klar, dass sie es als verkabelt und / oder verkabelt oder mit negativ wahrer Logik bezeichnen.
Shahbaz
1

Ich würde vorschlagen, ein passives Pull-up oder Pull-down im Bus zu haben (ich nehme an, Pull-up) und Slaves den Bus aktiv fahren zu lassen (hoch und niedrig fahren), wenn sie etwas zu sagen haben und es anders schweben lassen . Haben Sie Abfrage-Adress-Befehle, die eine Adresse und eine Maske annehmen und jeden Slave anweisen, 00 auszugeben oder nichts zu tun (schweben Sie die Ausgabe weiter), je nachdem, ob ihm die Adresse und die Maske gefallen. Wenn möglich, lassen Sie den Master den Bus einige Zeit aktiv hochfahren, bevor die Slaves ihn fahren. Abhängig von der Stärke des Pull-Ups und davon, ob der Master den Bus hoch fährt, bevor die Slaves ihn niedrig ziehen dürfen, kann es erforderlich sein, die Busgeschwindigkeit während der Setup-Phase zu begrenzen. Sobald die Einrichtung abgeschlossen ist,

Superkatze
quelle
Wenn zwei Slaves aktiv hoch und niedrig fahren, was soll ich dann vom Bus lesen?
Shahbaz
Man sollte vermeiden, dass jemals ein Slave versucht, hoch zu fahren, während ein anderer niedrig fährt. Ein Slave sollte den Bus nur fahren, wenn entweder (1) er weiß, dass dies das einzige ist, oder (2) er weiß, dass er und alle anderen, die den Bus fahren, ihn zum Gegenteil seines passiven Leerlaufs fahren Zustand.
Supercat
Was bedeutet das dann? ... wenn jeder ausgewählte Slave sowohl hohe als auch niedrige Pegel aktiv fährt, kann der Bus ...
Shahbaz
@ Shahbaz: Wenn ein Slave etwas zu sagen hat, sollte er den Bus aktiv hoch treiben, um "1" -Bits zu senden, und niedrig, um "0" -Bits zu übertragen. Wenn ein Sklave nichts zu sagen hat, sollte er den Bus überhaupt nicht fahren. Beachten Sie, dass Slaves den Bus aktiv hoch fahren lassen, wenn sie "1" -Bits senden möchten, wodurch der Bus viel schneller arbeiten kann, als wenn ein passiver Pull-up erforderlich wäre, um den Bus hoch zu fahren.
Supercat
@ Shahbaz: Was Supercat zu sagen versucht, ist, dass im Aufzählungsstatus ein Widerstand die Leitung hochziehen sollte und Slaves nur "0" oder nichts senden sollten (Open-Drain-Ausgang), aber danach bei normaler Kommunikation nur noch a Es sollte jeweils ein einzelner Slave aktiv sein, und der aktive Slave sollte "0" oder "1" senden (normaler Ausgang). Somit begrenzen der Pull-up-Widerstand und die Leitungskapazität nur die Bitrate während der Aufzählung. Danach kann bei normaler Kommunikation die Bitrate höher sein, wie es das aktive Fahren zulässt.
Laszlo Valko