Wie löse ich I2C-Adresskonflikte?

Ich möchte mehrere I2C-Slave-Geräte an einen Mikrocontroller anschließen, alle auf demselben Satz von Pins, aber die I2C-Geräte teilen sich alle dieselbe Adresse. Die Adressen sind in der Hardware festgelegt.

Gibt es eine Möglichkeit, mehrere Geräte mit derselben Adresse zu verbinden?

Vielleicht eine Art I2C-Adressübersetzungsmodul mit jedem Gerät mit einer konfigurierbaren Adresse, damit ich jedem meine eigenen Adressen zuweisen kann.

Antworten (8)

In I2C ist nichts eingebaut, um dies zu tun, normalerweise haben Slave-Geräte einige externe Pins, die auf 0 oder 1 gesetzt werden können, um ein paar der Adressbits umzuschalten, um dieses Problem zu vermeiden. Alternativ habe ich mich mit einigen Herstellern befasst, die 4 oder 5 Teilenummern für ein Teil haben, der einzige Unterschied ist die I2C-Adresse.

Die meisten Geräte haben spezielle Hardware, die die I2C-Kommunikation handhabt, das heißt, das Slave-ACK ist in der Hardware, sodass Sie es wirklich nicht umgehen können.

Was das Übersetzungsmodul betrifft, könnten Sie einige PICs für 0,50 $ mit 2 I2C-Bussen kaufen und einen schnellen Code schreiben, damit sie als Adressübersetzer fungieren, denke ich.

Danke. Ja, diese Geräte haben eine Adressauswahl, aber nur zwischen zwei Adressen und ich möchte mehr als 5 Geräte verbinden, also würde ich immer noch mit Konflikten enden. Ich hatte nicht daran gedacht, einen PIC zu verwenden. Das sollte funktionieren. Gibt es nichts von der Stange, was so etwas macht?
NXP stellt eine Reihe von Multiplexern / Switches für I2C her. Möglicherweise können Sie daraus etwas aufrüsten: ics.nxp.com/products/i2cmuxes. Beispielsweise könnten Sie in Ihrem Fall 3 Unterzweige mit jeweils 2 Geräten erstellen , und verwenden Sie einen der Schalter von NXP, um Ihr Ziel zu erreichen.
Super, genau so etwas habe ich gesucht. Ich wusste nur den Namen nicht. Danke.
Diese Antwort ist 7 Jahre alt, daher glaube ich, dass sie zu der Zeit, als sie angeboten wurde, die beste gewesen sein könnte. Für andere, die jetzt durchkommen, bieten einige der viel neueren Antworten (derzeit in der Liste niedriger eingestuft) möglicherweise bessere Ansätze, die auf neueren Komponenten basieren, die jetzt auf dem Markt sind.

Ich bin gerade auf dieses Problem mit mehreren I2C-Geräten mit einer festen Adresse gestoßen. Unsere Lösung bestand darin, E/A-Leitungen auf dem Mikrocontroller zu verwenden, um die SDA-Leitungen auf den Geräten, die wir nicht ansprechen möchten, hoch zu zwingen, während die E/A-Leitung für das Gerät, auf das wir abzielen, als Eingang eingestellt ist (hohe Impedanz). ). Dies bedeutet, dass nur das Zielgerät mit seiner I2C-Adresse übereinstimmt und die anderen alle nachfolgenden Daten ignorieren.

Mehrere I2C-Geräte mit derselben Adresse

Die Widerstände auf der SDA-Leitung für die inaktiven Geräte fungieren schließlich als Pull-Ups für den Bus, sodass der genaue Wert davon abhängt, wie viele Geräte Sie haben und welchen Pull-Up Sie für Ihren Bus benötigen. Wenn Sie also 10K-Widerstände wählen, ergeben 3 inaktive Geräte einen 3K3-Pullup.

Die Schottky-Dioden stellen sicher, dass das Gerät die SDA-Leitung immer noch niedrig genug ziehen kann, wenn es Daten zurück zum Host überträgt.

Ich weiß es zu schätzen, dass Sie dem nachgegangen sind und dies gepostet haben. Dies ist eine ziemlich geniale Lösung, ich bin sicher, dass sie für andere hilfreich sein wird.
Eine schöne Nische, die für einige Anwendungen verwendet werden kann. Ich mag es sehr.
Ist das nicht ein Workaround für falsches HW-Design? Was ist, wenn wir keine zusätzlichen IO-Pins übrig haben?
Dies ist die kostengünstigste Lösung. Unser Produkt verfügt über zwei gleiche Sensoren und hat kein Budget für zusätzliche ICs. Hier fügen wir nur zwei Dioden und einen Widerstand hinzu. Danke schön!

Es gibt jetzt eine Antwort – Linear Tech hat die LTC4316/17/18-Serie von Adressumsetzern im Angebot. Sie sind relativ neu und die Verfügbarkeit ist ungewiss.

Sehr interessante Komponente. Die meisten I2C-Geräte haben 2 feste Adressen, und dieser LTC4316 könnte potenziell die Adressierung zu angemessenen Kosten verdoppeln.

Wenn keines der I2C-Geräte Clock-Stretching (Handshaking) verwendet und Sie den I2C-Master bit-bangen, besteht ein einfacher Hack darin, einige der Geräte die Uhr- und Daten-Pins tauschen zu lassen. Während der Übertragung eines Bytes sieht das Gerät, bei dem die Takt- und Datenpins vertauscht sind, jedes "0"-Bit als Nichtereignis (Daten steigen und fallen ohne Takt) und sieht jedes "1"-Bit als I2C-Stopp und Start (Takt steigt, während Daten niedrig sind, wird von steigenden und fallenden Daten aufgegeben, gefolgt von fallendem Takt). Absichtliche Stopp- und Startbedingungen für ein Gerät können von dem anderen als Datenbits angesehen werden, aber wenn ein Gerät nicht eine übermäßige Anzahl von Start- und Stoppbedingungen zwischen "1"-Bits hat, wäre es unwahrscheinlich, dass ein Gerät "versehentlich"

Ich stimme nicht ab, aber das scheint mir ein bisschen riskant zu sein. Meine Erfahrung mit I2C ist, dass es mit nur der üblichen Verbindung rauschanfällig genug ist. Sie verwenden jedoch das Wort "Hack" und erwähnen die Einschränkung "wenn keines der i2c-Geräte Clock-Stretching verwendet", also wenn es für jemanden funktionieren kann, dann mehr Leistung für ihn.

Mehrere Hersteller bieten I2C-Bus-Multiplex- und Schalter-ICs an.

Ein Mux kann jeweils einen Kanal aktivieren; Ein Schalter kann mehrere parallel aktivieren.

Prüfen Sie zum Beispiel die Angebote von NXP , TI und Maxim .

Zum Experimentieren hat Adafruit ein TCA9548a-Board .

Wenn Sie 8 Zielchips mit identischen Adressen haben, wählen Sie einen 8-zu-eins-MUX. Bevor Sie auf einen der Zielchips zugreifen, konfigurieren Sie den MUX, um den richtigen I2C-Bus zu aktivieren.

Vorteile

  • Erfordert keine Programmierung (im Gegensatz zu einem mikrocontrollerbasierten Ansatz)
  • Kann die I2C-Funktionen und -Geschwindigkeiten unterstützen, die Sie benötigen (im Vergleich zu normalen analogen / digitalen Bus-Muxes). Zum Beispiel wird ein regulärer (Nicht-I2C) MUX allgemeine Rufadressen nicht an alle seine Kanäle weitergeben.

Ich hatte zwei TCS3414-Farblichtsensoren, die ich vergleichen wollte (die FN- und CS-Pakete, die unterschiedliche Filter haben). Die I2C-Adresse ist fest verdrahtet. Nachdem wir uns angesehen hatten, wie I2C in Bezug auf die SCL- (Takt-) und SDA- (Daten-) Leitungen funktioniert, schien es, dass das Ausschalten der SDA-Leitung verhindern würde, dass der Chip ein Start- oder Stoppbit erhält, und ihn daher inaktiv lassen würde. Verwenden Sie also einen CMOS-Analogschalter (4066B), um die SDA-Leitung zu jedem Gerät ein- oder auszuschalten. Dies funktionierte gut für das Umschalten zwischen den beiden Geräten. Ich weiß, es ist ein Hack, und der PCA9548 wäre viel besser, aber ich hatte keinen zur Hand.

Eigentlich ist dies überhaupt kein Hack, und ich würde argumentieren, dass dies die akzeptierte Antwort sein sollte. Ich habe gesehen, dass dies in mehreren kommerziellen Produkten verwendet wird, und mir fällt keine bessere Lösung ein (es sei denn, Sie haben kein GPIO zur Verfügung und benötigen daher eine reine I2C-Lösung wie die I2C-spezifischen Muxes). Gute alte analoge Muxes haben viel Bandbreite und sind wahnsinnig billig.

Ich würde erwägen, Busschalter zu verwenden, um den I2C-Bus zwischen den Geräten mit widersprüchlichen Adressen zu multiplexen. Busschalter haben eine sehr niedrige Kapazität und einen sehr geringen Widerstand, und im Gegensatz zu Puffern/Treibern sind sie echte Schalter, die zwei Schaltungsknoten verbinden oder trennen.

Busschalter haben normalerweise eine seltsame Eigenschaft, die für I2C keine Rolle spielt, da Open-Drain-Bausteine ​​verwendet werden: Ein Busschalter hat einen niedrigen Einschaltwiderstand, wenn Spannungen nahe 0 (Vss) zusammengebunden werden, aber der Widerstand steigt dramatisch an, wenn sich die Spannungen nähern die Stromversorgung Vdd. (Dies liegt daran, dass es sich im Grunde genommen um MOSFETs mit Gate-Spannungen an der Stromversorgung handelt, wenn sie eingeschaltet werden. Wenn sich die geschalteten Spannungen Vdd nähern, ist die verfügbare Vgs viel niedriger.)

Die Verbindung ist unterbrochen. fairchildsemi.com/product-technology/bus-switches funktioniert besser.

Verwenden Sie einen einfachen Demux-Chip (z. B. 74HC139 afaik) und verbinden Sie den I2C CLK-Pin mit dem Eingang (da der I2C CLK-Pin nur als Ausgang dient). Verwenden Sie GPIO-Pins, um die gewünschte Ausgabe zu steuern. Dann kann der I2C-Daten-Pin zwischen allen Slaves geteilt werden.

SCL wird nicht nur ausgegeben. Ein Sklave kann die Uhr dehnen, wenn er sie verlangsamen muss.
Sie können einen analogen Multiplexer verwenden (der bidirektional ist), aber ein Decoder funktioniert möglicherweise aus dem von Stevenh angegebenen Grund nicht. Wenn Sie einen Multiplexer verwenden, benötigen Sie auf der Slave-Seite einen schwachen Zellstoff, um sicherzustellen, dass er inaktiv bleibt. Ändern Sie die Multiplexer-Auswahl auch nur, wenn der Bus im Leerlauf ist.
Obwohl es keine allgemeine Lösung ist, kann es mit den meisten ICs durchgeführt werden, die keinen internen Mikrocontroller für die I2C-Schnittstelle verwenden. Sichere Geräte können in der Regel anhand der Pin-Beschreibungen oder des Blockschaltbildes in den jeweiligen Datenblättern ermittelt werden. Wenn SCL nur als Eingang konfiguriert ist, würde dies funktionieren.