Der I2C-BUS als bitserieller Datenübertragungskanal history menue Letztmalig dran rumgefummelt: 29.06.17 19:34:27
Der I2C-Bus ist entwickelt worden, um in Geräten der Unterhaltungselektronik, wie Fernsehgeräten, CD-Playern usw. eine einfache Kommunikation zwischen verschiedenen ICs (Inter IC =12C) des Geräts zu ermöglichen. Es handelt sich um einen
  • bidirektionalen
  • 2-Draht-Bus, der eine
  • serielle,
  • synchrone Datenübertragung
  • in 8-Bit-Blöcken
  • mit Geschwindigkeiten bis zu 100 kbit/s im Standardmodus (und 3,4 Mbit/s im High-speed mode)
  • über Kabellängen von mehreren Metern ermöglicht.

Dabei kann eine große Anzahl gleicher oder verschiedener ICs an den 12C -Bus angeschlossen werden, weil jedes IC über eine eigene, einstellbare Adresse verfügt.
Wir benutzen den I2C-Bus hier, um vom PC aus Mess- Steuer und Regelaufgaben zu erledigen. Um das Ganze überschaubar zu halten, beschränken wir uns dabei auf den Betrieb mit nur einem Master im Standardmodus - in der Gerätepraxis sieht das anders aus.

 1. Prinzip der I2C-Schnittstelle
 2. Prinzip und BUS-Kommunikation
 3. Protokoll einer Botschaft auf dem BUS
 4. Kommunikation mit Delphi
 5. Der I2C-BUS-Controller
 6. Stelligkeitenprüfung
 7. Verwandte Themen

Parallel-Serien sowie Serien-Parallel-Wandler

i2C-Schnittstelle - das Anliegen

inhaltlich auf korrektem Stand - evtl. partiell unvollständig ;-)

Informatik-Profi-Wissen

Quellen:

1. Prinzip und Kommunikationsprotokoll der I2C-Schnittstelle history menue scroll up
Hierbei wird die gesamte Information (z.B. die 8 Bit eines Wortes) zeitlich nacheinander auf einer einzigen Leitung (auf einem einzigen Übertragungskanal) übertragen bzw. steht an einem Schaltkreisanschluss zur Verfügung. Die Signale werden in Form von Impulsen (kurzzeitiger H- bzw. L-Spannungs- oder Strompegel) dargestellt. Zur Übertragung bzw. Darstellung eines n-bit-Wortes werden n „Bitzeiten“ benötigt. Je nach der Schaltzeit der digitalen Schaltungen liegt eine Bitzeit im Bereich von ns bis ms.

Kommunikationsprotokoll des 12C-Bus

Wie im Abschnitt Wired-OR schon zu sehen ist, sind die einzelnen Geräte (die ICs) am I2C-Bus alle parallel geschaltet. Genau genommen sind sie WIRED-OR verknüpft. Die WIRED-OR-Verknüpfung ist für die Leitungen SDA und SCL gleichermaßen realisiert und arbeitet so: Der Pull-up-Widerstand Rp zieht die Leitung SDA (oder SCL) auf +VDD = 5SV, was ja dem logischen Zustand High (1) entspricht; dieser Zustand bleibt solange erhalten, bis ein Gerät über den Transistor SDA Out die Leitung SDA mit der Masse verbindet, was ja dem logischen Zustand Low (0) entspricht. Für die Leitung SDA macht es keinen Unterschied, ob nun das Gerät 1 oder Gerät 2 die Verbindung mit der Masse herstellt, die Leitung würde in beiden Fällen den logischen Zustand Low (0) annehmen. Es ist also eine ODER-Verknüpfung, die einfach durch Anschluss aller Geräte an eine Leitung (wire) erreicht wird, daher WIRED-OR.

2. BUS-Kommunikation history menue scroll up
 
Die Rollenverteilung

Bei der Kommunikation zwischen zwei Partnern sind (nicht nur auf dem I2CBus) verschiedene Rollen zu beachten:

  • der Sender sendet die Daten auf den Bus (schreibt).
  • der Empfänger empfängt die Daten vom Bus (liest).
  • der Master leitet die Übertragung der Daten ein und beendet sie, er erzeugt das Taktsignal.
  • der Slave wird aktiviert, wenn seine Adresse vom Master auf den Bus gesendet wurde.

Die Rollenverteilung ist zu einem Teil durch die Hardware festgelegt und kann daher nicht geändert werden:
Der Controller in unserem Interface ist immer der Master auf dem I2C-Bus; die angeschlossenen ICs können nur als Slaves arbeiten, zu jedem Zeitpunkt aber immer nur eines. (Es gibt auch Systeme mit mehr als einem Master; dann kann auch jeder Master zum Slave werden. Solche Multi-Master-Systeme betrachten wir hier aber nicht.)
Der andere Teil der Rollenverteilung wird durch die Software festgelegt und ist daher auch veränderbar: Wer Sender und wer Empfänger einer Übertragung (oder Botschaft) ist, wird am Anfang der Übertragung (vom Master) festgelegt.

Der Aufbau einer I2C-Botschaft

Auf dem I2C-Bus sehen die beiden einfachsten Botschaften folgendermaßen aus:

Der Master sendet ein oder mehrere Daten-Bytes an einen Slave, den Empfänger.

Write-Cycle

Die acht Schritte eines Schreibvorgangs im Einzelnen:

  1. Der Master stellt die START-Bedingung her.
  2. Der Master sendet die 7 Bit der Slave Adresse und als B. Bit eine 0 (write).
  3. Der Slave sendet ein Acknowledge-Bit: „Ich bin bereit, Daten zu empfangen".
  4. Der Master sendet ein Datum (ein Byte).
  5. Der Slave sendet ein Acknowledge-Bit: „Ich bin bereit, Daten zu empfangen".
  6. Der Master sendet ein Datum (ein Byte).
  7. Der Slave sendet ein Acknowledge-Bit: „Ich bin bereit, Daten zu empfangen".
  8. Der Master stellt die STOP-Bedingung her.

Read-Cycle

Die acht Schritte eines Lesevorgangs im Einzelnen:

  1. Der Master stellt die START-Bedingung her.
  2. Der Master sendet die 7 Bit der Slave Adresse und als B. Bit eine 1 (read).
  3. Der Slave sendet ein Acknowledge-Bit: „Ich bin bereit, Daten zu senden".
  4. Der Slave sendet ein Datum (ein Byte).
  5. Der Master sendet ein Acknowledge-Bit: „Ich bin bereit, Daten zu empfangen".
  6. Der Slave sendet ein Datum (ein Byte).
  7. Der Master sendet ein NOT Acknowledge-Bit: „Ich bin nicht mehr bereit, Daten zu empfangen".
  8. Der Master stellt die STOP-Bedingung her.
Eine Botschaft besteht also aus folgenden Teilen:
  • START Bedingung
  • Slave Adresse mit dem R/W-Bit
  • Acknowledge-Bit
  • ein oder mehrere Daten-Bytes
  • gleiche Anzahl Acknowledge-Bits
  • STOP Bedingung.
nachfolgend nun die Teile einer Botschaft

3. Protokoll einer Botschaft auf dem BUS history menue scroll up
 
SDA und SCL, Zwei-Draht-Bus

Der 12C-Bus hat ja zwei Leitungen: SDA und SCL, Serial Data und Serial Clock. In unseren Konfigurationen wird der Takt immer vom Controller, dem einzigen Master auf dem Bus, erzeugt. Im Protokoll ist vereinbart, dass der Sender im Normalfall den Zustand der Datenleitung SDA nur ändern darf, wenn SCL = 0 ist. Deswegen liest der Empfänger das jeweilige Datenbit nur, wenn SCL = 1 ist. Die einzigen beiden Ausnahmen von diesem Normalfall sind die START und

STOP-Bedingung

START- und STOP-Bedingung
Wenn auf dem PC-Bus gerade keinerlei Übertragung stattfindet, sind beide Leitungen SDA = 1 und SCL = 1. Am Anfang einer Übertragung stellt der Master die START-Bedingung her, indem er die Leitung SDA von 1 auf 0 setzt, während SCL = 1 ist - im Gegensatz zum Normalfall. Entsprechendes gilt für die STOP-Bedingung: der Master ändert den Zustand auf SDA von 0 auf 1, während SCL = 1 ist.

START- und STOPP-Bedingung wird vom Master erzeugt

Slave Adresse

Die Slave Adresse eines ICs besteht aus einer 7 Bit langen eigentlichen Adresse und dem RIW-Bit. Die 7 Bit setzen sich meist aus 4 Bits, die im IC als Hardware fest eingebaut sind, und 3 Bits, die meist mit Jumpern eingestellt werden können, zusammen. Das achte, niederwertigste Bit zeigt dem angesprochenen IC an, ob geschrieben (0) oder gelesen (1) wird.

 

 
  MSB             LSB
Bit-Nr. 7 6 5 4 3 2 1 0
  Fest eingebaut durch Jumper einstellbar R/W
Beispiel PCF 8574 0 1 0 0 X X X 0
 


Beispiel: Der I/O-Expander PCF 8574 hat als Bit 7 ... 4 fest eingebaut 0100; wenn man die drei einstellbaren Adressleitungen alle auf 0 setzt und den Baustein zum Schreiben (0) ansprechen will, muss man also die Adresse 0100 0000 im Binärformat oder 0x40 im Hexadezimalformat oder 64 dezimal auf den FC-Bus senden. Schickt man hingegen 65, bzw. 0x41, bzw. 0100 0001 auf den Bus, würde man den gleichen Baustein ansprechen, um von ihm Daten zu lesen.

Acknowledge-Bit

Quittungssignal mit Hilfe des Acknoledge-Bits

Auf jedes gelesene Daten-Byte reagiert der Empfänger mit einem Acknowledge­Bit. Damit quittiert der Empfänger dem Sender den Empfang des Daten-Bytes. Der Empfang wird während des 9. Taktimpulses quittiert, indem der Sender die Leitung SDA = 1 lässt und nachsieht, ob der Empfänger diese Leitung auf SDA = 0 zieht. Wenn der Empfänger das Datenbyte korrekt empfangen hat, zieht er vor Beginn des 9. Takt-impulses die Leitung auf SDA = 0; wenn der Empfänger kein komplettes Byte empfangen hat, tut er nichts und lässt damit SDA = 1, was der Sender als NOT Acknowledge interpretiert.

 

4. Kommunikation in Delphi history menue scroll up
Das gerade vorgestellte Kommunikationsprotokoll beherrscht der Controller auf der Interfacekarte natürlich, er erledigt für uns das korrekte Timing auf der Leitung SCL, die Serialisierung eines Daten-Bytes in die 8 Bit für die Leitung SDA und das Warten auf das Acknowledge-Bit, sowie die Herstellung der START und der STOP-Bedingung. Wir brauchen dem Controller also nur die passenden Anweisungen zu geben.

Betrachten wir jetzt einmal die Übersetzung des Kommunikationsprotokolls in Delphi am Beispiel der Übertragung eines Daten-Bytes an ein IC auf dem 12C-Bus. Die folgende Methode der Klasse T12c erledigt die Übertragung der

procedure WriteToIC( adr: Byte;

p buffer: array of Byte; size: Integer);

12C-Adresse des IC und mehrerer Datenbytes und die Beendigung der Kom­munikation mit diesem IIC.

// WriteToIC       Sendet eine Zeichenfolge              //

//                              an ein bestimmtes IC                  // //------------------------------------------------------// // Eingabe    adr = Adresse des IC                  //

//                              p buffer = Zeiger auf ein Zeichenfeld//

//                 size = Größe des Zeichenfelds buffer //

// Ausgabe         keine                                 // procedure T12C.WriteToIC( adr: Byte;

p buffer: array of Byte; size: Integer );

var n: Integer; begin

InitWrite(adr);

for n:= 0 to size-1 do WriteCont(p_buffer[n]); StopWrite();

end;

Die eigentliche Datenübertragung findet in der Methode WriteCont statt: // WriteCont :    Sendet ein Byte an ein IC und                                        //

//                            wartet dann auf ein Ackknowledgemet     // //------------------------------------------------------// // Eingabe  value = zu sendende Byte                //

// Ausgabe        keine                                   // procedure T12C.WriteCont(value: Byte);

begin WriteData(value); if (GetAcknowledgement = NOACK) then begin

GenerateStop;

raise TERR.Create(12C NACK ON DATA, 0); end;

end;

Sie schreibt den übergebenenWert mit WriteData (value), procedure T12C.WriteData(value: byte);

begin

m EPP.Write(DATA, value); end;

die nur die EPP-Methode m_EPP.Write(DATA,value) aufruft, und wartet dann auf ein Acknowledge vom IC.

// GetAcknowledgement:     Wartet auf das                // //         Acknowledgement-Bit // //__-----__-------____-----____-----___-------___-----__// // Eingabe         : keine   //

// Ausgabe    : ACK = Acknowledgement-Bit TRUE            //

//         NOACK =Acknowledgement-Bit FALSE                   // function T12C.GetAcknowledgement: Byte;

var i: Integer; sl: Byte; begin

i:= 0;      // Warten auf ACK oder NACK repeat

sl:= ReadAdr(); Inc(i);

until ( (i > 12C-TRIES) or

(not (sl and PIN MASK = PIN MASK))); if (sl and PIN MASK = PIN_MASK) then begin                    // Timecut ? GenerateStop();

raise TERR.Create(12C TIME OUT, 0); end;

if not (sl and LRB_MASK = LRB_MASK) then GetAcknowledgement:= ACK

else

GetAcknowledgement:= NOACK;

end;

Der Controller zeigt in seinem Register S 1 den Status der Datenübertragung an, u.a. ob der angesprochene Slave mit einem Acknowledge den Empfang quittiert hat. In diesem Fall setzt der Controller dann nämlich in S 1 das LRBit = TRUE.
Sie sehen schon, wir müssen uns noch näher mit dem Controller und den angeschlossenen ICs beschäftigen.


5. Der I2C-Bus-Controller history menue scroll up
Bis hierher haben wir uns mit der 8-Bit-Seite des Controllers (Parallel Bus, Parallel Bus Control) beschäftigt - nunmehr müssen wir uns mit dem Innenleben des Controllers (seinen Registern), seiner 12C-Bus-Seite sowie seiner Programmierung auseinandersetzen.
Register

Blockschaltbild des Controllers

Der Controller besitzt fünf Register: SO, SO', S1, S2 und S3. Auf das Register SO kann man schreibend und lesend zugreifen, wenn AO = 0 ist; ist jedoch AO = 1, kann man in das Register S1 schreiben oder seinen Inhalt lesen. Wann man auf die anderen Register zugreifen kann, wird vom Inhalt des Registers S1 bestimmt.

Das Daten-Schieberegister SO

Das Register SO ist das Register, das die Verbindung zur 8-Bit-Welt herstellt, mit dem Parallel-Bus (dem EPP). Wenn der Controller einmal initialisiert ist, findet die Datenübertragung vom EPP zum I2C-Bus und umgekehrt über dieses Register SO statt.
Ein Byte vom Parallel-Bus wird in SO zwischengelagert und dann über das Schieberegister bitweise auf den IzC-Bus geschickt.
Bits vom 12C-Bus werden im Schieberegister zwischengelagert bis ein Byte komplett ist und dann über das Register SO dem Parallel-Bus übergeben


6. Stelligkeitenprüfung history menue scroll up
Hier gilt es zu prüfen, ob eine Zahl gerade oder ungerade ist. Dies kann auf logischer Ebene ohne die Anwendung einer implementierten Funktion schon zu einem echten Problem werden. Auf der Hardwareebene dagegen eine relativ leicht zu lösendes Aufgabe. Da die Zahlen eh im Binärformat vorliegen, muss eigentlich nur das Bit 0 getestet werden. Ist es gleich "0", so ist die Zahl gerade, sonst ungerade.
 

7. Verwandte Themen history menue scroll up
Codewandlungen stehen in der Praxis immer dann an, wenn Gerätekomponenten eingangs- und/oder ausgangsseitig einen Wechsel des Signalmusters erwarten oder benötigen. De facto ist die Gesamtheit aller logischen Schaltungen nichts weiter als eine Codewandlung. Immer wird aus einem gleichen Input ein äquivalenter Output generiert.

Wired-OR

Datenübertragungsverfahren

die RS232-Schnitttstelle

Parity-Generatoren

Serial Peripherial Interface

DigitalCommand Control Interface


zur Hauptseite

© Samuel-von-Pufendorf-Gymnasium Flöha © Frank Rost im Februar 1999

... dieser Text wurde nach den Regeln irgendeiner Rechtschreibreform verfasst - ich hab' irgendwann einmal beschlossen, an diesem Zirkus (das haben wir schon den Salat - und von dem weiß ich!) nicht mehr teilzunehemn ;-)

„Dieses Land braucht eine Steuerreform, dieses Land braucht eine Rentenreform - wir schreiben Schiffahrt mit drei „f“!“

Diddi Hallervorden, dt. Komiker und Kabarettist