I2C-Kommunikation mit dem PIC: Anschluss von Sensoren und EEPROMs

I2C-Kommunikation mit dem PIC: Anschluss von Sensoren und EEPROMs ist eine der praktischsten Fähigkeiten in der Mikrocontroller-Welt, weil I2C (auch I²C geschrieben) den Anschluss vieler Bausteine mit nur zwei Leitungen ermöglicht. Ob Temperatursensor, Beschleunigungssensor, Luftdrucksensor, RTC (Real-Time-Clock) oder externes EEPROM: Mit SDA (Daten) und SCL (Takt) lässt sich eine große Zahl von Geräten an einem gemeinsamen Bus betreiben. Für PIC-Projekte ist das besonders attraktiv, weil Pins knapp sind und I2C als standardisiertes Protokoll gut dokumentiert ist. Gleichzeitig ist I2C berüchtigt für „funktioniert manchmal“-Fehler: falsche Pull-up-Widerstände, ungeeignete Kabellängen, Adresskonflikte, Timingprobleme, Clock Stretching oder ein Bus, der nach einem Reset hängen bleibt. Dieser Artikel zeigt Ihnen, wie Sie I2C am PIC elektrisch korrekt anschließen, wie die Kommunikation auf Protokollebene funktioniert und wie Sie typische Sensoren und EEPROMs zuverlässig ansprechen. Sie erhalten praxistaugliche Strategien für stabile Übertragung, Debugging und saubere Softwarearchitektur – ohne unnötigen Ballast und so strukturiert, dass Sie das Wissen direkt in eigenen Projekten einsetzen können.

I2C in einem Satz: Was passiert auf dem Bus?

I2C ist ein synchrones, serielles Bussystem mit zwei Leitungen: SCL (Clock) und SDA (Data). Ein Master erzeugt den Takt und startet Transaktionen. Slaves besitzen Adressen und antworten, wenn sie angesprochen werden. Die Datenübertragung erfolgt in Bytes, jedes Byte wird durch ein ACK/NACK-Bit bestätigt. Der Bus ist „wired-AND“ (Open-Drain/Open-Collector): Geräte ziehen Leitungen nur nach Low; High entsteht über Pull-up-Widerstände.

  • Startbedingung (START): SDA fällt von High auf Low, während SCL High ist.
  • Adresse + R/W: 7-Bit-Adresse (oder 10 Bit) plus Read/Write-Bit.
  • ACK/NACK: Empfänger bestätigt jedes Byte.
  • Stopbedingung (STOP): SDA steigt von Low auf High, während SCL High ist.

Elektrischer Anschluss: Pull-ups sind nicht optional

Der wichtigste Hardwarepunkt bei I2C ist: SDA und SCL benötigen Pull-up-Widerstände. Ohne Pull-ups kann die Leitung nicht zuverlässig auf High gehen, weil die Teilnehmer die Leitung nur aktiv nach Low ziehen. Viele Einsteigerfehler entstehen genau hier. Einige Module bringen Pull-ups bereits mit – dann kann es beim Zusammenschalten mehrerer Module zu „zu starken“ Pull-ups kommen (zu niedriger Gesamtwiderstand), was wiederum Stromverbrauch und Signalform beeinflusst.

  • Pull-ups an SDA und SCL: typischerweise im kΩ-Bereich, abhängig von Buskapazität und Geschwindigkeit.
  • Open-Drain-Logik: Keine Push-Pull-Ausgänge auf SDA/SCL erzwingen.
  • Spannungspegel: PIC und Slaves müssen dieselben Pegel unterstützen (3,3 V vs. 5 V).
  • Level-Shifting: Wenn Pegel nicht kompatibel sind, ist ein Pegelwandler notwendig.

Pull-up-Wahl: Zusammenhang zwischen Widerstand, Kapazität und Anstiegszeit

Die Signalqualität hängt stark von der Anstiegszeit ab. Ein vereinfachtes Modell nutzt die RC-Zeitkonstante aus Pull-up-Widerstand R und Buskapazität C:

τ = R C

Je größer R oder C, desto langsamer steigt das Signal. Bei längeren Leitungen, vielen Devices oder Steckboards steigt die Kapazität, wodurch Sie oft kleinere Pull-ups (also stärkere Pull-ups) brauchen – jedoch auf Kosten höherer Ruhestromaufnahme, weil Low-Pegel dann mehr Strom „versenken“ muss.

I2C-Geschwindigkeiten: Standard Mode, Fast Mode und die Praxis

In der Theorie gibt es definierte I2C-Modi (z. B. 100 kHz, 400 kHz). In der Praxis bestimmen Layout, Leitungslänge, Pull-ups und Gerätefähigkeit, ob eine Geschwindigkeit zuverlässig funktioniert. Für Prototypen auf Breadboards ist 100 kHz oft deutlich stabiler als 400 kHz.

  • 100 kHz: robust, ideal für lange Leitungen, Prototypen, viele Slaves.
  • 400 kHz: schneller, erfordert meist bessere Pull-ups und saubere Signalführung.
  • Noch schneller: nur sinnvoll, wenn PIC und Slaves es explizit unterstützen und die Hardware sauber ausgelegt ist.

Der PIC als I2C-Master: Typische Registerlogik und Ablauf

Viele PICs besitzen ein Hardwaremodul für I2C (häufig im Rahmen von MSSP oder ähnlichen Peripherien). Das entlastet die CPU und macht Timing stabiler als Bit-Banging. Auch wenn Registerbezeichnungen je nach Familie variieren, ist der logische Ablauf als Master meist ähnlich:

  • Bus initialisieren: Takt einstellen, Pins konfigurieren, Modul aktivieren.
  • START senden: Bus übernehmen und Transaktion beginnen.
  • Adresse senden: 7-Bit-Adresse + R/W-Bit.
  • ACK prüfen: Nur bei ACK fortfahren, sonst Fehlerbehandlung.
  • Daten senden/empfangen: Byteweise, jeweils mit ACK/NACK.
  • STOP senden: Bus freigeben.

Für gerätespezifische Details sind Datenblatt und Reference Manual entscheidend. Eine zentrale Anlaufstelle ist die Microchip Dokumentensuche. Für die Toolchain sind MPLAB X IDE und MPLAB XC8 relevant.

Sensoren am I2C-Bus: Register lesen und schreiben

Die meisten I2C-Sensoren arbeiten registerbasiert. Das bedeutet: Sie schreiben zuerst die Registeradresse (Pointer), danach lesen oder schreiben Sie Daten. Ein typisches Muster für „Register lesen“ sieht so aus:

  • START
  • Slave-Adresse + Write
  • Registeradresse senden (z. B. 0x01)
  • Repeated START (ohne STOP)
  • Slave-Adresse + Read
  • Datenbytes lesen, ACK für alle bis auf das letzte
  • NACK beim letzten Byte
  • STOP

Repeated START: Warum es wichtig ist

Viele Geräte erwarten, dass der Registerpointer gesetzt wird und anschließend ohne Busfreigabe direkt gelesen wird. Ein STOP dazwischen kann dazu führen, dass der Sensor intern in einen anderen Zustand wechselt oder dass ein anderer Master (in Multi-Master-Systemen) dazwischenfunkt. In den meisten PIC-Projekten ist Repeated START daher das Standardmuster für Registerzugriffe.

EEPROMs am I2C-Bus: Besonderheiten bei Speicherzugriffen

Externe I2C-EEPROMs sind extrem verbreitet, weil sie nichtflüchtige Speicherung ermöglichen, ohne die Firmware neu zu flashen. Im Gegensatz zu Sensoren gibt es hier typische Stolpersteine: Seitenweise Schreiben (Page Writes), Write-Cycle-Zeiten und Adressierung, die je nach EEPROM-Größe in 1 oder 2 Adressbytes erfolgt.

  • Byte Read/Write: einzelne Bytes sind möglich, aber nicht immer effizient.
  • Page Write: mehrere Bytes in einem Rutsch, aber nur bis zur Page-Grenze.
  • Write-Cycle Time: nach einem Schreibvorgang ist das EEPROM kurz beschäftigt.
  • ACK-Polling: Master fragt per Adresse an, bis das EEPROM wieder ACK gibt.

Page-Grenzen: Warum Daten sonst „umklappen“

Viele EEPROMs schreiben intern in Seiten. Wenn Sie über das Seitenende hinaus schreiben, wrappt das EEPROM oft zurück zum Seitenanfang. Das Ergebnis sind scheinbar „korrupt“ geschriebene Daten. Deshalb müssen Sie Page Writes so splitten, dass sie niemals eine Page-Grenze überschreiten.

Adressierung verstehen: 7-Bit-Adresse, R/W-Bit und Konflikte

Ein häufiger Fehler ist die Verwechslung von 7-Bit- und 8-Bit-Adressen. Viele Datenblätter nennen eine „I2C-Adresse“, die bereits das R/W-Bit enthält oder als 8-Bit-Wert dargestellt ist. In der I2C-Logik ist die Grundadresse jedoch 7 Bit, und das R/W-Bit kommt separat dazu.

  • 7-Bit-Adresse: eigentliche Slave-Adresse.
  • 8-Bit-Adressbyte: (7-Bit-Adresse << 1) + R/W.
  • Adresspins: Viele EEPROMs haben A0/A1/A2 zur Adresswahl.
  • Konflikte: Zwei Geräte mit gleicher Adresse verursachen Buskollisionen (beide antworten).

Clock Stretching: Wenn der Slave den Takt „anhält“

Manche I2C-Slaves halten SCL kurz auf Low, um intern Zeit zu gewinnen (Clock Stretching). Das ist standardkonform, aber nicht jeder Master oder jede Softwarekonfiguration behandelt es sauber. Wenn Sie Sensoren einsetzen, die Clock Stretching nutzen, müssen Sie sicherstellen, dass Ihr PIC-I2C-Modul und Ihre Treiberlogik damit umgehen.

  • Typische Fälle: Sensoren mit interner Messzeit oder aufwendiger Datenbereitstellung.
  • Symptom: Bus wirkt „langsam“ oder bleibt scheinbar hängen.
  • Lösung: Treiber/Hardwaremodus so konfigurieren, dass Stretching toleriert wird.

Bus hängt: Recovery-Strategien, die in der Praxis funktionieren

Ein I2C-Bus kann hängen bleiben, wenn ein Slave SDA dauerhaft Low hält (z. B. nach einem abgebrochenen Transfer oder Reset zur falschen Zeit). Das ist in realen Systemen nicht selten. Ein robustes Design enthält daher eine Recovery-Strategie.

  • Bus-Reset per SCL-Toggles: Mehrere Clock-Pulse erzeugen, damit ein Slave seine State Machine freigibt.
  • STOP erzwingen: Wenn möglich, eine definierte Stopbedingung erzeugen.
  • Peripherie neu initialisieren: I2C-Modul am PIC kurz deaktivieren/aktivieren.
  • Power-Cycle einzelner Slaves: Wenn Hardware es erlaubt (Lastschalter/Transistor).

Softwarearchitektur: Treiber, Abstraktion und Fehlerbehandlung

Damit I2C-Projekte wartbar bleiben, lohnt sich eine klare Trennung: ein I2C-Basistreiber (Start/Stop/Read/Write), darüber Geräteschicht (Sensor/EEPROM), darüber die Anwendung. So können Sie Fehler sauber propagieren und Debugging vereinfachen.

  • Basistreiber: sendet Start/Stop, liest/schreibt Bytes, prüft ACK.
  • Device-Treiber: kennt Registermap, Datenformate, Initialisierung.
  • Application: nutzt „getTemperature()“, „readEEPROMBlock()“ statt Registerdetails.
  • Fehlercodes: z. B. NACK, Timeout, Bus Busy, CRC-Fehler (bei Datenprotokollen).

I2C mit Interrupts oder Polling: Was ist sinnvoll?

Viele PIC-Anwendungen nutzen I2C per Polling, weil Transfers kurz sind und die Komplexität gering bleibt. Interruptbetrieb kann sinnvoll sein, wenn Sie lange Transfers haben oder die CPU währenddessen andere Aufgaben erledigen soll. Für Einsteiger ist Polling meist der bessere Startpunkt – sofern Sie Timeouts implementieren, damit Ihr System nicht hängen bleibt.

  • Polling: einfach, gut nachvollziehbar, ideal für Sensorabfragen im festen Zeitraster.
  • Interrupt/DMA (falls vorhanden): effizienter, aber komplexer in Zustandsmaschine und Fehlerhandling.
  • Timeouts: Pflicht, egal ob Polling oder Interrupt.

Praxis-Fehlerbilder und schnelle Ursachenanalyse

Wenn I2C nicht stabil läuft, liegt die Ursache häufig an wenigen, wiederkehrenden Punkten. Eine strukturierte Checkliste spart Zeit.

  • Keine Antwort (NACK): falsche Adresse, falsche 7/8-Bit-Interpretation, Gerät nicht versorgt, Pegelproblem.
  • Zufällige Fehler: Pull-ups ungeeignet, Breadboard-Kapazität, Leitungslänge, Störungen durch PWM.
  • Bus hängt (SDA Low): abgebrochener Transfer, fehlende Recovery, Reset-Sequenzen ungünstig.
  • Falsche Daten: Registerpointer falsch, Endianness verwechselt, Mehrbyte-Register falsch gelesen.
  • EEPROM-Schreiben fehlschlägt: Write-Cycle nicht abgewartet, Page-Grenze überschritten.

Konfiguration beschleunigen: MCC nutzen, aber Busparameter bewusst setzen

Mit dem MPLAB Code Configurator (MCC) lässt sich I2C häufig schnell konfigurieren. Dennoch sollten Sie die generierten Parameter prüfen: Busfrequenz, Pinbelegung, Interruptoptionen und – falls vorhanden – Einstellungen zur Bus-Idle-Erkennung und Clock Stretching. MCC ist eine Abkürzung, ersetzt aber nicht die Validierung an der Hardware.

Weiterführende Ressourcen: Tools und Dokumentation

IoT-PCB-Design, Mikrocontroller-Programmierung & Firmware-Entwicklung

PCB Design • Arduino • Embedded Systems • Firmware

Ich biete professionelle Entwicklung von IoT-Hardware, einschließlich PCB-Design, Arduino- und Mikrocontroller-Programmierung sowie Firmware-Entwicklung. Die Lösungen werden zuverlässig, effizient und anwendungsorientiert umgesetzt – von der Konzeptphase bis zum funktionsfähigen Prototyp.

Diese Dienstleistung richtet sich an Unternehmen, Start-ups, Entwickler und Produktteams, die maßgeschneiderte Embedded- und IoT-Lösungen benötigen. Finden Sie mich auf Fiverr.

Leistungsumfang:

  • IoT-PCB-Design & Schaltplanerstellung

  • Leiterplattenlayout (mehrlagig, produktionstauglich)

  • Arduino- & Mikrocontroller-Programmierung (z. B. ESP32, STM32, ATmega)

  • Firmware-Entwicklung für Embedded Systems

  • Sensor- & Aktor-Integration

  • Kommunikation: Wi-Fi, Bluetooth, MQTT, I²C, SPI, UART

  • Optimierung für Leistung, Stabilität & Energieeffizienz

Lieferumfang:

  • Schaltpläne & PCB-Layouts

  • Gerber- & Produktionsdaten

  • Quellcode & Firmware

  • Dokumentation & Support zur Integration

Arbeitsweise:Strukturiert • Zuverlässig • Hardware-nah • Produktorientiert

CTA:
Planen Sie ein IoT- oder Embedded-System-Projekt?
Kontaktieren Sie mich gerne für eine technische Abstimmung oder ein unverbindliches Angebot. Finden Sie mich auf Fiverr.

 

Related Articles