Mehrere I²C-Slaves mit unterschiedlichen Adressen VS. Verwendung eines Multiplexers

Ich möchte viele identische I²C-Sensoren, sagen wir 32, mit einer MCU verbinden, die nur 2 I²C-Busse hat.

Ich kann jeden Sensor so konfigurieren, dass er bis zu 8 verschiedene Adressen hat. Daher kann ich 8 Sensoren pro Bus oder 16 Sensoren insgesamt haben, was für meine Anwendung nicht ausreicht.

Ich plane, einen Multiplexer oder eine Art I²C-Puffer (beschrieben in diesem Dokument , Seite 8) zu verwenden, um die Anzahl der Sensoren zu erhöhen, die ich anschließen kann.

Allerdings muss ich mich jetzt zwischen mehreren Optionen entscheiden:

  • 4 verschiedene Sensorbusse mit jeweils 8 Sensoren haben und zwei 2-Kanal-Multiplexer (oder Puffer) auf jedem MCU-Bus verwenden, um zwischen diesen 4 Sensorbussen umzuschalten.
  • 8 verschiedene Sensorbusse mit jeweils 4 Sensoren haben und zwei 4-Kanal-Multiplexer auf jedem MCU-Bus verwenden, um zwischen diesen 8 Sensorbussen umzuschalten.

Das sind nur Beispiele, es gibt viele andere Konfigurationen, aber die Frage ist dieselbe:

Gibt es einen Grund, mehr Kanäle mit jeweils weniger Sensoren gegenüber weniger Kanälen mit jeweils mehr Sensoren zu bevorzugen?

Ich habe versucht herauszufinden, ob es eine Änderung in der max. Aktualisierungsrate meiner Sensoren in jeder Konfiguration, aber ich kann keinen Unterschied feststellen.

Wenn einige von Ihnen bereits mit diesem Dilemma konfrontiert waren und / oder eine Antwort haben, würde ich mich freuen, es zu hören!

BEARBEITEN: Der fragliche Sensor ist der TLV493D , ein 3-Achsen-Magnetometer. Eine Beschreibung des Busses mit bis zu 8 Sensoren finden Sie auf Seite 24 des zuvor verlinkten Benutzerhandbuchs.

Ich habe noch keine genaue Vorstellung von Multiplexern, aber es wird wahrscheinlich etwas Ähnliches wie die PCA954*-Familie sein.

"weniger" nicht "weniger". Was ist der Sensor - Datenblatt bitte.
Sie haben 2 I2C-Busse in Ihrem Mikro, sodass Sie 2 I2C-Operationen gleichzeitig ausführen können. Es sollte keine Rolle spielen, ob Sie jeden als 2x8 oder 4x4 aufteilen, Sie können immer noch nur mit einem Gerät pro Bus gleichzeitig sprechen.
@Andyaka, der Beitrag wurde bearbeitet.
@brhans, das ist in der Tat die Schlussfolgerung, zu der ich gekommen bin. Ich wollte sicher sein, dass ich nichts verpasse. Der einzige Unterschied, den ich bisher sehe, ist die Anzahl der Pull-up-Widerstände, die ich verwenden muss, aber das ist keine große Sache für mich.
Ich würde erwägen, den Adressraum zu maximieren und Muxes nach Bedarf auf nur einem Bus hinzuzufügen. Oftmals (in der Zukunft) habe ich festgestellt, dass ich wünschte, ich hätte einen anderen Bus zur Verfügung, um meinem Projekt neue Widgets hinzuzufügen. Oder vielleicht könnten die Pins für den anderen verfügbaren Bus auch für SPI, UART oder sogar DIO verwendet werden. Es ist schön, Optionen zu haben ...
@ChrisKnudsen Bitte schreiben Sie Antworten in das Antwortfeld, damit Ihre Antwort durch Abstimmen, Bearbeiten, Akzeptieren usw. überprüft werden kann.
Ist die Aktualisierungsrate für Sie eigentlich wichtig? Oder sind andere Dinge wichtig? (Zuverlässigkeit, einfach zu routen, geringer Platzbedarf, Kosten, einfach zu programmieren...)
@pipe, für mich wären die wichtigsten Kriterien die Updaterate und die Kosten. Was meinst du genau mit "Zuverlässigkeit"?
@ChrisKnudsen Danke für deine Antwort. Ich dachte tatsächlich daran, aber ich nahm an, dass das Projekt für neue Funktionen geschlossen war;) Aber Sie haben Recht, das ist eine wichtige Sache, über die Sie nachdenken sollten!

Antworten (3)

Bei näherer Betrachtung der von Ihnen verwendeten Geräte scheint es, dass Sie zum Konfigurieren ihrer Adresse jedes Gerät einzeln einschalten können müssen, was bedeutet, dass Sie einen E / A-Pin pro Gerät benötigen, um es einstellen zu können die Adresse.

Um 8 Adressen konfigurieren zu können, müssen Sie zusätzlich die Spannung am SDA-Pin einstellen können, wenn das Gerät eingeschaltet ist. Diese Bedingung wird mit I2C-Multiplexern schwer zu erfüllen sein. Um dies zu erreichen, müssten Sie ein Paket über den I2C-Bus senden und sicherstellen, dass die SDA-Leitung für 200 us entweder hoch oder niedrig gehalten wird. Während dieser 200 us müssen Sie ein Gerät einschalten.

Aus diesem Grund ist es möglicherweise besser, einen anderen Satz von Optionen als meinen ursprünglichen Vorschlag zu wählen:

Option 1

Die einfachste Methode wäre die Verwendung eines Paares von I2C-Multiplexern, von denen einer mit jedem I2C-Master verbunden ist. Jeder E/A-Expander hätte 4 Downstream-Busse mit 4 Geräten.

Da an jedem Bus nur 4 Geräte vorhanden sind, bedeutet dies, dass das LSB der Adresse (eingestellt durch die SDA/ADDR-Pin-Spannung beim Einschalten) immer auf 1 gesetzt werden kann (der Leerlaufwert des I2C-Busses). Dadurch entfällt die Schwierigkeit, die SDA-Spannung beim Einschalten der Geräte auf den richtigen Pegel einzustellen.

Zweitens können Sie sich darauf beschränken, nur 3 I/O-Pins zum Einschalten der Geräte zu benötigen. Die Einschaltsequenz kann wie folgt aussehen:

  1. Das erste Gerät an jedem Bus wird mit VCC eingeschaltet. Nach dem Einschalten schreiben Sie in jeden Bus, um das MOD1-Register auf b11 zu ändern.

  2. Sie verwenden eine E/A-Leitung, um das zweite Gerät an jedem Bus einzuschalten. Wieder können Sie jetzt auf jeden Bus schreiben und das MOD1-Register auf b10 ändern.

  3. Sie verwenden eine zweite E/A-Leitung, um das dritte Gerät an jedem Bus einzuschalten. Schreiben Sie in jeden Bus, um MOD1 auf b01 zu ändern.

  4. Sie verwenden Ihre dritte E/A-Leitung, um das vierte und letzte Gerät an jedem Bus einzuschalten.

Damit haben Sie nun 8 Busse, die jeweils aus 4 Geräten mit einer eindeutigen Adresse bestehen. Es besteht keine Notwendigkeit, den SDA/ADDR-Pin auf eine bestimmte Spannung einzustellen.

Option 2

Die zweite Möglichkeit besteht darin, für jedes Gerät einen I2C-Puffer/Isolator (z. B. PCA9515a) zu verwenden. Sie verbinden eine 16er-Gruppe über Isolatoren mit einem Master und die andere 16er-Gruppe über Isolatoren mit dem zweiten Master.

Sie würden dann 16 E/A-Pins benötigen, um die Aktivierungspins der Isolatoren zu steuern. Jeder I/O-Pin steuert einen Isolator auf jedem I2C-Master.

Um von einem Gerät zu lesen, aktivieren Sie einfach den entsprechenden Isolator und lesen zwei Geräte gleichzeitig mit Ihren beiden Mastern. Das Aktivieren von I/O-Pin 0 ermöglicht das Lesen von Gerät 0 auf jedem Master, I/O-Pin 1 ermöglicht das Lesen von Gerät 1 auf jedem Master und so weiter.

Um E/A-Pins zu sparen, könnten Sie einen 74HC154 oder einen ähnlichen 4:16-Zeilendecoder verwenden, da Sie immer nur einen Isolator zu einem bestimmten Zeitpunkt ausgewählt haben. Dies reduziert Ihren I/O-Pin-Bedarf von 16 auf 4.



Alte Antwort (gilt für Geräte, die die Adresse mit Axx-Pins festlegen):

Wenn Sie einen I2C-Multiplexer verwenden, müssen Sie einen Befehl an den Multiplexer schreiben, um zu ändern, welcher Downstream-Bus gerade aktiv ist. Das braucht Zeit.

Wenn Sie weniger Downstream-Busse zum Umschalten haben (dh die Anzahl der Geräte auf jedem Bus maximieren), reduzieren Sie die Anzahl der zum Lesen aller Geräte erforderlichen Befehle – Sie können alle Geräte auf einem Bus lesen und dann zum nächsten Bus wechseln.

Der schnellste Weg, alle Geräte zu lesen, ist die Option, die mehr Geräte pro Downstream-Bus und weniger Downstream-Busse hat.

In Ihrem Fall haben Sie zwei Upstream-Busse. Verbinden Sie diese jeweils mit einem I2C-Multiplexer. Zu jedem I2C-Multiplexer führen zwei Downstream-Busse mit 8 Geräten.

Während Sie sich für einen 1:2-Mux entscheiden können, der Ihnen gerade genug Adressraum bietet, könnten Sie immer noch einen 1:4-Mux verwenden, bei dem zwei Downstream-Busse auf jedem Mux ungenutzt bleiben. Dies gibt Ihnen die Möglichkeit, bei Bedarf später zusätzliche Geräte hinzuzufügen.

Vielen Dank für Ihre Antwort. Ich hatte das im Sinn, aber ich dachte, der Befehl zum Umschalten des Multiplexers wäre im Vergleich zur Zeit zum Lesen jedes Sensors unbedeutend. Glauben Sie, dass diese Befehle die Aktualisierungsrate erheblich erhöhen würden?
@JK hängt davon ab. Benötigt zwei I2C-Bytes, um den Bus zu ändern. Wenn Sie also 8 pro Bus haben, sparen Sie jedes Mal zwei Bytes, wenn Sie von allen Sensoren lesen (das sind 40 us bei einem 400-kHz-Bus).
WAHR. Ist es in Anbetracht dessen richtig zu sagen, dass es besser ist, Puffer wie im TI-Anwendungsbericht (z. B. PCA9515) über Mux zu verwenden, da deren Befehl nur einen zusätzlichen Pin (für eine 2-Kanal-Umschaltung) und nicht I²C erfordert Befehle?
@JK Im Wesentlichen ist ein I2C-Mux im Grunde nur ein I2C-E / A-Expander und eine Reihe von Puffern. Der E/A-Expander wählt einfach aus, welcher Puffer aktiviert wird. Wenn Sie die freien E/A-Pins auf Ihrer MCU haben, können Sie dem TI-App-Bericht folgen und Puffer verwenden - im Wesentlichen ersetzen Ihre MCU-E/A-Pins den I2C-E/A-Expander.
Perfekt, ich werde mich dafür entscheiden und Sie im Falle eines Problems informieren.
@JK Ich habe gerade das Datenblatt Ihres Sensors gelesen, und es scheint, dass das Einstellen der Adresse nicht so einfach ist, wie ursprünglich angenommen. Ich habe der Antwort einige Optionen hinzugefügt.
Ja, ich war mir des ganzen Durcheinanders bewusst, um die Adressen der Sensoren einzustellen ... Die Lösung, die ich gefunden habe (nicht so entwickelt wie Ihre), bestand darin, Geräte auf verschiedenen Downstream-Bussen für die Einschaltsequenz zu gruppieren . Zum Beispiel würde ich die 4 Nr. 1-Sensoren einschalten, ihre Adresse konfigurieren, dann die 4 Nr. 2 einschalten, sie konfigurieren und so weiter. Ich bräuchte dann nur noch 7 I/O-Pins und keine weiteren Bauteile

Aus Programmiersicht:

Höchstwahrscheinlich werden alle Ihre Magnetometer von einem einzigen Thread verwaltet. Reservieren Sie am besten einen I²C-Bus für diesen Thread, damit Sie die isochrone Abtastung problemlos implementieren können. Dadurch wird es einfacher, eine zeitdiskrete Regelung zu realisieren.

Der andere I²C kann dann von einem anderen Thread gesteuert werden und sammelt alle anderen Sensoren, die Sie möglicherweise benötigen.

Ich kann jeden Sensor so konfigurieren, dass er bis zu 8 verschiedene Adressen hat. Daher kann ich 8 Sensoren pro Bus oder 16 Sensoren insgesamt haben, was für meine Anwendung nicht ausreicht.

Laut Datenblatt werden zum Einstellen von 8 Slaves mit unterschiedlichen Adressen 7 zusätzliche IO-Leitungen benötigt. Um den Bus (über einen Multiplexer) zu 32 Slaves zu routen, sind 5 zusätzliche IO-Leitungen und kein Durcheinander beim Einrichten der Slave-Adressen erforderlich.

Sie können wahrscheinlich einen Standard-Multiplexer (1:16 oder 2 x 1:8) verwenden, um die Stromversorgung auf 1 von 16 Slave-Geräten (oder 2 Slaves auf verschiedenen I2C-Bussen) zu schalten, und daher müssen die Busse nicht gemultiplext werden. Ich weiß nicht, wie hoch die Startzeit aus einem ausgeschalteten Zustand für die Slaves ist, daher könnte dies am Ende etwas langsam sein.

Ich sage sicherlich nicht, dass dies die optimale Lösung für Ihre spezifische Anwendung ist, aber es sollte als Option in Betracht gezogen werden, wenn IO-Pins gefragt sind.

Es ist wahr, ich überlege (vorerst), dass ich genügend IO-Pins haben werde, damit dies kein Problem darstellt.