Hi...
Hier gibts öfter mal Diskussion um die Pullups beim I2C. Von einigen wird die Notwendigkeit angezweifelt, andere haben Probleme bei der Bemessung. Der leider falsche Schluss aus solchen Problemen: I2C ist Mist.
Hier ein Foto von meinem Testaufbau.
Und im Anhang 2 PDF Dateien.
Einmal der komplette Aufbau, also mit FRAM, EEPROM und RTC, und einmal der gleiche Aufbau, nur RTC gezogen.
Wie man sieht, wenn man die Beiden vergleicht, sind die Pegel bei gesteckter RTC viel höher und auch deutlich rechteckiger.
Der logische Schluss:
- Die RTC hat Pullups auf dem Board
- Die internen Pullups des UNO sind zu groß um ordentliche Signale zu bekommen.
- Ohne extra Pullups ist die Sache ein reines Glücksspiel.
Ein Logikanalysator zeigt das nicht, in dieser Form.
Der ist also bei der Analyse der Flanken wenig hilfreich.
Im Gegenteil. Er verbirgt das Problem, da er einen Schmitt Trigger Eingang hat, und so saubere Rechtecke zeigt.
Für eine Analyse der übertragenen Daten ist er dagegen sehr hilfreich.
Tipps zur Fehlersuche:
-> Nutze den I2C Scanner!
Wenn ein I2C Modul nicht vom Scanner gefunden wird, dann hat man ein Problem, welches behoben werden will, bevor man im Programm rum doktert.
Genauso, wenn der Scanner Mist zeigt.
-> Prüfe auf Erfolg!
Werte das Ergebnis von Wire.endTransmission() oder/und Wire.requestFrom() aus.
-> Vermeide Race Conditions!
Race Conditions treten in Multitasking und Multimaster Umgebungen auf.
Sie sind recht schwer zu finden.
Im Multitasking System muss der Ausschluss per Semaphor erfolgen.
Um diese Race Conditions in Multimaster Umgebungen zu vermeiden haben einige Methoden den stop Parameter.
- Wire.endTransmission(stop)
- Wire.requestFrom(address, quantity, stop)
Setzt man diesen auf false, dann kann sich kein anderer Master zwischen zwei Zugriffe, auf ein und denselben Baustein, drängeln. Der Bus bleibt belegt.
-> Beachte die Regeln für ISRs (z.B. auf den AVR Arduinos)
onReceive() und onRequest() werden von einer Interrupt Service Routine aufgerufen. Achte darauf, dass alle davon veränderten Daten das volatile Attribut bekommen und von der Hauptanwendung atomar gelesen werden.
Links:
Wikipedia zu I2C
I2C Spezifikation
I2C Bus Pullup Resistor Calculation
I2C Level Shifter
I2C Multiplexer TCA9548A
LTC4311 aktiver Pullup
Arduino Wire
Race Conditions
Atomically Executed Code Blocks
eeprom_fram_rtc.pdf (117 KB)
eeprom_fram.pdf (119 KB)