Warum führt das Einfügen von Widerständen zwischen Vcc / SDA und Vcc / SCL in I2C zu einer Rechteckwelle?

8

Ich versuche zu verstehen, warum das Platzieren von Widerständen zwischen Vcc und den Daten- / Taktleitungen dazu beiträgt, dass meine Wellenform quadratisch ist, wenn ich zwischen Arduino und einem EEPROM-Chip kommuniziere. Wenn keine Widerstände im Stromkreis platziert sind, sehen die Wellen wie Haifischflossen aus. Die Schaltung funktioniert immer noch, aber es sind definitiv seltsam aussehende Wellen.

Als Hintergrund stellte sich diese Frage, nachdem ein Arduino mit I2C an einen Microchip 24LC256 (EEPROM) angeschlossen wurde. Als ich die Signale mit meinem Oszilloskop untersuchte ( versuchte, etwas zu tun, das nichts damit zu tun hatte ), bemerkte ich, dass die Wellen schrecklich aussahen. Sie sahen für mich wie Haifischflossen aus (gibt es dafür eine akzeptiertere EE-Formulierung?). Ich habe mehrmals überprüft, ob meine Sondenbereiche korrekt eingestellt / kompensiert wurden, und festgestellt, dass ich bei anderen Schaltkreisen kein solches Verhalten festgestellt habe. So sah die Verkabelung aus:

Ursprüngliche Verkabelung

Gelbes Signal ist die SDA-Leitung und Blau ist SCL

In einem zufälligen Gespräch erzählte ich einem EE davon - und sie sagten, dies sei für I2C nicht ungewöhnlich. Er empfahl, einen 10k Ohm Widerstand zwischen Vcc und SCL zu legen und einen niedrigeren Widerstand zwischen Vcc und SDA zu versuchen. Zusätzlich empfahl er, die I2C-Geschwindigkeit auf die niedrigste Einstellung zu reduzieren (31 kHz für Uno). Sicher genug, wenn ich einen 10k-Widerstand zwischen Vcc / SCL und einen 4,7k-Widerstand zwischen Vcc / SDA setze - sie sehen gut und quadratisch aus. Ich habe auch die Geschwindigkeit von normal auf 31 kHz gesenkt, aber das hat einen viel geringeren (wenn überhaupt) Einfluss.

Leider hatte ich nie die Gelegenheit zu fragen warum! Ich bin ein Neuling in der Elektronik, aber ich bin sehr neugierig, warum ein so platzierter Widerstand dazu führt, dass sie besser aussehende Rechteckwellen sind. Dieses Foto unten ist nach der Verwendung von Widerständen, aber vor der Auswahl der "optimalen" Widerstandswerte für die am besten aussehenden Rechteckwellen. Ich denke es sieht viel besser aus.

Geben Sie hier die Bildbeschreibung ein

Ich habe nach Erklärungen für Stack Exchange gesucht, aber ohne Erfolg. Diese schienen (möglicherweise) meinem Problem ähnlich zu sein: Problem mit der I2C-EEPROM-Kommunikation (seine Wellen sehen ähnlich aus wie meine, aber die Antwort ging nicht auf meine Frage ein) I2C-Schnittstelle zwischen zwei Chips (diese schien ebenfalls ziemlich vielversprechend, aber nicht Ich beschäftige mich nicht mit dem "Warum".) Seltsame I2C-Signale, die vom FPGA ausgesendet werden (dies schien mit etwas anderem zu tun zu haben ... obwohl ihre Wellen ähnlich "hässlich" aussehen).

Danke für die Hilfe!

Thomas
quelle
1
Lange Rede, kurzer Sinn (und stark vereinfacht): Es soll quadratisch sein und es ist der Mangel an Widerstand, der dazu führte, dass es nicht quadratisch war. Oder tatsächlich war der Widerstand zu hoch und der zusätzliche Widerstand senkte ihn (weil parallel) weit genug, um die Anstiegszeit festzulegen. Schauen Sie sich die RC-Zeiten an.
Mast

Antworten:

9

I2C ist ein Bus, der Open-Drain-Ausgänge verwendet. Ein offener Abfluss ist wie ein Schalter zwischen Ausgang und Masse. Ohne Pullup-Widerstände funktioniert es nicht, da es nichts gibt, was es hoch bringen könnte.

Wenn die Pullup-Widerstände einen zu hohen Wert haben, funktioniert sie nicht (oder nicht zuverlässig), da der Widerstand die Kapazität der Eingänge, des Ausgangs, des Kabels und möglicherweise einer Oszilloskopsonde nicht schnell genug auflädt . Wenn sie zu niedrig sind, ist der Ausgang nicht stark genug, um ihn nach unten zu ziehen.

Sie bemerken, dass bei Ihrer Oszilloskopmessung die Ausgänge sehr schnell niedrig werden, aber nur schleppend auf Logikpegel 1 ansteigen.

Wenn der Code auf Ihrem Arduino die internen Pullup-Widerstände des ATMega verwendet, um eine I2C-Schnittstelle zu schlagen, haben sie wahrscheinlich einen zu hohen Wert (mehrere zehn K Ohm und nicht genau spezifiziert), um zuverlässig zu arbeiten parallel zu externen Widerständen sein.

Persönlich hätte ich den Code geschrieben, um die internen Pullups (standardmäßig) nicht zu verwenden, um zu vermeiden, dass der Bus "fast" nicht funktioniert, und den Benutzer zu zwingen, die Widerstände zu verwenden oder absichtlich die internen zu verwenden. Es ist möglich, dass sie akzeptabel sind, wenn die Chips sehr nahe beieinander liegen, eine niedrige Geschwindigkeit (100 KB) verwendet wird und keine Oszilloskopsonden (insbesondere in x1) angebracht sind.

Ich habe eine sehr ähnliche Situation gesehen, in der versehentlich 47K-Widerstandsnetzwerke anstelle von 4,7K installiert wurden.

Spehro Pefhany
quelle
1
Danke Spehro, das ist sehr hilfreich. Ich bin nicht sicher, ob die "Draht" -Bibliothek auf dem Arduino standardmäßig die internen Pull-up-Widerstände verwendet, aber ich tue in meinem Code nichts explizites, um sie zu verwenden. Ich stimme zu, dass ich diese Widerstände lieber absichtlich auswählen lassen möchte, als mich im Code darauf zu verlassen. Könnte helfen, solche Situationen zu verhindern. Entschuldigung, eine kurze Frage: Warum würde sich die Verwendung von Oszilloskop-Sonden (insbesondere in x1) darauf auswirken?
Thomas
Scope-Sonden im x1-Modus erhöhen die Kapazität möglicherweise um 30-40 pF, was aufgrund der anderen Faktoren die bereits vorhandene Kapazität mehr als verdoppeln kann. In x10 beträgt die zusätzliche Last eher 1/10 davon.
Spehro Pefhany
5

I2C soll ohne Pull-up-Widerstände überhaupt nicht funktionieren . Sie sind bei der Gestaltung des Busses ausdrücklich erforderlich.

Tatsächlich ist Ihre Frage also umstritten - machen Sie es falsch und es passieren schlimme Dinge.

Wenn Sie wirklich genau verstehen möchten, was passiert, ist es wahrscheinlich, dass Sie einen schwachen Pull-up-Effekt durch einen Leckstrom oder möglicherweise sogar einen internen Pull-up-Widerstand erhalten, der etwa zehnmal größer ist als der I2C-Buswiderstand. Dies verursacht diese exponentielle RC-Anstiegswellenform - die klassische eines Kondensators, der über einen Widerstand aufgeladen wird. Mit einem Pull-up-Widerstand mit dem richtigen Wert geschieht dies immer noch, aber schnell genug, dass das Exponential auf dem Oszilloskop vertikal aussieht.

Unabhängig davon, welche Stromquelle die Leitung in Abwesenheit eines echten Pull-up-Widerstands hoch bringt, ist sie schwach (dh die Schaltung ist sehr hochohmig), so dass sie auch extrem anfällig für kapazitive Kopplung von der Taktleitung ist, wie Sie sehen Die Spitzen der Datenleitungswellenform zeigen Artefakte, wenn die Uhr schaltet.

Verwenden Sie die erforderlichen Pull-up-Widerstände. Legen Sie einen Versorgungsbypass-Kondensator über Ihren Chip. Halten Sie die Verkabelung so kurz wie möglich. Befolgen Sie die Regeln und vermeiden Sie die Probleme, die charakteristisch sind, wenn Sie sie brechen.

Chris Stratton
quelle
Danke, Chris. Ich nehme an, dies ist die Gefahr, blind einem Online-Tutorial zu folgen, in dem Pull-up-Widerstände nicht verwendet werden. Vielen Dank für die Erklärung (und ja, ich wollte wissen, was der Grund für das Geschehen war).
Thomas
@Thomas - leider ist die Welt der Online-Arduino-Tutorials ebenso eine Sammlung von Dingen, die man nicht tun sollte, wie man sollte - einschließlich einiger offizieller von Arduino. Das heißt nicht, dass sie nicht nützlich sein können, aber man muss oft drei oder vier schlechte durchwaten und ablehnen, um etwas zu finden, das tatsächlich funktioniert, und den Chip, von dem man gehofft hatte, dass er einen Arduino herausholt, schnell bewerten kann.
Chris Stratton