Wie wird die Taktfrequenz zwischen Master und Slave im I2C-Protokoll festgelegt?

8

Dies ist eine Folgefrage zu Was passiert, wenn ich die Pullup-Widerstände auf I2C-Leitungen weglasse?

Bei einer von mir entworfenen digitalen Wanduhr (unter Verwendung der DS1307 RTC und der ATmega328 MCU) habe ich versehentlich die Pull-up-Widerstände weggelassen, die an beide I2C-Leitungen angeschlossen werden müssen. Am Ende hatte ich das Glück, dass die internen Klimmzüge auf den ATmega I2C-Leitungen ausreichten, um die Kommunikation zwischen den Geräten (kaum) zu ermöglichen. Das Ergebnis waren lange Anstiegszeiten auf den I2C-Leitungenund Geschwindigkeitsreduzierung auf 32 kHz wie in den Scope-Aufnahmen unten zu sehen.

Bearbeiten: Tatsächlich beträgt die Frequenz genau 100 kHz - es gibt 2 Spitzen pro 20 us auf der grünen Spur. Anfangs dachte ich, es gäbe eine Reduzierung auf 32 kHz, weil mein Oszilloskop die Frequenz auf der gelben Spur berechnete.

Scope Shot 1 Scope Shot 2

Was mich jetzt verwundert, ist, wie die Geräte entschieden haben, dass 32 kHz für die Kommunikation ausreichen. Das Datenblatt DS1307 besagt, dass das Gerät eine Frequenz von 100 kHz auf dem I2C-Bus unterstützt. Wie kommt es, dass stattdessen 32 kHz verwendet wurden? Gibt es eine Art Handshake-Phase, in der die Frequenz eingestellt wird?

Am Ende lautet meine Frage wirklich: Wie wird die Taktfrequenz zwischen Master und Slave im I2C-Protokoll festgelegt?

Ich konnte diese Informationen im Internet nicht finden.

In diesem Fall verwende ich Arduino IDE 1.03 und meine Firmware verwaltet die RTC mithilfe der DS1307RTC Arduino lib (über ihre Funktionen RTC.read()und RTC.write()). Diese Bibliothek verwendet wiederum, Wire.hum mit der RTC zu sprechen.

Ricardo
quelle
4
Der Standard für I2C ist hier
Warren Hill
1
Könnte dies nicht sein, dass Sie diese Frequenz willkürlich hart codieren, ohne es zu wissen?
Dzarda
@ Warren Diese Referenz ist wirklich hilfreich, danke. Ich konnte Google nicht dazu bringen, mich zu THE SPEC zu bringen. Stattdessen ging ich zu Wikipedia-Artikeln und anderen tangenzialen Dokumenten. Trotzdem konnte ich nicht verstehen, wie die Geschwindigkeit bestimmt wird. Ich denke, was ich wissen möchte, ist in Abschnitt 3.1.7 Uhrensynchronisation , aber ich würde mich sehr freuen , wenn mir jemand dies einfacher erklären könnte, da es immer noch etwas über meinem Kopf liegt.
Ricardo
1
In Ihrem System ist der DS1307 ein Slave und seine SCL-Leitung ist nur ein Eingang. Die Frequenz wird vom Master der MCU eingestellt. Wer auch immer die Firmware dafür geschrieben hat, hat entschieden, welche Geschwindigkeit sie wollen. Es gibt keine Verhandlung, die fest codiert ist.
Warren Hill
1
Richtig, die meisten Systeme haben nur einen Master. Die Taktsynchronisierung ist nur in einer Multi-Master-Umgebung sinnvoll
Warren Hill,

Antworten:

4

Folgen Sie den Kommentaren:

Ja, die Frequenz ist in bestimmten I2C-Registern fest codiert. Zur Laufzeit.

Das heißt, Ihre Arduino-Bibliothek führt möglicherweise eine Sondierungs- und Anstiegszeitmessung auf dem Bus durch, um eine brauchbare Taktrate zu bestimmen. Wir werden sehen.


Nachdem Sie ein bisschen nach Quellen gesucht haben, ist die Antwort in zwei Stunden

#ifndef TWI_FREQ
#define TWI_FREQ 100000L
#endif

Ein weiteres Stück aus dieser Datei:

TWBR = ((CPU_FREQ / TWI_FREQ) - 16) / 2;

Wo TWBR für Two Wire Baudrate Register steht, vermute ich.

Ich würde das als genügend Beweise bezeichnen und definitiv sagen, ja, Ihre I2C-Frequenz wird ohne Verhandlungen direkt von Ihrer Bibliothek festgelegt. Wenn Sie es ändern möchten, würde ich vorschlagen, dass Sie TWI_FREQ definieren, bevor Sie twi.h einschließen (oder indirekt über Wire.h).

Dzarda
quelle
1
"Wenn Sie es ändern möchten, würde ich vorschlagen #undefund #defineweiter, TWI_FREQnachdem Sie Wire.h hinzugefügt haben." Nein, das ist falsch. Der Weg twi.hist geschrieben, du solltest #definedeinen Brauch TWI_FREQ vor dir haben #include twi.h. (Und was hat "Wire.h" mit irgendetwas zu tun?)
Dave Tweed
Tatsächlich war die Frequenz immer genau 100 kHz - es gibt 2 Spitzen pro 20 us auf der grünen Spur. Anfangs dachte ich, es gäbe eine Reduzierung auf 32 kHz, weil mein Oszilloskop die Frequenz auf der gelben Spur berechnete. Dies macht Ihre Antwort richtig. Vielen Dank!!
Ricardo
5

Damit in I2C eine ansteigende Taktflanke auftritt, muss der Master den Takt aktivieren, was dazu führen kann, dass einige Slaves ihn ebenfalls aktivieren, und dann müssen der Master und alle Slaves beim Freigeben des Takts übereinstimmen. Bis alle Geräte die Uhr freigeben, bleibt sie aktiviert und alle Geräte sehen, dass sie aktiviert ist.

Sobald jedes Gerät die Uhr freigegeben hat, "schaltet" jedes Slave-Gerät die Takthalteschaltung wieder auf, es sei denn oder bis es für die nächste ansteigende Flanke bereit ist [einige Geräte sind immer "bereit" für ansteigende Flanken, so schnell wie die Der Master kann sie senden und benötigt daher überhaupt keine Clock-Hold-Schaltung. andere wissen manchmal, dass sie nicht an steigenden Flanken interessiert sind, bis die nächste Startbedingung auftritt, und schalten ihre Takthalteschaltung bis dahin nicht wieder ein]. Wenn der Master sieht, dass die Uhr freigegeben ist, wartet er einige Zeit, um sicherzustellen, dass jeder, der eine Bushalteschaltung erneut aktivieren muss, die Möglichkeit dazu hat, und setzt dann die Uhr erneut fest und stellt sicher, dass dies der Fall ist lange genug gehalten, damit sich bewaffnete Bushaltestellen daran beteiligen können. Der Zyklus kann sich dann wiederholen.

Slave-Geräte haben im Allgemeinen keine minimale Betriebsgeschwindigkeit, aber eine maximale. Einige Geräte synchronisieren ihre gesamte I2C-Logik mit einem internen Takt und benötigen daher möglicherweise ein oder zwei Zyklen, um ihre Takthalteschaltung zu aktivieren oder auszulösen. Darüber hinaus verlangt I2C, dass Geräte zu 100% zuverlässig bestimmen müssen, ob Flanken auf der Taktleitung vor oder nach Kanten auf der Datenleitung auftreten. Da Datenleitungsänderungen häufig fast unmittelbar nach fallenden Taktflanken auftreten, können Geräte eine gewisse Verzögerung hinzufügen, wenn sie Datenleitungsänderungen wahrnehmen. Dies erfordert das Hinzufügen einer Verzögerung zwischen jeder Änderung der Datenausgabe durch den Master und der Erhöhung der Uhrzeit. Sofern für jedes Gerät die Mindestverzögerungsanforderung erfüllt ist, kann der Master so lange verzögern, wie er möchte. Je länger der Master jedoch verzögert, desto länger dauert das Senden von Daten.

Superkatze
quelle
3

Von der Arduino-Website - Wire Library Detaillierte Referenz :

Der Aufruf von twi.init () ist intern in der Wire-Bibliothek. Es führt die folgenden Aufgaben aus: Legt die Taktfrequenz fest, die die TWI-Hardware verwendet, wenn sie der Master auf dem I2C-Bus ist. Es ist im Quellcode auf 100 kHz eingestellt, aber theoretisch können Sie diese Frequenz zumindest zurücksetzen, indem Sie TWBR vor dem Aufruf von Wire.begin () neu definieren. Beispiel: TWBR = 400000L sollte sie auf 400 kHz einstellen.

Die von Ihnen verwendete RTC-Bibliothek ändert TWBR nicht. Etwas anderes, das Sie verwenden, hat es möglicherweise geändert. Oder die lange langsame Pull-up-Zeit der superschwachen internen Pull-ups hat den i2c-Motor des ATMega effektiv verlangsamt. Der Motor prüft vor dem Wechseln, ob die Leitung hoch oder niedrig ist.

Die i2c-Taktfrequenz ist jedoch beliebig , bis zur niedrigsten maximal unterstützten Frequenz eines Geräts am Bus (und möglicherweise einige zehn Hz mehr). Schneller und Sie bekommen Probleme beim Lesen und Schreiben. Einige Geräte haben Mindestfrequenzen, bevor sie eine Zeitüberschreitung aufweisen, aber ich habe gesehen, dass 400-kHz-Geräte mit 10 kHz arbeiten. Die Taktrate wird ausschließlich vom Master (dh von Ihnen, dem Codierer) festgelegt.

Es gibt eine Option zum Dehnen der Uhr seitens des Slaves (sie hält die Taktleitung niedrig, bis sie bereit ist, und die i2c-Spezifikation erfordert, dass der Master dies überprüft), aber die Scope-Bilder scheinen nicht darauf hinzudeuten, dass dies hier geschieht .

Wenn Sie einige geeignete externe Pullups hinzufügen, ohne Code zu ändern, sollte die Frequenz näher an 100 kHz ansteigen, wie in der Drahtbibliothek als Standard definiert

Passant
quelle