Der I2C-BUS als bitserieller Datenübertragungskanal |
![]() |
![]() |
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
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. |
||||||
![]() |
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 |
||||||
![]() |
|
||||||
![]() |
Quellen:
|
1. Prinzip und Kommunikationsprotokoll der I2C-Schnittstelle |
![]() |
![]() |
![]() |
![]() |
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. |
![]() |
|
![]() |
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 |
![]() |
![]() |
![]() |
![]() |
|
![]() |
Die Rollenverteilung Bei der Kommunikation zwischen zwei Partnern sind (nicht nur auf dem I2CBus) verschiedene Rollen zu beachten:
Die Rollenverteilung ist zu einem Teil durch die Hardware festgelegt und kann
daher nicht geändert werden: |
![]() |
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. Die acht Schritte eines Schreibvorgangs im Einzelnen:
|
![]() |
Die acht Schritte eines Lesevorgangs im Einzelnen:
|
![]() |
Eine Botschaft besteht also aus folgenden Teilen:
|
![]() |
nachfolgend nun die Teile einer Botschaft |
3. Protokoll einer Botschaft auf dem BUS |
![]() |
![]() |
![]() |
![]() |
||||||||||||||||||||||||||||||||||||||||
![]() |
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 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.
|
|||||||||||||||||||||||||||||||||||||||
![]() |
Acknowledge-Bit Quittungssignal mit Hilfe des Acknoledge-Bits Auf jedes gelesene Daten-Byte reagiert der Empfänger mit einem AcknowledgeBit. 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 |
![]() |
![]() |
![]() |
![]() |
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 Kommunikation 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. |
5. Der I2C-Bus-Controller |
![]() |
![]() |
![]() |
![]() |
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. |
6. Stelligkeitenprüfung |
![]() |
![]() |
![]() |
![]() |
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 |
![]() |
![]() |
![]() |
![]() |
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. | ||||||
![]() |
|
![]() |
© 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 |