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

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 in der Schaltung 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 Unabhängiges zu debuggen ), bemerkte ich, dass die Wellen schrecklich aussahen. Sie sahen für mich wie Haifischflossen aus (gibt es dafür einen akzeptierteren EE-Ausdruck?). Ich habe mehrmals überprüft, ob meine Sondenfernrohre richtig abgestimmt/kompensiert waren, und festgestellt, dass ich auf anderen Schaltungen kein solches Verhalten hatte. So sah die Verkabelung aus:

Originale 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, dass dies für I2C nicht ungewöhnlich sei. Er empfahl, einen 10-kOhm-Widerstand zwischen Vcc und SCL zu platzieren und einen niedrigeren Widerstand zwischen Vcc und SDA zu versuchen. Außerdem empfahl er, die I2C-Geschwindigkeit auf die niedrigste Einstellung (31 kHz für Uno) zu reduzieren. Sicher genug, wenn ich einen 10k-Widerstand zwischen Vcc/SCL und einen 4,7k-Widerstand zwischen Vcc/SDA stecke - sie sehen schön und quadratisch aus. Ich habe auch die Geschwindigkeit von normal auf 31 kHz gesenkt, aber das hatte einen viel geringeren (wenn überhaupt) Einfluss.

Leider kam ich nie dazu 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 finde es sieht viel besser aus.

Geben Sie hier die Bildbeschreibung ein

Ich habe auf Stack Exchange nach Erklärungen gesucht, aber ohne Erfolg. Diese schienen meinem Problem (möglicherweise) ä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 (dieser schien auch ziemlich vielversprechend zu sein, tat es aber nicht in das "Warum" eintauchen Seltsame I2C-Signale, die von FPGA ausgesendet wurden (dies schien mit etwas anderem zusammenzuhängen ... obwohl ähnlich, dass ihre Wellen "hässlich" aussehen)

Danke für die Hilfe!

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. Schau mal in die RC-Zeiten.

Antworten (2)

I2C ist ein Bus, der Open-Drain-Ausgänge verwendet. Ein Open Drain ist wie ein Schalter, der zwischen Ausgang und Masse geschaltet ist. Ohne Pullup-Widerstände funktioniert es nicht, da es nichts gibt, was es hochgehen lässt.

Wenn die Pullup-Widerstände einen zu hohen Wert haben, funktioniert es 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 die Ausgabe nicht stark genug, um sie nach unten zu ziehen.

Sie bemerken, dass bei Ihrer Oszilloskopmessung die Ausgänge sehr schnell niedrig werden, aber nur träge auf den Logikpegel 1 steigen.

Wenn der Code auf Ihrem Arduino die internen Pullup-Widerstände auf dem ATMega verwendet, um eine I2C-Schnittstelle zu bit-bangen, dann sind sie wahrscheinlich zu hoch im Wert (zig kOhm und nicht gut spezifiziert), um zuverlässig zu funktionieren, also müssen sie es mit externen Widerständen parallel geschaltet werden.

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 sich bewusst für die Verwendung der internen zu entscheiden. Es ist möglich, dass sie akzeptabel sind, wenn die Chips sehr nahe beieinander liegen, eine niedrige Geschwindigkeit (100K) verwendet wird und keine Oszilloskopsonden (insbesondere in x1) angeschlossen sind.

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

Danke Spehro, das ist sehr hilfreich. Ich bin mir nicht sicher, ob die "Wire" -Bibliothek auf dem Arduino standardmäßig die internen Pullup-Widerstände verwendet, aber ich mache in meinem Code nichts explizites, um sie zu verwenden. Ich stimme zu, dass ich diese Widerstände lieber absichtlich wählen lassen würde, als mich im Code darauf zu verlassen. Könnte helfen, solche Situationen zu vermeiden. Tut mir leid, eine kurze Folgefrage: Warum sollte das Vorhandensein von Scope-Sonden (insbesondere in x1) das beeinflussen?
Oszilloskopsonden im x1-Modus fügen der Kapazität vielleicht 30-40 pF hinzu, was aufgrund der anderen Faktoren mehr als das Doppelte dessen sein kann, was bereits vorhanden ist. In x10 beträgt die zusätzliche Last eher 1/10 davon.

I2C soll überhaupt nicht ohne Pull-up-Widerstände funktionieren; sie werden bei der Auslegung des Busses explizit gefordert.

Ihre Frage ist also strittig - machen Sie es falsch, und es passieren schlimme Dinge.

Wenn Sie wirklich genau verstehen wollen, was passiert, ist es wahrscheinlich, dass Sie einen schwachen Pullup-Effekt von einem Leckstrom oder möglicherweise sogar einem internen Pullup-Widerstand bekommen, der etwa 10-mal größer ist als der I2C-Buswiderstand sein sollte. Dies verursacht diese exponentiell ansteigende RC-Wellenform - die klassische eines Kondensators, der über einen Widerstand aufgeladen wird. Mit einem Pullup-Widerstand mit dem richtigen Wert passiert es immer noch, aber schnell genug, dass die Exponentialfunktion auf dem Oszilloskop vertikal aussieht.

Unabhängig davon, welche Stromquelle die Leitung in Abwesenheit eines echten Pull-up-Widerstands hochbringt, ist sie schwach (dh die Schaltung ist sehr hochohmig), sodass sie auch extrem anfällig für kapazitive Kopplung von der Taktleitung ist, daher sehen Sie Die Spitzen der Wellenform der Datenleitung zeigen Artefakte, wenn der Takt umschaltet.

Verwenden Sie die erforderlichen Pull-up-Widerstände. Legen Sie einen Bypass-Kondensator für die Versorgung über Ihren Chip. Halten Sie die Kabelwege so kurz wie möglich. Befolgen Sie die Regeln, und Sie vermeiden die Probleme, die typischerweise durch das Brechen dieser Regeln entstehen.

Danke, Chris. Ich nehme an, dies ist eine Gefahr, blind einem Online-Tutorial zu folgen, in dem keine Pull-up-Widerstände verwendet werden. Vielen Dank für die Erklärung (und ja, ich wollte wissen, was der eigentliche Grund für das war, was passiert ist).
@Thomas - leider ist die Welt der Online-Arduino-Tutorials ebenso eine Sammlung dessen, was man nicht tun sollte, wie man sollte - einschließlich einiger der offiziellen von Arduino. Das soll nicht heißen, dass sie nicht nützlich sein können, aber Sie müssen oft drei oder vier schlechte durchwaten und ablehnen, um etwas zu finden, das tatsächlich funktioniert und den Chip, von dem man hoffte, dass das Herausziehen eines Arduino helfen könnte, sinnvoll ausnutzt, um ihn schnell zu bewerten.