I²C Bus Einführung
Der von der Firma Philips für Consumer Anwendungen entwickelte Inter-IC Bus oder I²C Bus wurde ursprünglich in den 80er Jahren als unkomplizierter, serieller Kommunikations-Bus zwischen verschiedenen integrierten Bausteinen konzipiert. Die erste allgemeine Spezifikation (Revision 1.0) aus dem Jahre 1992 fasste die bis dahin als Firmenspezifikation festgelegten Busmerkmale zusammen und erweiterte die Funktionalität im Wesentlichen um den “Fast Mode” (400 kBit/s) und die Möglichkeit 10 Bit Adressen zu verwenden. In der Version 2.0 dieser Spezifikation wurde der “High Speed Mode” (bis 3.4 Mbit/s) eingeführt. Als letze Erweiterung wurde der „Ultra-Fast Mode“ mit einer Datenübertragungsrate von 5 Mbit/s eingeführt, der aber nur im unidirektionalen Verfahren eingesetzt werden kann. Zum aktuellen Zeitpunkt gilt die Spezifikation Version 6.0 aus dem Jahre 2014 die bei NXP (ehemals Philips Semiconductor) zu erhalten ist.
Der I²C Bus ist ein bidirektionaler Bus mit Master/Slave Funktionalität, der jedoch auch Multi-Master Fähigkeiten besitzt. D.h. im Wesentlichen, jeder Teilnehmer am Bus kann als Master agieren, sollten mehrere “Master” gleichzeitig aktiv werden, wird eine auftretende Kollision beim Bus-Zugriff erkannt und wird dann durch entsprechende Mechanismen aufgelöst.
Der Bus selbst besteht aus nur zwei Signalen (bzw. Signalleitungen) die für die Übertragung des Bustaktes (SCL = Serial Clock) und für die Übertragung der Daten ( SDA = Serial Data) verwendet werden. Beide Signalleitungen sind über jeweils einen “Pull-Up” Widerstand mit der System-Versorgungsspannung (Vcc) verbunden. Die Größe der “Pull-Up” Widerstände bewegt sich, laut Spezifikation in Abhängigkeit der Vorsorgungs-spannung, in einem Bereich von 500 Ohm bis ca. 5,6 kOhm. Die Bussignale sind einfache unsymmetrische Signale mit gemeinsamer Masse als Referenzpunkt. Die maximale kapazitive Last pro Signalleitung beträgt nach Spezifikation 400 pF.

Die an die Busleitungen angeschlossenen Bausteine besitzen jeweils einen “ SCL”- und einen “SDA”-Pin welche sowohl Signal-Ausgang als auch Signal-Eingang sein können. Die Ausgangsstufe für die beiden Signale darf den Ausgang nur gegen Masse (VSS) schalten und keinesfalls gegen VDD („Open Drain“ oder „Open Collector“ Konfiguration) um Kurzschlüsse auf dem Bus zu vermeiden.
Die Eingänge der einzelnen Bausteine sind permanent mit dem Bus verbunden um eine auftretende " Start" Kondition oder eine ankommende Adresse erkennen zu können. Der maximale erlaubte Eingangsstrom pro Signal-Eingang beträgt +/- 10 uA. Dieser Eingangsstrom legt zusammen mit dem Wert des “Pull-Up” Widerstands die maximal mögliche Anzahl von Bausteinen fest, die mit dem Bus verbunden werden können.
n x Ie x Rp < VDD – Voh – Vnm
n = Anzahl der mit dem Bus verbundenen Bausteinen
Ie = maximaler Eingangsstrom pro Bausteine
Rp = Wert des Pull-Up Widerstands
VDD = Versorgungsspannung (für den Pull-Up Widerstand)
Voh = minimaler Eingangspegel für “High”-Level
Vnm = Noise Margin (Sicherheitsabstand min. Ausgangs/max.
Eingangspegel)
setzt man in oben aufgeführte Formel entsprechende Werte aus der Spezifikation ein, ergibt sich:
n x 10uA x Rp < VDD – 0,7xVDD – 0,2xVDD
oder
n x 10uA x Rp < 0.1xVDD
Der Eingangspegel für einen “Low”-Level ist dabei mit kleiner 0.3 x VDD und für einen “High”-Level mit grösser 0.7 x VDD spezifiziert. Die Hysteresis des Eingangs beträgt üblicherweise 0.1 x VDD (bei Versorgungsspannungen (VDD) unter 2 Volt lediglich 0.05 x VDD).
Die Ausgangsstufen müssen einen “Low”-Pegel von kleiner 0.4 Volt bzw. bei Bausteinen mit weniger als 2 Volt Versorgungsspannung, von 0.2 x VDD ermöglichen. Der “High”-Pegel auf dem Bus wird durch den jeweiligen “Pull-Up” Widerstand und die Eingangs- plus Sperr-Ströme der angeschlossenen Bausteine bestimmt.
Grundsätzlich können in einem Bussystem Bausteine mit verschiedenen Versorgungsspannungen verwendet werden, solange diese Bausteine mit den Signalpegeln an deren Ein-/Ausgängen kompatibel sind. Die Spezifikation sieht auch serielle Schutzwiderstände an den Ein-/Ausgängen der angeschlossenen Bausteine vor, die bei der Berechnung mit berücksichtigt werden müssen.
Jedes Bit innerhalb eines zu übertragenden Bytes wird durch einen “SCL”-Puls übermittelt. Dabei sind die Daten auf dem Bus stabil wenn die Takt-Leitung einen “High”-Pegel einnimmt und die Daten können sich ändern wenn die Taktleitung auf “Low”-Pegel ist.

Ist der “SLAVE” Baustein momentan nicht bereit weitere Daten zu übernehmen so kann von diesem Baustein die Taktleitung solange auf “Low” gehalten werden bis weitere Daten akzeptiert werden können. Der jeweilige Bus-”MASTER” liest den Pegel auf beiden Signalleitungen mit, erkennt den unterdrückten Takt und sendet keine weiteren Daten bis die Taktleitung wieder freigegeben wird.
Um den Start bzw. das Ende eines zu übertragenden Rahmens oder einer Übertragung im Generellen zu indizieren wird die oben aufgeführte Konvention der erlaubten Pegeländerungen auf der Signal- und auf der Datenleitung durchbrochen.

Wie beschrieben dürfte sich der Signalpegel auf der Datenleitung nur dann ändern wenn die Taktleitung auf “Low”-Pegel liegt. Tritt hingegen ein Pegel-übergang von “High” auf “Low” auf der Datenleitung auf während der Pegel auf der „Clock“-Leitung “High” ist, so wird damit eine “START” Kondition signalisiert. Entsprechend gilt dies bei einem “Low” auf “High” Übergang der Datenleitung und gleichzeitigem “High” Pegel der Taktleitung, als “STOP” Kondition.
Bussysteme mit "Multi-Master" Fähigkeit erfordern einen Mechanismus der gleichzeitige Zugriffe mehrerer Master auf den Bus erkennt und eine Möglichkeit findet einem einzelnen Master den Bus zu zuweisen. Da der I²C-Bus oder besser die seriellen Busleitungen eine "wired-AND" Konfiguration darstellen, wird der Bus-Pegel "Low" von dem Baustein (Bus-Teilnehmer) bestimmt, der eine "0" schreibt. Kein Baustein kann den Pegel auf "High" hochziehen. Darauf beruht der "Schlichtungs"-Mechanismus (Arbitration) des I²C-Busses.
Dies gilt sowohl für die Clock- als auch für die Datenleitung, wobei die beiden Aktionen sich dennoch von der logischen Funktion her unterscheiden.
Der Bus-Master liefert den Takt für die Datenübertragung auf dem Bus, dies kennzeichnet einen Master. Sind mehrere Master mit dem Bus verbunden und sind diese nicht vom Takt her synchronisiert oder haben einen gemeinsamen Takt würde es eine Überlagerung der Signale auf der "SCL" Leitung geben und eine saubere Übertragung wäre nicht möglich. Beim I²C-Bus ist ein gemeinsamer Takt (Clock) nicht implementiert und auch eine Synchronisation (z.B. in Form einer PLL) ist nicht vorgesehen.
Die Lösung liegt darin, dass jeder Bus-Master die "SCL" Leitung überwacht und sich auf die Änderungen des Takt-Pegels synchronisiert.
Der "High"-Pegel der Busleitung "SCL" wird über einen Pull-Up Widerstand erzeugt, der Master, der als erster die "SCL"-Leitung auf "Low" zieht bestimmt deshalb den Beginn der "Low"-Periode. Die anderen Master erkennen dass der Bus auf "Low" ist und setzen ihre internen Zähler auf diesen Zustand. Jetzt laufen alle Master mit ihren Zustandszählern synchron auf "Low"-Pegel. Der Master dessen "Low"-Zähler als Erster abläuft hat jedoch keinen Einfluss auf den Buspegel, weil der "langsamste" Master (im Sinne der "Low"-Clock-Periode) den Bus immer noch auf "Low" hält. Erst wenn alle Zähler in den verschiedenen Master-Bausteinen ihre "Low"-Periode beendet haben kann der Bus wieder auf "High" gehen ("wired-AND" >> Baustein1 AND Baustein2 AND .... ).
Wechselt der "SCL" Pegel auf "High" beginnen alle Master mit dem Zählen der "High"-Periode. Im Gegensatz zum vorhergehenden "Low"-Zyklus bestimmt aber jetzt der Master die Länge der "High"-Periode der als Erster seinen "SCL"-Ausgang auf "Low" schaltet, wobei wir wieder am Anfang der Takt-Synchronisierungs-Schleife wären.
Mit dieser Art der Takt-Synchronisierung ist es theoretisch möglich verschiedene Bausteine mit verschiedenen möglichen Übertragungsgeschwindigkeiten ("Standard Mode"," Fast Mode") zu kombinieren, wobei der langsamste Baustein die schnelleren Bausteine "überschreibt". Ist eine solche Kombination von verschiedenen "Bus-Geschwindigkeiten" notwendig, ist es empfehlenswert die "langsamen" Master nur bei Bedarf als Master arbeiten zu lassen.
Nachdem sich die einzelnen Master am Bus auf eine gemeinsamen Takt geeinigt haben steht einer Übertragung von Daten eigentlich nichts mehr im Wege aber welcher Master darf zu welcher Zeit Daten senden? Wir haben ja ein Bussystem.
Der "Arbitration"-Mechanismus auf dem I²C-Bus erlaubt jedem Master mit der Übertragung zu beginnen - solange der Bus frei ist, d.h. solange sowohl die "SCL" als auch die "SDA" Leitung auf "High"-Pegel liegt.
Die Übertragung beginnt wie bei der Rahmen-Synchronisation besprochen mit einer "START" Kondition während einer "High"-Periode von "SCL". Diese "START" Kondition kann von mehreren Teilnehmern gleichzeitig generiert werden. Nach dem Start beginnt die Übertragung des ersten Datenbytes (hier speziell der Adresse) mit dem ersten Bit. Jeder Master überwacht dabei die "SDA" Leitung um zu vergleichen ob die von ihm gesendeten Daten auch auf dem Bus ankommen.
Durch die "wired-AND" Struktur des Busses gewinnt immer der Master der statt eines "High" Pegels einen "Low" Pegel ausgibt.
Ein Master der einen "High"-Pegel ausgibt aber einen "Low"-Pegel auf der "SDA" Leitung liest, stoppt sofort jede weitere Datenausgabe auf die "SDA" Leitung und hat damit das Zugriffsrecht verloren.
Auf diese Weise wird Bit für Bit entschieden welcher Master das Zugriffsrecht behält und seine Übertragung beenden kann. Adressieren zwei Master denselben Baustein und wollen diesen lesen oder beschreiben, so wird erst bei der Übertragung der Daten selbst die Arbitrierung gelöst. Theoretisch könnten zwei Master synchron einen Slave adressieren und von dort die gleichen Daten lesen, ohne dass einer der Master abbrechen müsste, was aber sicher nicht häufig vorkommt.
Es gibt 4 verschiedene Basis-Protokolle für die Übertragung zwischen einem Master und einem Slave:
Dazu gibt es sogenannte "COMBINED" Protokolle die mehrfache Zugriffe innerhalb eines Protokolls erlauben (beispielsweise zum Lesen von seriellen Speicher-Bausteinen, erst eine Adresse zum Slave übertragen und danach Daten lesen).
Der I²C-Bus verwendet ein “Byte-orientiertes” Protokoll, d.h. es können über den Bus keine einzelnen Bits sondern nur Vielfache von Bytes übertragen werden. Theoretisch wäre zwar auch eine Übertragung von einzelnen Bits oder “Bit-orientierten” Protokollen möglich, aber per Definition in der Spezifikation muss jedes Byte acht Bit lang sein. Dies wird bei den implementierten Bausteinen auch entsprechend überwacht und bei Nicht-Einhaltung als Fehler signalisiert.
In der Bit-Übertragungs-Schicht wurde der Datenfluss auf Bit-Ebene besprochen, zusätzlich wurde ein weiterer Mechanismus zur Übertragung von seriellen Bytes implementiert.
Jedes zu übertragende Paket (nicht Byte) auf dem I²C Bus beginnt mit einer “START” Kondition und endet mit einer “STOP” Kondition. In den
verschiedenen Protokollen auf dem I²C Bus sind innerhalb dieses Rahmens weitere “START” Konditionen möglich um beispielsweise eine Umkehrung der
Datentransfer-Richtung zu erwirken. Eine “START” Kondition ist jedoch nur am Beginn eines Übertragungspakets nicht jedoch für jedes übertragene Byte
innerhalb eines Pakets notwendig.

Zusätzlich zu jedem übertragenem Byte wird ein “ACKNOWLEDGE” Bit übertragen, das vom jeweiligen Empfänger (kann Master oder Slave sein) den Empfang des gerade übertragenen Bytes quittiert. Dabei erzeugt der Master zu den 8 Takt-Impulsen einen zusätzlichen Takt und der zuletzt aktive Baustein der die Daten empfangen hat zieht die Datenleitung bei diesem "neunten" Takt auf “Low”. Dieses “ACKNOWLEDGE” Verfahren ist laut Spezifikation vorgeschrieben.
Werden sequenzielle Lesevorgänge durchgeführt und soll ein weiteres Auslesen von Daten unterbrochen werden sendet der "lesende" Baustein beim letzten Lesevorgang kein Acknowledge um den Abbruch der Übertragung anzuzeigen.
Die Übertragung eines Bytes auf der seriellen Bus-Leitung erfolgt übrigens immer mit dem “Most Significant Bit” (höchstwertigen Bit) zuerst.
Nach einer “START” Kondition wird als erstes Byte eine Adresse übertragen. Die Adresse besteht aus 7 Adressbits und einem Read/Write Bit (least signifikant bit), die von jedem Busteilnehmer gelesen und mit der für jeden Busteilnehmer eigenen Adresse verglichen wird. Die Adress-Bits werden von allen Busteilnehmern seriell in ein Register geschoben und dann parallel mit der jeweiligen, eingestellten Baustein-Adresse verglichen.

Besitzt ein Busteilnehmer die angesprochene Adresse, so wird er das “ACKNOWLEDGE” Bit am Ende des ersten übertragenen Bytes bedienen (senden), was dem Master eine Rückmeldung über die Verfügbarkeit des entsprechenden Bausteins liefert.
Die 7-Bit Adressen (und auch die 10 Bit Adressen, siehe unten) sind üblicherweise aufgeteilt in einen fest kodierten Teil (üblicherweise die oberen 4 der 7 Bits) der bausteinspezifisch ist und einen einstellbaren variablen Teil (bleiben die unteren 3 Bits), der über externe Pins nach Bedarf konfiguriert werden kann. Der Sinn hinter dieser Aufteilung ist ganz klar, damit können in einem System mehrere identische Bausteine eingesetzt werden, die über die externe Beschaltung auf verschiedene Adressen gelegt werden. Die Implementierung dieser Adresseinstellung ist jeweils aus der Spezifikation des jeweiligen I²C-Bus-fähigen Bausteines ersichtlich.
Zwei Adress-Patterns haben innerhalb des Adress-Bytes eine Sonderfunktion.
In einigen Fällen reichte der Adressraum des I²C-Busses nicht mehr aus. Deshalb wurde in der ersten allgemeinen Spezifikation ein 10-Bit Adress Modus definiert.
Um eine Adresserweiterung vorzunehmen, wurde das Adress-Pattern “1111.0xxy” reserviert. Das Pattern “11110” signalisiert, dass es sich bei dem als erstes empfangenen Byte nicht um die Adresse selbst, sondern um eine Erweiterung handelt. Die beiden Bits “xx” liefern dann die zwei höchstwertigen Bits der 10-Bit Adresse und das Bit “y” ist das “READ/WRITE” Bit. Nach dem Empfang des 10-Bit Patterns wird das nachfolgende Byte als Adresse behandelt und liefert die 8 niedrigwertigeren Bits der 10 Bit Adresse.

Das Adress-Vergleichsregister in den Bausteinen erkennt falls die ersten 4 Bit nach der "START" Kondition "1" sind und schaltet in den 10-Bit Modus.
Ergänzend sei gesagt, dass der Adressbereich "1111.xxxx" komplett reserviert ist, der Bereich "1111.1xxx" ist für zukünftige mögliche Anwendungen reserviert und wird zur Zeit nicht benutzt.
Die “GENERAL CALL” Adresse “0000.0000” ist eine Adresse die einen “Broadcast” auf dem Bus ermöglicht. Wird diese Adresse verwendet, kann an alle Busteilnehmer eine gemeinsame Nachricht oder gemeinsame Daten gesendet werden, vorausgesetzt der jeweilige Slave kann diese Information verarbeiten. Dies heißt im Einzelnen, jeder Baustein muss auf die Adresse “0000.0000” reagieren und das “ACKNOWLEDGE” Bit bedienen.

Da es sich beim General Call um eine “broadcast” Message handelt kann nur der Master Daten senden aber nicht empfangen und das “Least Significant Bit” des ersten Bytes muss immer “Low” (0) sein. Die 7 Bit des zweiten Bytes werden als Instruktion interpretiert, die an alle Bausteine auf dem Bus gesandt wird.
Ergänzend sei gesagt, dass der Adressbereich "1111.xxxx" komplett reserviert ist, der Bereich "1111.1xxx" ist für zukünftige mögliche Anwendungen reserviert und wird zur Zeit nicht benutzt.
Momentan sind zwei Funktionen definiert:
Übrigens sind alle Adressen, die mit "0000.xxx0" beginnen (zur Zeit nur "0000.0000" bis "0000.0110") für "Instruktionen" reserviert.
Das Pattern "0000.0000" als zweites Byte ist nicht erlaubt; es würde mit der General Call Adresse zusammen nur aus "Nullen" bestehen und könnte leicht zu Fehlern führen.
Das "least significant Bit" des zweiten Bytes ist in den oben aufgeführten Fällen, in denen eine "Instruktion" an alle Teilnehmer abgesetzt wird immer "0". Falls das "LSB" eine "1" enthält, bietet sich die Möglichkeit in den anderen 7 Bit die Adresse des Senders (Hardware-Master) zu hinterlegen und/oder auch zusätzliche Daten an die beiden Bytes des "Hardware General Calls" anzuhängen.

Mit dieser Methode sind folgende Möglichkeiten verbunden:
Nachdem jetzt die Möglichkeit besprochen wurde, einen Busteilnehmer über die Adressierung auszuwählen, können komplette Bus-Protokolle aufgebaut werden.
Nachfolgend die möglichen Protokolle, die sich durch die Art der Adressierung (7 Bit- oder 10 Bit Adressen), durch die Daten-Transfer Richtung (schreiben / Lesen) sowie durch die etwas komplexere Struktur eines kombinierten Schreib/Lese Vorgangs ("COMBINED") unterscheiden.
Das einfachste Busprotokoll auf dem I²C-Bus benötigt im minimum 2 Bytes, ein Adress-Byte und ein Datenbyte.

Jedes gesendete Byte wird in diesem Fall vom Slave mit dem jeweils neunten Takt-Impuls auf der "SDA" Leitung quittiert ("Acknowledged"). Die Anzahl der übertragenen Datenbytes im Anschluss an das Adressbyte ist nicht limitiert solange das System mit der Busauslastung zurecht kommt, d.h. solange andere Teilnehmer auch Zugriff zum Bus erhalten. Solange der Master kein "Stop"-Bit sendet, hat er beliebigen Zugriff und blockiert den Bus.
Der gesamte Übertragungsrahmen ist durch ein "Start"-Bit und ein "Stop"-Bit begrenzt. Adresse und Daten werden vom Master (dem sendenden Teilnehmer) auf den Bus erzeugt, die "ACKNOWLEDGES" vom Slave (dem empfangenden Teilnehmer).
Das achte Bit im ersten Byte ("Read/Write") ist eine "0", weil Daten zum Slave geschrieben werden.
Der zweite Fall behandelt das Lesen eines Slaves mit einer 7-Bit Adresse. Das Protokoll ist fast identisch mit dem Protokoll beim Schreiben aber das "Read/Write"-Bit ist auf "1" gesetzt.

Da sich die Datenübertragungs-Richtung umkehrt, muss der Slave (der zu lesende Baustein) die Daten auf dem Bus mit dem externen Takt bereitstellen und der Master quittiert über die jeweiligen "ACKNOWLEDGES" nach jedem Daten-Byte den Empfang.
Je nach Slave-Device (z.B. Speicherbausteine) können große Mengen an Daten sequentiell ausgelesen werden. Benötigt ein Master nur einen Teil der verfügbaren Daten, so kann er die weitere Übertragung unterbrechen, indem er nach dem letzten gewünschten Byte kein "ACKNOWLEDGE" sendet.
Bei der erweiterten Adressierungsart mit 10 Bit Adressen werden zwei Byte als "Header" verwendet. Im ersten Byte wird das "LSB" weiterhin als "Read/Write"-Bit interpretiert und bestimmt die Übertragungsrichtung. Will der Master senden so ist das Bit auf "0" gesetzt.

Die "10-Bit" Kennung zu Beginn des ersten Bytes aktiviert im Slave den 10-Bit Adressmodus. Danach wird die eigentliche Adresse aus den beiden Adressbits des ersten Bytes und den 8 Bit des zweiten Bytes zusammengesetzt.
Auch im 10-Bit Modus gibt es ein entsprechendes "Master liest Slave" Protokoll.
Die Adressierung im Header ist identisch zum Schreib-Modus, auch das "Read/Write" Bit ist auf "0" gesetzt und ermöglicht es ein weiteres Byte (in diesem Fall das erweiterte Adress-Byte) zu übertragen. Dieses zweite Byte sowie die beiden Adressbits im ersten Adress-Byte ergibt die 10 Bit Adresse, die von allen Slaves hinsichtlich der Übereinstimmung zur eigenen Adresse verglichen wird.
Als wesentlicher Unterschied zu den bisher behandelten Adressierungsarten bedarf es danach einer Möglichkeit, die Übertragungsrichtung innerhalb des Protokolls umzukehren. Dies geschieht mit Hilfe einer "repeated Start" Kondition. Diese wird vor einer regulären "Stop" Kondition erzeugt und setzt die interne Bus-Logik aller Slaves zurück, um ein weiteres erstes Adressbyte zu dekodieren.

Im hier behandelten Falle der einfachen 10-Bit Adressierung zum Lesen eines Bausteines bleibt die Selektion des Bausteines bestehen und nach einer "repeated Start" Kondition wird das 10-Bit extended Adressen Pattern ( 1111.0xx ) mit einem auf "1" gesetzten "Read/Write" Bit gesendet, was bedeutet, dass alle nachfolgenden Daten vom Slave gelesen werden und kein weiteres Adressbyte mehr zu erwarten ist!
WICHTIG !
Ist der entsprechende Baustein angesprochen so bleibt er bis zur nächsten "Stop" Kondition oder bis eine weitere komplette Adressierung erfolgt, selektiert!
Das "ACKNOWLEDGE" wird wie im 7-Bit-"lese"-Modus vom Master nach jedem gelesenen Datenbyte gesteuert. Ebenfalls wie im 7-Bit Modus kann die weitere Übertragung von Daten vom Slave zum Master durch ein nicht-quittiertes "ACKNOWLEDGE" gestoppt werden.
Genau genommen ist der 10-Bit Adressen Modus beim Lesen von einem "Slave" bereits ein "combined Modus".
Diese bisher aufgezeigten Adressierungsarten betreffen immer die Adresse eines physikalischen Bausteines am I²C-Bus. D.h. die im Adressfeld des I²C-Bus-Protokolls übertragene Adresse ist einem "Chip-Select" gleich zu setzen und selektiert nur einen Baustein (oder sollte das zumindest).
I²C-Bus-Bausteine können intern aber sehr unterschiedliche Register-Strukturen besitzen, die angesprochen werden müssen. Um diese Strukturen (Register, Speicherzellen)
ansprechen zu können, wird üblicherweise eine weitere Adressierungsschicht verwendet, die aber Baustein-spezifisch ist und durch die sogenannte "Combined Mode" Adressierung
in der I²C-
Bus Spezifikation unterstützt wird.
Der "Combined Mode" ermöglicht die Umkehr der Datentransfer-Richtung, ohne dass der Master die Kontrolle über den I²C-Bus abgeben muss. Dies ist speziell dann notwendig, wenn ein Register oder eine Speicherzelle in einem I²C-Bus Baustein adressiert und danach dieses oder andere Register oder Speicherzellen gelesen werden sollen.
Der erste Teil läuft wie ein normaler Zyklus mit Angabe der Zieladresse (kann 7 Bit oder 10 Bit lang sein) und darauf folgendem "Schreiben" eines Datenbytes in den Slave-Baustein ab. Um den Buszugriff nicht zu verlieren wird jedoch keine "Stop" Kondition gesendet, sondern erneut eine "Start" Kondition. Daher gilt der Bus weiter als aktiv und kein anderen Master kann darauf zugreifen.
Mit der erneuten "Start" Kondition ( "repeated Start" ) wird ein neuer Adress-Zyklus gestartet. Als Adresse wird die vorher angesprochene "Slave"-Adresse verwendet, allerdings wird jetzt das "Read/Write" Bit auf "Lesen" gesetzt und das erste Byte von diesem Baustein gelesen. Damit werden die Daten vom Slave zum Master übertragen. Dieser Vorgang ist auch umkehrbar und es kann zuerst von einer Adresse gelesen und danach geschrieben werden.
Als weitere Möglichkeit bietet der "Combined" Mode die sequentielle Adressierung mehrere Slaves innerhalb eines aktiven Bus-Zyklus.
Für den/die Slave/s an einem I²C-Bus ist dieser Vorgang transparent, d.h. der Slave erkennt eine "Start" Kondition und interpretiert das darauf folgende Byte als Adresse, ganz gleich ob es sich dabei um eine normale oder eine wiederholte "Start" Kondition handelt. Die Adresse wird dekodiert und die darauf folgenden Daten übernommen.
In der I²C-Bus Spezifikation wird explizit darauf hingewiesen, dass kompatible I²C-Bus Bausteine beim Empfang einer "Start" Kondition ihre Bus-Logik zurücksetzen müssen, um die folgende Adresse dekodieren zu können. Eine vorangegangene Selektion eine Bausteines durch einen Adress-Zyklus bleibt aber vorerst erhalten.

Dies impliziert auch, dass mehrere aufeinander folgende "repeated Start" Konditionen möglich sind und ein Master den Bus auch dauerhaft blockieren kann, falls er keine "Stop" Kondition sendet.
Mit dem "combined Mode" können mehrere Bus-Transaktionen, ausgehend von einem Master ohne zwischenzeitliche Bus-Arbitrierung (Zugriffsvergabe), zusammengefasst werden.
Innerhalb eines "Combined Mode" Zugriffs kann :
Natürlich gelten auch innerhalb der "combined Modi" die Regeln für das "ACKNOWLEDGE" Bit, d.h. ein mehrfacher Lesevorgang von einer Adresse (nicht von verschiedenen Adressen) innerhalb des "combined Mode" Rahmens wird durch ein nicht bestätigtes "ACKNOWLEDGE" Bit abgebrochen.
Jeder Adress-Zyklus startet mit einer "Start" Kondition (oder "repeated Start" Kondition, was eigentlich dasselbe ist). Jeder I²C-Baustein löscht sein Eingangs-Register und erwartet das erste Byte, das wie beschrieben eine Adresse ist.
Sobald das erste Byte im Register ist werden folgende Aktionen ausgeführt:

Die interne Implementierung von Slave Bausteinen ist in der I²C-Bus Spezifikation logischer Weise nicht definiert, da diese ja nur den Datentransfer behandelt (Physical Layer, Bit Layer und Protocol Layer) nicht aber die Weiterverwendung der übertragenen Daten. Den Entwicklern von integrierten Schaltungen ist daher ein grosser Spielraum für die Implementierung der Bausteine gegeben, allerdings sind bedingt durch den I²C-Bus auch Einschränkungen vorhanden.
Die heute verfügbaren Bausteine mit I²C-Interface reichen von einfachen I/O-Expandern, A/D-Wandlern, Speichern bis hin zu komplexen Komplettfunktionen wieTuner- oder Audio-ICs. Dieses Kapitel soll einige grundlegende Möglichkeiten für die Adressierung und Ansteuerung von solchen Bausteinen aufzeigen.
Da komplexe Bausteine eine große Anzahl von internen Registern besitzen, muss eine Möglichkeit gefunden werden diese zu adressieren. Diese Registeradressen haben, und hier muss man klar trennen, nichts zu tun mit der I²C-Bus Adresse (bis auf eine Ausnahme, siehe Hybride Adressierung) ! Es bedarf also einer zweiten Adressierungsebene die innerhalb des Datenbereichs eines I²C-Bus Protokolls frei festgelegt werden kann.
Es können verschiedene Adressierungsarten Verwendung finden.
Was hier als direkte Adressierung bezeichnet wird ist die feste Zuordnung eines Datenbytes im I²C-Protokoll zu einem Register. Diese Adressierungsart ist daher nur für Bausteine implementierbar die nur einige wenige interne Register besitzen (Datenregister, Konfigurationsregister). Ein Analog-Digital-Wandler mit nur einem Analogeingang besitzt im einfachsten Fall nur ein Datenregister das vom Prozessor (I²C-Master) ausgelesen werden soll um das "Daten-Sample" abzuholen.

Als echtes Beispiel möchten wir aber den Baustein PCF8575 von Philips Semiconductor verwenden. Dieser Baustein ist ein I/O-Expander, also ein IC das, in diesem Fall, zwei 8-Bit Ports zur Verfügung stellt. Beide Ports sind sowohl als Eingang als auch als Ausgang verwendbar und kommen durch eine clevere Ausgangsstruktur ohne ein Konfigurations-register aus.
Es geht also bei diesem Baustein lediglich darum die Daten der beiden Ports zu lesen oder zu schreiben. Dies wird durch die I²C-Protokoll-Struktur festgelegt und durch das R/W Bit innerhalb des I²C-Adressbits definiert, das wurde ja bereits beschrieben.
Direkte Adressierung heißt in diesem Fall, das Port 0 des Bausteins wird durch das erste Datenbyte im I²C-Protokoll und Port 1 durch das zweite Datenbyte im I²C-Protokoll angesprochen. Es liegt als eine feste Zuordnung der einzelnen Datenbytes im Protokoll zu den physikalischen Registern im Baustein vor.
Diese Registeradressierung hat den Vorteil, dass lediglich die Daten übertragen werden müssen und kein Overhead entsteht. Die Limitierung dieser Art und Weise, Register in einem IC über I²C anzusprechen, liegt in der Anzahl der in einem Baustein verwendeten Register, da für die Änderung eines Registers jeweils der komplette Satz Daten übertagen werden muss. Bei zwei, drei eventuell vier Registern ist das kein großes Thema aber bei 10, 20 oder mehr Registern entsteht doch ein wesentlicher Mehraufwand bei der Steuerung des Bausteins.
Wenn es sich um nur wenige Register handelt, wie beispielsweise beim MAX1236 der Firma Maxim, einem 12-Bit A/D-Wandler mit Analogmultiplexer, der jeweils ein Register für die Konfiguration bzw. den Setup besitzt, kann die Adressierung der Register Teil des Datenbytes selbst sein.

Das nach dem I²C-Adressbyte übertragene Datenbyte enthält im höchstwertigen Bit die Selektion (Adresse) in welches Register die nachfolgenden 7 Bits geschrieben werden sollen oder auch welches Register gelesen werden soll.
Dieser kompakte Adressierungs-Modus ist ein Übergang von der direkten Adressierung zur nachfolgend beschriebenen "Sub-Adressierung". Die implizite Adressierung erlaubt im Gegensatz zur direkten Adressierung das Ansprechen einzelner Register und hat deshalb Vorteile wenn nur verschiedene einzelne Register geschrieben werden sollen.
Bei noch mehr Registern oder Speicherarrays bietet es sich an eine "Subadressierung" zu übertragen. Neben der I²C-Bus Adresse wird meist ein Byte (es könnten aber auch zwei oder mehrere Bytes sein) als "Registeradresse" übertragen. Wie vorher schon angesprochen ist das keine in der "I²C-Bus Spezifikation" definierte Vorgehensweise, sondern eine applikations-spezifische Implementierung. Daher kann und wird es bei verschiedenen Schaltungen die auf dem Markt erhältlich sind Unterschiede geben.
Die Funktionsweise der "Sub-Adressierung" ist dadurch gekennzeichnet, dass als erstes Datenbyte ein vom jeweiligen Baustein als Adressebyte interpretierter Wert übertragen wird, der dann ein definiertes, internes Register aktiviert. Das darauf folgende Datenbyte im Protokoll wird in diese Register geschrieben oder von diesem Register gelesen.

In diesem Fall, bei dem ein Register (oder eine Speicherzelle) "gelesen" werden soll, wird die "Repeated Start" Kondition benötigt, da erst die Adresse geschrieben werden muss und danach das Register gelesen wird, also eine Umkehrung des Datenflusses stattfindet.
Als Beispiel für eine solche "Sub Adressierung" kann der Baustein TDA 7462 dienen, ein komplettes Audioprozessor System auf einem Chip. Bei diesem Baustein ist das erste Datenbyte das der I²C-Bus Adresse folgt als "Subadresse" definiert. Die 4 niedrig-wertigeren Bits diese Subadresse sind direkt auf ein Reihe von sechzehn internen Registern „gemappt“ und ermöglichen das Ansprechen von Funktionen wie Lautstärke, Bässe und Höhen, Balance und Fader, aber auch verschiedene Einstellungen der Baustein- Konfiguration. Der Vollständigkeit halber sei erwähnt dass die 4 höherwertigen Bits in der "Subadresse" beim TDA 7462 eine Umschaltung des Betriebsmodus ermöglichen, hier wurde also eine Art "gemischtes Daten-Adressen Byte" implementiert.
Der Vorteil gegenüber der direkten Adressierung besteht darin das komplexe Registerstrukturen adressiert werden können, ohne redundante Daten übertragen zu müssen. Noch mehr zum Tragen kommt diese Konzept der impliziten Adressierung bei Speicherbausteinen, da hier ja große Adressbereiche anzusprechen sind.
Was wir hier als "Automatische Adressierung" bezeichnen wollen ist eigentlich keine eigenständige Adressierungsart innerhalb eines Bausteins sondern eher eine Erweiterung der "Sub-Adressierung". Bei der automatischen Adressierung muss wie bei der Sub-Adressierung erst einmal eine Basisadresse übermittelt werden. Von dieser Basisadresse ausgehend kann dann gelesen oder geschrieben werden.

Der Unterschied besteht darin, dass die Basisadresse beim lesen bzw. schreiben automatisch inkrementiert wird. Dadurch ist es möglich große Speicherbereiche durch Angabe der Basisadresse und zyklisches Lesen ohne neue Adressierung auszulesen. Diese Art der Übertragung bezeichnet man auch als "Blocktransfer" oder "Auto-Increment " Modus. Solche Modi sind nicht nur bei Speicherbausteinen implementiert sonder auch bei komplexen Bausteinen wie dem oben erwähnten TDA 7462 um eine schnelle Initialisierung des Bausteins zu ermöglichen.
Der Lesevorgang, auch im automatischen Modus kann durch jederzeit durch ein nicht quittiertes "ACKNOWLEDGE" beendet werden.
Für diesen "Auto-Increment" Modus wird im Baustein ein Adresszähler implementiert, der auch nach der Übertragung einer "Stop" Kondition noch die zuletzt inkrementierte Adresse behält. Daraus lässt sich ein weitere Modus ableiten, der bei dem EEPROM Baustein M24C16 von STMicroelectronics als "Current Adress" Modus bezeichnet wird. Nach einem initialen Lesevorgang bei dem die erste Adresse in den Baustein (Adresszähler) geschrieben und die erste Speicherzelle ausgelesen wird, kann nach Beendigung des I²C-Protokolls durch eine "Stop" Kondition zu jeder Zeit (kein Reset/Spannungsverlust vorausgesetzt) durch einen reinen Lesevorgang, ohne weitere Adressierung das nächste Byte im Speicher gelesen werden. Dies kann beliebig oft wiederholt werden.
Ein weiterer Fall von automatischer Adressierung wird bei Speicherbausteinen als "Page Mode" bezeichnet. Der Page Mode ist ein "Auto-Increment" Modus, mit der durch die Speichermatrix des Bausteins hervorgerufenen Limitierung, dass über "Page-Grenzen" nicht so einfach geschrieben werden kann. Bei dem oben erwähnten Baustein M24C16 ist der "Page Mode" auf 16 sukzessive Schreibzyklen begrenzt. Außerdem dürfen diese 16 Bytes nicht über eine Page-Grenze geschrieben werden da sonst ein "Roll-Over" auftritt und Speicherzellen in derselben Bank überschrieben werden (Modulo "n").
Diese Adressierungsart wird in dem Sinne als eine hybride (gemischte) Adressierung bezeichnet, da ein Teil der I²C-Bus Adresse für die Baustein interne Adressierung mitverwendet wird. Bei der Adressierung des I²C-Busses wurde im 7-Bit Modus aufgezeigt wie die 7 Bit Adresse sich aus zwei Teilen zusammensetzt. Die 4 höherwertigen Bits werden bei der Entwicklung des ICs fest codiert, dieser Teil wird als "Device Adresse" bezeichnet. Die drei niedrigwertigeren Bits werden üblicherweise durch externe Pins des ICs bestimmt um mehrere gleiche Bausteine am gleichen Bus betreiben zu können.

Bei der hybriden Adressierung werden diese drei Bits zusammen mit einer "Subadresse" (also eine im Datenbereich des Protokolls übertragenen Adresse) für die Adressierung der Slaves internen Register bzw. Speicherzellen verwendet.
Bei dem schon mehrfach erwähnten Baustein M24C16 (16 kBit) werden die 3 Bit aus der I²C-Adresse als Page-Select (Bank Select) benutzt und die "Subadresse" als Adresse innerhalb der Page. Die Bausteinvarianten M24C08 (8kBit) , M24C04 (4 kBit) benutzen nur zwei , bzw. eines der I²C Adressbits. Der noch kleineren Speicher M24C02 (2kBit) verwendet dagegen keine "Hybride Adressierung" da die 8-Bit Adresse (Subadresse) ausreicht um die 256x8Bit Speichermatrix zu adressieren.
[1] The I²C-Bus Specification, Version 2.1 , January 2000, Philips Semiconductors
[2] I²C-bus specification and user’s manual, Rev. 6, 4 April 2014, NXP
Copyright 2017 by Dipl.Ing.(FH) Franz Henkel
Dieses Dokument sowie dessen Inhalt, insbesondere Texte, Fotografien und Grafiken, unterliegt dem Copyright (© 2017) und sind nur mit einer schriftlicher Zustimmung des Autors, Dipl.Ing.(FH) Franz Henkel zur vollständigen oder auszugsweisen Weiterverwendung in Form einer gedruckten oder elektronischen Kopie oder Replikation bzw. einer vollständigen oder auszugsweisen Bereitstellung des Inhalts in schriftlicher, gedruckter oder elektronischer Form, zu verwenden.