2.9 Schnittstellen
2.9.1 UART
Grundlagen der UART Kommunikation
Universal
Asynchronous
Receiver
Transmitter
Die UART-Schnittstelle beschreibt ein einfaches serielles Kommunikations-Protokoll welches von vielen Mikrocontrollern unterstützt wird. Im Gegensatz zu SPI und I2C - welche im weiteren Verlauf behandelt werden - ist UART nicht im Master-Slave-Modus, sondern im Punkt-zu-Punkt-Modus implementiert. Das bedeutet, dass zwei Geräte direkt miteinander kommunizieren können, ohne dass ein Master-Gerät erforderlich ist.
Die Koummunikation über die UART-Schnittstelle kann in drei verschiedenen Modi erfolgen: Voll-Duplex, Halb-Duplex und Simplex. Duplex bedeutet, dass die Kommunikation in beide Richtungen gleichzeitig erfolgen kann. Halb-Duplex bedeutet, dass die Kommunikation in beide Richtungen erfolgen kann, jedoch nicht gleichzeitig. Simplex bedeutet, dass die Kommunikation nur in eine Richtung erfolgen kann.
Im einfachsten Fall reichen drei Leitungen aus um eine Verbindung herzustellen:
- TX (Transmit)
- RX (Receive)
- GND (Ground)
RX und TX werden dabei gekreuzt, d.h. TX des einen Geräts wird mit RX des anderen Geräts verbunden und umgekehrt. GND wird für die Referenzspannung benötigt.

Typische UART-Anwendungsgebiete
- Debugging
- Steuerung und Datenkommunikation (z.B. mit Sensoren, Peripheriegeräten oder anderen Geräten/Mikrocontrollern)
- Firmware-Updates, Kommunikation mit Bootloadern
- Kommunikation mit einem Computer (z.B. über USB-zu-UART-Adapter)
Protokoll
Ein UART-Frame besteht aus folgenden Teilen:
- Startbit (immer LOW)
- Datenbits (5-8 Bit, üblich sind 8 Bit)
- Paritätsbit (optional)
- Stopbit (immer HIGH, 1 oder 2 Bit)
Üblich ist 8N1, d.h. 8 Datenbits, kein Paritätsbit und 1 Stopbit.

Paritätsbit
Das Paritätsbit wird verwendet, um die Anzahl der Einsen im Datenbyte zu überprüfen. Es gibt zwei Arten von Paritätsbits:
-
Gerade Parität (even parity): Die Anzahl der Einsen in den Daten und im Paritätsbit ist gerade.
01100101 Das Paritätsbit ist 0 weil die Anzahl der Einsen bereits gerade ist.01100100 Das Paritätsbit ist 1 weil die Anzahl der Einsen ungerade ist. -
Ungerade Parität (odd parity): Die Anzahl der Einsen in den Daten und im Paritätsbit ist ungerade.
01100101 Das Paritätsbit ist 1 weil die Anzahl der Einsen gerade ist.01100100 Das Paritätsbit ist 0 weil die Anzahl der Einsen bereits ungerade ist.
Das Paritätsbit wird verwendet, um Übertragungsfehler zu erkennen. Wenn ein Bit während der Übertragung verloren geht oder sich ändert, wird dies durch die Paritätsprüfung erkannt. Sollten mehrere Bits kippen, funktioniert die Paritätsprüfung nicht mehr.
In der Praxis wird das Paritätsbit jedoch selten verwendet, da die meisten modernen Kommunikationsprotokolle andere Methoden zur Fehlererkennung und -korrektur verwenden.
Baudrate
Die Baudrate gibt an, wie viele Symbole (nicht Bits!) pro Sekunde übertragen werden. Die Baudrate muss auf beiden Seiten der miteinander kommunizierenden Geräte gleich eingestellt sein. Typische Werte sind 9600, 19200, 38400, 57600, 115200, ...
Handshake
Handshake ist eine Methode, um zu signalisieren, ob Daten gesendet oder empfangen werden können.
Es gibt zwei Arten von Handshake:
-
Hardware-Handshake (RTS/CTS): Hierbei wird ein zusätzliches Leitungs-Paar verwendet, um zu signalisieren, ob Daten gesendet werden können. RTS (Request to Send) wird vom Sender gesetzt, um zu signalisieren, dass Daten gesendet werden. CTS (Clear to Send) wird vom Empfänger gesetzt, um zu signalisieren, dass Daten empfangen werden können.
-
Software-Handshake (XON/XOFF): Hierbei wird ein spezielles Steuerzeichen verwendet, um zu signalisieren, ob Daten gesendet werden können. XON (ASCII 17) wird vom Empfänger gesendet, um zu signalisieren, dass Daten empfangen werden können. XOFF (ASCII 19) wird vom Empfänger gesendet, um zu signalisieren, dass keine Daten empfangen werden können.
Elektrische Spezifikationen
Der physikalische Layer der UART-Schnittstelle kann unterschiedlich spezifiziert sein:
- Spannung: 3.3V oder 5V
- Pegel: CMOS/TTL oder RS-232 (+3-15V für logische 0, -3-15V für logische 1)
RS232 ist ein älterer Standard, der heute nur noch selten verwendet wird. Die meisten modernen Mikrocontroller verwenden einen CMOS/TTL-Pegel, die mit 3.3V oder 5V arbeiten. Die Kommunikation mit einem Computer folgt dann meist über einen UART-zu-USB-Adapter. Hierfür gibt es spezielle ICs, die die Umwandlung von TTL-Pegeln zu USB übernehmen. Auf dem PC wird dann ein virtueller COM-Port erstellt, über den die Kommunikation erfolgt. Auf der MEGACARD wird z.B. ein FTDI-Chip verwendet (FT230XS).
U(S)ART beim ATmega16
Der ATmega16 verfügt über eine USART-Schnittstelle, wobei das S für synchronous steht. Im Unterschied zur Implemention einer reinen UART-Schnittstelle, kann die USART-Schnittstelle somit auch im synchronen Modus betrieben werden, d.h. es wird ein zusätzliches Taktsignal benötigt.

Register
- UBRR (USART Baud Rate Register) Besteht aus UBBRH und UBRRL
-
UCSRA (USART Control and Status Register A)
-
UCSRB (USART Control and Status Register B)
-
UCSRC (USART Control and Status Register C)
-
UDR (USART Data Register)
Modi
- Asynchronous normal mode: Asynchroner Betrieb
- Asynchronous double speed mode: Asynchroner Betrieb, doppelte Geschwindigkeit (d.h. doppelte Übertragungsrate)
- Synchronous master mode: Synchroner Betrieb, Master-Modus
Baudrate
Hinweis: Die Berechnung für die Baudrate wird hier nur für den asynchronous normal mode beschrieben. Die Modi asynchronous double speed mode mit doppelter Geschwindigkeit und sychronous master mode sind im Datenblatt des ATmega16 zu finden.*
Über die Register UBRRH und UBRRL wird die Baudrate eingestellt. Diese wird wie folgt berechnet:
Um also UBRR zu berechnen, kann die Formel umgestellt werden zu:
Im folgenden wird ein Beispiel für eine Baudrate von 9600 und einem Systemtakt von 12MHz durchgerechnet.
fOSC = 12 MHz (Systemtakt der CPU)
BAUD = 9600 (gewünschte Baudrate)
Folglich ist der Wert von UBRR:
Es wird der nächste ganzzahlige Wert verwendet, also 77. Die reale Baudrate beträgt somit:
Der Fehler der Baudrate berechnet sich mit der Formel:
In unserem Beispiel:
Mit diesem Wert kann nun UBRRH und UBRRL gesetzt werden wobei UBRRL die unteren 8 Bit und UBRRH die oberen 4 Bit enthält (UBBR ist ein 12 Bit Register).
Der Fehler der Baudrate soll maximal 2%, idealerweise unter 0.5% betragen.
Der GCC-Compiler bietet die Möglichkeit, die Baudrate direkt zu berechnen (mittels util/setbaud.h). Hierzu muss F_CPU gesetzt werden. Mittels BAUD wird die Baudrate festgelegt. Der Compiler berechnet dann den Wert für UBRR.
#define BAUD 9600UL // Baudrate, UL = unsigned long
#include <util/setbaud.h>
void uart_init(uint16_t baudrate) {
UBRRH = UBRRH_VALUE; // UBBRH_VALUE und UBRRL_VALUE werden vom Compiler berechnet
UBRRL = UBRRL_VALUE;
UCSRB = (1 << RXEN) | (1 << TXEN); // Enable receiver and transmitter
UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); // 8 data bits, 1 stop bit, no parity (8N1)
}
Bit-Erkennung im asynchronen Modus
Mithilfe des Startbit wird der Beginn der Übertragung eines neuen Zeichens eingeläutet. Das Startbit synchronisiert einen interner Timer, d.h. er wird zurückgesetzt. Dieser tastet nun (im normalen Mode) das Eingangssignal mit 16-facher Baudrate ab. Mittels einem majority voting (die Mehrheit gewinnt) der mittleren drei Taktzyklen wird erkannt, ob das jeweilige übertragene Bit eine "0" oder eine "1" ist. Sind z.B. 2 von 3 Taktzyklen "1", wird das Bit als "1" erkannt.

Bit-Definitionen
- UCSZ2:0 (UCSRC) - Character Size
- USBS (UCSRC) - Stop Bit Select
- UPM1:0 (UCSRC) - Parity Mode
- UMSEL (UCSRC) - USART Mode Select
Interrupts
Für die USART-Schnittstelle können 3 Interrupts aktiviert werden (Aktivierung über das UCSRB-Register):
- RXCIE (UCSRB) - USART, RX Complete Interrupt Enable
- TXCIE (UCSRB) - USART, TX Complete Interrupt Enable
- UDRIE (UCSRB) - USART Data Register Empty Interrupt Enable
Terminal-Programm
Die Kommunikation zum AVR kann z.B. über ein Terminal-Programm erfolgen. Es gibt eine Vielzahl unterschiedlicher Programme für die verschiedenen Betriebssysteme.
Ein Terminal-Programm für Windows ist z.B. PuTTY link, plattformunabhängig und sehr bedienerfreundlich ist z.B. CoolTerm link. Letzten Endes ist es jedoch egal, welches Terminal-Programm verwendet wird, da alle eine ähnliche Funktionalität bieten.
UART-Beispiele (MEGACARD)
Simple example to send a string via UART:
2.9.2 SPI
Allgemeines
Das Serial Peripheral Interface ist ein von Motorola in den 1980er entwickeltes serielles Kommunikationsprotokoll, das für die Kommunikation zwischen Mikrocontrollern und Peripheriegeräten verwendet wird. Es ist ein Master-Slave-Protokoll, bei dem ein Master mehrere Slaves steuern kann.
Ein empfehlenswertes Video zu den Grundlagen der SPI-Schnittstelle findet sich hier.
Anwendungsgebiete
Typische Vertreter von Chips mit SPI-Schnittstelle sind z.B. Sensoren, Displays, Speicherchips, etc.
Einige Beispiele sind hier mit Datenblätter verlinkt:
- 25LC256 - 256K SPI Bus Serial EEPROM
- BMP280 - Digital Pressure Sensor
- MC3008 - 8-Channel 10-Bit A/D Converters with SPI Serial Interface
- MCP4921/4922 - 12-Bit DAC with SPI™ Interface
- SSD1306 - 128 x 64 Dot Matrix OLED/PLED Segment/Common Driver with Controller
Leitungen
Die SPI-Schnittstelle besteht aus vier Leitungen:
- CS (Chip Select) - alternativ auch SS (Slave Select)
- SCK (Serial Clock) - alternativ auch SCLK
- MISO (Master In, Slave Out) alternativ auch SDO (Serial Data Out)
- MOSI (Master Out, Slave In) alternativ auch SDI (Serial Data In)
Modes
Es gibt vier verschiedene Modi, in denen die SPI-Schnittstelle betrieben werden kann. Diese unterscheiden sich in der Polarität und Phase des Taktsignals:
| CPOL | CPHA | SPI Mode |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 2 |
| 1 | 1 | 3 |

Adressierung
Die Adressierung erfolgt über das CS-Signal. Der Master aktiviert das CS-Signal des Slaves.
Werden mehrere Slaves verwendet, so kann man zur Einsparung von I/O-Pins am Mikrocontroller folgende Methoden einsetzen:
- Eine Daisy Chain verwendet werden (siehe unten)
- Einen Line Decoder (z.B. 3 to 8), um mehrere Slaves zu adressieren.
AVR Implementierung
Die folgende Grafik gibt eine Übersicht über die Implementierung der SPI-Schnittstelle beim ATmega16:

Die SPI-Schnittstelle wird über Register gesteuert:
SPCR (SPI Control Register)

SPSR (SPI Status Register)

Mit SPI2X kann die Übertragungsrate verdoppelt werden.
WCOL (Write Collision) wird gesetzt, wenn ein Schreibzugriff auf das SPDR-Register während einer laufenden Übertragung (Senden) erfolgt.
SPDR (SPI Data Register)
Das SPDR-Register wird zum Senden und Empfangen von Daten verwendet. Beim Senden wird das zu sendende Byte in das SPDR-Register geschrieben. Beim Empfangen wird das empfangene Byte aus dem SPDR-Register gelesen.

Achtung: CS muss manuell gesetzt werden, d.h. es gibt keine automatische Aktivierung des CS-Signals beim Senden als Master!
AVR Data Direction
Die Datenrichtung der SPI-Leitungen wird über das DDR-Register festgelegt, dabei ist folgende Tabelle zu beachten:

Daisy Chain
Eine Daisy Chain ist eine Verkettung von mehreren Slave-Geräten. Dabei wird das MISO-Signal des ersten Slaves mit dem MOSI-Signal des nächsten Slaves verbunden, und so weiter. Das MISO-Signal des letzten Slaves wird dann mit dem MISO-Signal des Masters verbunden. Das MOSI-Signal des Masters wird mit dem MOSI-Signal des ersten Slaves verbunden.

(c) Microchip
In einer Daisy Chain-Konfiguration wird das CS-Signal des Masters verwendet, um alle Slaves gleichzeitig zu aktivieren. Die Daten werden dann von einem Slave zum nächsten weitergereicht, bis sie den Master erreichen. Diese Konfiguration wird häufig verwendet, wenn mehrere Slaves in einer festen Reihenfolge kommunizieren müssen.
Ein Beispiel für eine Daisy Chain-Konfiguration ist die Verbindung von mehreren Schieberegistern, bei denen die Daten von einem Register zum nächsten weitergereicht werden, um eine größere Anzahl von Ausgängen zu steuern.
Wenn z.B. eine Daisy Chain aus drei Slaves besteht, wird das CS-Signal des Masters solange gehalten, bis alle drei Slaves die jeweils für sie bestimmten Befehle erhalten haben. Danach wird das CS-Signal dekativiert und die jeweiligen Slaves führen die Befehle aus. Möchte man von den jeweiligen Slaves Daten empfangen, so wird das CS-Signal wiederum aktiviert und die Daten werden von Slave zu Slave weiter bis zum Master gereicht. Dafür kann man z.B. ein NOP (No Operation) Befehl senden, um die Daten von Slave zu Slave weiterzureichen.
Beispiel
Per Teams zur Verfügung gestellt.
2.9.3 I2C
Allgemeines
Das Inter-Integrated Circuit-Protokoll (I2C) ist ein serielles Kommunikationsprotokoll, das von Philips (heute NXP) entwickelt wurde. Es wird häufig für die Kommunikation zwischen Mikrocontrollern und Peripheriegeräten verwendet. Es ist ein Master-Slave-Protokoll, bei dem ein Master mehrere Slaves steuern kann. Die Begriffe Master/Slave wurden in der aktuellen Version 7 des Standards durch die Begriffe Controller und Target ersetzt. In älteren Datenblättern und Dokumentationen werden Sie jedoch weiterhin die Begriffe Master und Slave vorfinden.
Die aktuelle (Stand 01/2025) Version des Standards kann hier (c) NXP eingesehen werden.
Ein empfehlenswertes Video zu den Grundlagen der I2C-Schnittstelle findet sich hier.
Eine Weiterentwicklung des I2C-Protokolls ist das System Management Bus (SMBus), das von Intel entwickelt wurde. Es basiert auf dem I2C-Protokoll und erweitert es um zusätzliche Funktionen wie z.B. eine CRC-Prüfung.
Seit 2017 gibt es einen auf I2C aufbauenden Standard namens I3C (I3C - Improved Inter-Integrated Circuit), der von der MIPI Alliance entwickelt wurde. I3C bietet zusätzliche Funktionen wie z.B. eine höhere Datenrate, eine verbesserte Adressierung und eine bessere Energieeffizienz.
Anwendungsgebiete
Die Anwendungsgebiete sind ähnlich wie bei SPI. Typische Vertreter von Chips mit I2C-Schnittstelle sind z.B. Sensoren, Displays, Speicherchips, etc..
Leitungen
Die I2C-Schnittstelle besteht aus zwei Leitungen:
- SDA (Serial Data Line)
- SCL (Serial Clock Line)
Controller (Master)
Der Controller (Master) ist für die Steuerung der Kommunikation auf dem I²C-Bus verantwortlich. Er initiiert die Kommunikation, erzeugt Start- und Stop-Bedingungen und gibt die Taktsignale (SCL) vor. Ein Controller kann mehrere Targets (Slaves) auf dem Bus ansprechen. Außerdem unterstützt der I²C-Bus mehrere Controller (Multi-controller), wobei in diesem Fall ein Verfahren zur Controller-Arbitration eingesetzt wird, um Konflikte zu vermeiden, wenn mehrere Controller gleichzeitig den Bus übernehmen wollen. Arbitration (dt. Entscheidung) ist ein Verfahren, bei dem der Controller mit der höchsten Priorität gewinnt und den Bus nutzen darf, die anderen Controller müssen ihre Kommunikation abwarten.
Modes
Es gibt mehrere verschiedene Modi, in denen die I2C-Schnittstelle betrieben werden kann:
Bidirectional bus:
- Standard Mode (Sm): up to 100 kbit/s
- Fast Mode (Fm): up to 400 kbit/s
- Fast-mode Plus (Fm+): up to 1 Mbit/s
- High Speed Mode (Hs): up to 3.4 Mbit/s
Unidirectional bus:
- Ultra Fast-mode (UFm): up to 5 Mbit/s
Datenrahmen
Ein Datenrahmen besteht aus folgenden Teilen:
- Start Condition: SDA von HIGH auf LOW, während SCL HIGH ist
- Address: 7-Bit-Adresse des Targets (Slave), gefolgt von einem Bit, das angibt, ob das Target schreiben oder lesen soll (RW, 0 = schreiben, 1 = lesen)
- Data: Ein oder mehrere (unlimitiert) Bytes (8 bit, MSB zuerst), gefolgt von einem ACK/NACK-Bit
- Stop Condition: SDA von LOW auf HIGH, während SCL HIGH ist


Bilder (c) NXP
Read/Write
Ein Target (Slave) kann nur Daten senden, wenn es vom Controller (Master) dazu aufgefordert wird. Der Controller sendet dazu eine Lese (Read)-Anfrage an das Target. Das Target antwortet dann mit den angeforderten Daten. Daraufhin bestätigt der Controller den Empfang der Daten mit einem ACK (Acknowledge) oder einem NACK (Not Acknowledge).

Bild (c) NXP
Adressierung
Die Adressierung erfolgt über 7-Bit-Adressen. Jedes Gerät auf dem I2C-Bus hat eine eindeutige 7-Bit-Adresse. Es gibt auch 10-Bit-Adressen, die für spezielle Geräte reserviert sind. Um doppelte Adressen zu vermeiden, haben viele ICs eine programmierbare Adresse, die durch Setzen von Pins oder durch Schreiben in ein Konfigurationsregister geändert werden kann. Es gibt jedoch IC's mit einer oder mehreren festen Adressen, die nicht geändert werden können.
ACK / NACK
Nach jedem Byte, das gesendet oder empfangen wird, sendet das empfangende Gerät ein ACK (Acknowledge) oder NACK (Not Acknowledge) zurück. Ein ACK bedeutet, dass das Byte korrekt empfangen wurde und das Gerät bereit ist, das nächste Byte zu empfangen. Ein NACK bedeutet, dass das Byte nicht korrekt empfangen wurde oder das Gerät nicht bereit ist, das nächste Byte zu empfangen.
Ablauf:
- Der Sender (Controller oder Target) überträgt ein 8-Bit-Datenbyte auf die SDA-Leitung, syncrhonisiert mit dem Taktsignal auf der SCL-Leitung.
- Nach den 8 Datenbits gibt der Empfänger (Target oder Controller, je nach Richtung) auf das neunte Bit (ACK-Bit) eine Rückmeldung:
- ACK: Der Empfänger zieht die SDA-Leitung während dem neunten Taktsignal auf LOW. Damit wird signalisiert, dass das Byte korrekt empfangen wurde und das Gerät bereit ist, das nächste Byte zu empfangen.
- NACK: Der Empfänger lässt die SDA-Leitung während des neunten Taktisgnals auf HIGH. Damit wird signalisiert, dass das Byte nicht korrekt empfangen wurde oder das Gerät nicht bereit ist, das nächste Byte zu empfangen (z.B. weil der Speicher voll ist).
- Der Sender kann nun das nächste Byte senden oder die Übertragung (Stop-Bedinggungssignal) beenden.
Logikpegel
Die Logikpegel sind < 30% der Betriebsspannung für LOW und > 70% der Betriebsspannung für HIGH.
Berechnung der Pull-up Widerstände
Die I2C-Schnittstelle verwendet Open-Drain- bzw. Open-Kollektor-Ausgänge, d.h. die Pegel der SDA- und SCL-Leitungen können nur auf LOW gezogen werden. Für den HIGH-Pegel sind Pull-up-Widerstände erforderlich. Die Größe der Pull-up-Widerstände hängt von der Kapazität der Leitungen und der gewünschten Taktfrequenz ab.
Die Widerstände sollten so dimensioniert sein, dass sie einen ausreichend schnellen Anstieg auf den HIGH-Pegel gewährleisten, ohne jedoch übermäßigen Stromfluss bei LOW-Pegeln zu verursachen. Dabei muss sichergestellt werden, dass die Spannung der Leitungen im Fehlerfall (z. B. Kurzschluss) nicht die maximal zulässige Eingangsspannung des Mikrocontrollers überschreitet.
Ablauf:
- Berechnung der maximalen Kapazität der Leitungen (Cb) in pF (Buskapazität, beinhaltet die Kapazität der der Pins der angeschlossenen Geräte und der Leiterbahnen/Leitungen)
- Wählen von trise (maximale Anstiegszeit) in ns (abhängig von der Taktfrequenz, z.B. 300ns für 100kHz Fast Mode)
- Berechnung des maximalen Pull-up-Widerstands (Rp)
- Berechnung des minimalen Pull-up-Widerstands (Rp)

tr ... maximale Anstiegszeit (ns) Cb ... Buskapazität (pF)
Die maximale Buskapazität (Cb) ist in den Datenblättern der Geräte angegeben. Laut Standard ist die maximale Kapazität 400pF (Standard Mode und Fast Mode) und 550pF (Fast-mode Plus und High Speed Mode).
Typische Werte für Rp(max) sind im Bereich von 1kΩ bis 10kΩ mit 4.7kΩ als Standardwert.

VDD ... Betriebsspannung (V)
VOL ... LOW-Pegel (V) (typisch 0.4V)
IOL ... LOW-Pegel-Strom (A) (typisch 3mA für Standard-mode)
Rechenbeispiel:
Berechnen Sie den minimalen und maximalen Pull-up-Widerstand für eine Schaltung mit folgenden Parametern:
Cb = 200 pF
VDD = 3.3 V
IOL = 3 mA
VOL = 0.4 V
Clock-Stretching
Clock-Stretching ist ein Verfahren, bei dem das Target (Slave) den Takt verlangsamen kann, um dem Slave mehr Zeit zum Verarbeiten der Daten zu geben. Dies kann z.B. erforderlich sein, wenn das Target noch nicht bereit ist, Daten zu senden oder zu empfangen.
Ablauf:
- Der Controller generiert das Taktsignal (SCL).
- Das Target zieht SCL auf LOW, um den Controller zu verlangsamen.
- Der Controller wartet, bis SCL wieder auf HIGH gezogen wird und setzt die Übertragung dann fort.

(c) Microchip
Ein Beispiel für Clock Streching kann etwa ein Speichchip sein, der noch nicht bereit ist, Daten zu senden oder zu empfangen. Der Speicherchip kann dann den Takt verlangsamen um mehr Zeit zu haben, die Daten zu verarbeiten. Clock-Stretching wird nicht von allen I2C Chips unterstützt.
Takt-Synchronisierung
Multi-Master-Betrieb
Der I2C-Bus unterstützt den Multi-Master-Betrieb, d.h. mehrere Controller können den Bus gleichzeitig nutzen. Um Konflikte zu vermeiden, wird ein Verfahren zur Controller-Arbitration eingesetzt. Dabei wird der Controller mit der höchsten Priorität den Bus nutzen dürfen, die anderen Controller müssen ihre Kommunikation abwarten.
Ablauf:
Wenn zwei Master gleichzeitig Nachrichten übertragen, geschieht dies bitweise. Beide Master übertragen ihre Adressbits auf den Bus, beginnend mit dem höchstwertigen Bit (MSB). Wenn die Bits gleich sind, setzt sich die Arbitration fort. Überträgt jedoch ein Master eine '1' und der andere eine '0', bleibt der Bus auf '0' (da die I2C-Leitungen Open-Drain sind). Der Master, der '1' überträgt, erkennt den Unterschied, stellt fest, dass ein anderer Master ebenfalls sendet, und hört sofort auf zu senden, um zum Slave zu werden. Dies bedeutet wiederum, dass die niedrigste Adresse die höchste Priorität hat.
AVR Implementierung
Beim AVR ist die I2C-Schnittstelle aus markenschutzrechtlichen Gründen als TWI (Two-Wire Interface) implementiert.
Allgemeines
Das TWI entspricht elektrisch den Spezifikationen des I2C-Busses. Es unterstützt Geschwindigkeiten bis zu 400 kHz, kann sowohl als Controller als auch als Target betrieben werden und unterstützt Multi-Master-Betrieb.
Blockschaltbild

Register
Details zu den Registern entnehmen Sie bitte dem Datenblatt, hier ist nur eine allgemeine Übersicht wiedergegeben.
- TWBR (TWI Bit Rate Register)
Mit diesem Register in Kombination mit den Prescaler Bits (TWPS0 und TWPS1 im TWI Status Register) wird die Bit Rate des TWI-Busses eingestellt. Die zwei TWPS Bits können 4 Kombinationen annehmen sodass die TWPS in der Formel unten die Werten 0-3 annehmen kann, entsprechend Prescaler Werten von 1, 4, 16 und 64.
Die Formel lautet:

Nach Umstellen der Formel ergibt sich zur Berechnung von TWBR:

Unter der Annahme, dass TWPS0 und TWPS1 auf 0 gesetzt sind, ergibt sich folgende Formel zu Berechnung von TWBR:

Mit letzter Formel kann bei der MEGACARD TWBR für 100kHz bzw. 400kHz exakt berechnet werden.
- TWSR (TWI Status Register)
Das TWI Status Register enthält Informationen über den Status des TWI-Busses, z.B. ob eine Übertragung erfolgreich war oder ob ein Fehler aufgetreten ist.
- TWCR (TWI Control Register)
Das TWI Control Register wird verwendet, um den TWI-Bus zu steuern, z.B. um eine Übertragung zu starten oder zu stoppen.
- TWDR (TWI Data Register)
Das TWI Data Register enthält die Daten, die über den TWI-Bus gesendet oder empfangen werden. Daten werden in dieses Register geschrieben, bevor sie gesendet werden, und aus diesem Register gelesen, nachdem sie empfangen wurden. Auch die Adresse des Targets (Slave) wird vor der Übertragung in dieses Register geschrieben.
- TWAR (TWI Address Register)
Mittels TWI Address Register wird Adresse des anzusprechenden Targets (Slaves) festgelegt.
Ablauf einer Übertragung (Controller/Master)
Im Datenblatt des Mikrocontrollers ist ein Ablaufdiagramm zu finden, das den Ablauf einer Übertragung auf dem TWI-Bus zeigt. Hier ist ein allgemeiner Ablauf dargestellt:

Zudem ist ein Code-Beispiel zu finden, welches hier wiedergegeben wird. Die Initialisierung (z.B. Festlegen der SCL Frequenz) ist dabei nicht enthalten sondern nur das Senden des eigentlichen Dataframes.

2.9.4 USB
Noch nicht bearbeitet.
2.9.5 CAN
Noch nicht bearbeitet.
2.9.6 Weitere Bussysteme
Noch nicht bearbeitet.