Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
Beide Seiten der vorigen Revision Vorhergehende Überarbeitung Nächste Überarbeitung | Vorhergehende Überarbeitung | ||
microcontrollertechnik:11_i2c_schnittstelle [2023/11/19 02:34] mexleadmin |
microcontrollertechnik:11_i2c_schnittstelle [2024/08/29 19:37] (aktuell) mexleadmin |
||
---|---|---|---|
Zeile 1: | Zeile 1: | ||
- | ====== | + | ====== |
<WRAP group> | <WRAP group> | ||
<WRAP column 30%> | <WRAP column 30%> | ||
Zeile 8: | Zeile 8: | ||
- wissen wie die Kommunikation zwischen I2C Master und Slave funktioniert | - wissen wie die Kommunikation zwischen I2C Master und Slave funktioniert | ||
+ | |||
+ | Im Video wird eine Library für die Kommunikation verwendet. Wir werden in untenstehenden Beispiel die Register selbst schreiben. | ||
</ | </ | ||
==== Video ==== | ==== Video ==== | ||
+ | {{youtube> | ||
+ | |||
+ | <WRAP hide> | ||
{{youtube> | {{youtube> | ||
+ | </ | ||
</ | </ | ||
- | |||
==== Statemachine für Datenpaket ==== | ==== Statemachine für Datenpaket ==== | ||
Zeile 37: | Zeile 42: | ||
</ | </ | ||
- | **Übertragung**\\ | + | === Übertragung |
Für die I2C Übertragung " | Für die I2C Übertragung " | ||
D.h. während der Datenübertragung bleibt die Datenleitung bei SCL=High konstant. \\ | D.h. während der Datenübertragung bleibt die Datenleitung bei SCL=High konstant. \\ | ||
Zeile 149: | Zeile 154: | ||
===== Software ===== | ===== Software ===== | ||
- | ==== einfache Anwendung ==== | + | ==== einfache Anwendung |
Im ersten Schritt ist im folgenden eine einfache Anwendung dargestellt. \\ | Im ersten Schritt ist im folgenden eine einfache Anwendung dargestellt. \\ | ||
Zeile 177: | Zeile 182: | ||
--> III. Code in Microchip Studio # | --> III. Code in Microchip Studio # | ||
- | === TWI Master | + | <fs x-large> |
<WRAP group>< | <WRAP group>< | ||
Zeile 195: | Zeile 200: | ||
| | ||
| | ||
- | | + | |
C-Compiler: AVR/GNU C Compiler 5.4.0 | C-Compiler: AVR/GNU C Compiler 5.4.0 | ||
| | ||
Zeile 251: | Zeile 256: | ||
I2C_transmitDataOrAddress(TWI_Data); | I2C_transmitDataOrAddress(TWI_Data); | ||
I2C_transmitStop(); | I2C_transmitStop(); | ||
- | // | + | _delay_us(1); |
} | } | ||
} | } | ||
Zeile 295: | Zeile 300: | ||
</ | </ | ||
</ | </ | ||
- | \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ | + | \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ |
'' | '' | ||
\\ \\ | \\ \\ | ||
- Hier wird die Frequenz des Quarz direkt eingestellt. | - Hier wird die Frequenz des Quarz direkt eingestellt. | ||
- Weiterhin wird eine Konstante für die I2C Frequenz definiert \\ \\ | - Weiterhin wird eine Konstante für die I2C Frequenz definiert \\ \\ | ||
- | - Die Header-Dateien und die Bit-ändernden Makros entsprechen denen der letzten Programme. \\ \\ \\ | + | - Die Header-Dateien und die Bit-ändernden Makros entsprechen denen der letzten Programme. |
- Die weiteren Konstanten sind: | - Die weiteren Konstanten sind: | ||
- | - Kostante | + | - Konstante |
- | - Kostante | + | - Konstante |
- Konstante für die I2C Adresse | - Konstante für die I2C Adresse | ||
- | - Zwei globale Variablen beinhalten die I2C Adresse und die Daten | + | - Zwei globale Variablen beinhalten die I2C Adresse und die Daten \\ \\ |
'' | '' | ||
- | - es wird zunächst die Pull-up Widerstände aktiviert, um die Schalter einlesen zu können | + | - es werden |
- in der Haupschleife läuft: | - in der Haupschleife läuft: | ||
- Zu Beginn eine Iitialisierung der I2C Schnittstelle. Die wiederholte Initialisierung vermeidet Probleme der I2C Zustandsmaschine. | - Zu Beginn eine Iitialisierung der I2C Schnittstelle. Die wiederholte Initialisierung vermeidet Probleme der I2C Zustandsmaschine. | ||
Zeile 316: | Zeile 321: | ||
- Nun wird der Zustand das Port B als I2C Daten eingelesen. | - Nun wird der Zustand das Port B als I2C Daten eingelesen. | ||
- Diese werden per I2C übertragen. | - Diese werden per I2C übertragen. | ||
- | - Und zum Schluss wird das Stopp Bit gesendet | + | - Und zum Schluss wird das Stopp Bit gesendet |
'' | '' | ||
- | - im Statusregister werden die Bits '' | + | - Durch das Zurücksetzen der Bits '' |
- | - Der Überlauf-Interrupt durch den Timer2 wird erst bei Überlauf des 8-Bit Wert ausgeführt. Auch hier ergibt sich durch den Prescaler | + | |
- Auch das Kontrollregister wird zurückgesetzt | - Auch das Kontrollregister wird zurückgesetzt | ||
- | - im Bitraten Register wird die I2C Frequenz eingestellt | + | - im Bitraten Register wird die I2C Frequenz eingestellt \\ \\ \\ \\ |
'' | '' | ||
- | \\ \\ \\ | ||
- Es soll die I2C Schnittstelle aktiviert ('' | - Es soll die I2C Schnittstelle aktiviert ('' | ||
- | - Nach dem Ändern des Konrollregisters muss die Abarbeitung abgewartet werden. Dies ist daran zu erkennen, das '' | + | - Nach dem Ändern des Konrollregisters muss die Abarbeitung abgewartet werden. Dies ist daran zu erkennen, das '' |
'' | '' | ||
- Bevor Daten übertragen werden sollen, müssen diese erst in das I2C Datenregister geschrieben werden. | - Bevor Daten übertragen werden sollen, müssen diese erst in das I2C Datenregister geschrieben werden. | ||
- Wieder die I2C Schnittstelle aktivieren ('' | - Wieder die I2C Schnittstelle aktivieren ('' | ||
- | - auch hier muss wieder die Abarbeitung abgewartet werden | + | - auch hier muss wieder die Abarbeitung abgewartet werden \\ \\ \\ |
- | + | ||
- | \\ \\ \\ \\ \\ \\ | + | |
'' | '' | ||
- Das Stoppbit wird wieder im Kontrollregister aktiviert | - Das Stoppbit wird wieder im Kontrollregister aktiviert | ||
Zeile 341: | Zeile 340: | ||
</ | </ | ||
- | === TWI Slave === | + | <fs x-large> |
<WRAP group>< | <WRAP group>< | ||
/* ---------------------------------------------------------------------------- | /* ---------------------------------------------------------------------------- | ||
- | + | | |
| | ||
| | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | |||
+ | | ||
- | Dateiname : I2C_SimpleMaster.c | + | Displayanzeige : keine |
- | Autoren | + | Tastenfunktion : Die Tastenstellung der Dip-Schalter an Port B werden als Wert über I2C weitergegeben. |
+ | Dabei zählt ein gedrückter Schalter | ||
- | Datum | + | Jumperstellung : |
- | + | ||
- | | + | |
- | + | ||
- | | + | |
- | + | ||
- | | + | |
- | C-Compiler: AVR/GNU C Compiler 5.4.0 | + | |
- | + | ||
- | | + | |
+ | Fuses im uC : keine | ||
| | ||
+ | |||
// ----------------------------------------------------------------------------*/ | // ----------------------------------------------------------------------------*/ | ||
- | + | | |
// Deklarationen ============================================================== | // Deklarationen ============================================================== | ||
- | + | | |
// Festlegung der Quarzfrequenz | // Festlegung der Quarzfrequenz | ||
- | #define F_CPU 16000000UL | + | #define F_CPU 8000000UL // |
- | #define F_SCL 10000L | + | #define F_SCL 100000L // Baudrate von 100 kHz |
+ | |||
// Include von Header-Dateien | // Include von Header-Dateien | ||
#include < | #include < | ||
+ | |||
// Konstanten | // Konstanten | ||
- | # | + | #define SET_BIT(BYTE, |
- | #define CLR_BIT(BYTE, | + | #define CLR_BIT(BYTE, |
- | #define TGL_BIT(BYTE, | + | #define TGL_BIT(BYTE, |
+ | #define SET_ALL_TO_OUT (0xFF) // | ||
+ | #define TWI_ADRESS (0b0001010) // | ||
+ | #define TWI_ADRESS_MASK (0b0001010) // | ||
+ | |||
// | // | ||
void I2C_Init(); | void I2C_Init(); | ||
void I2C_setAddress(char Address); | void I2C_setAddress(char Address); | ||
char I2C_readData(); | char I2C_readData(); | ||
- | + | ||
- | uint8_t TWI_Address = | + | uint8_t TWI_Address |
- | uint8_t TWI_AddressMask = 0b11111110; | + | uint8_t TWI_AddressMask |
+ | |||
int main(void) | int main(void) | ||
{ | { | ||
- | DDRD= 0xFF; // Auf DDRC die Daten ausgeben | + | DDRB= SET_ALL_TO_OUT; // Auf DDRC die Daten ausgeben |
- | I2C_setAddress(TWI_Address); | + | I2C_setAddress(TWI_Address); |
- | + | | |
while (1) | while (1) | ||
{ | { | ||
- | PORTD | + | PORTB = I2C_readData(); |
} | } | ||
} | } | ||
+ | |||
////////////////////////////////////////////////// | ////////////////////////////////////////////////// | ||
// Setzen der I2C Adresse auf die der Slave hört | // Setzen der I2C Adresse auf die der Slave hört | ||
////////////////////////////////////////////////// | ////////////////////////////////////////////////// | ||
- | void I2C_setAddress(char Address) | + | void I2C_setAddress(char Address) |
{ | { | ||
- | TWAR = (Address<< | + | |
- | TWAMR= TWI_AddressMask; | + | TWAMR= TWI_AddressMask; |
- | TWCR = (1<< | + | TWCR = (1<< |
} | } | ||
+ | |||
////////////////////////////////////////////////// | ////////////////////////////////////////////////// | ||
// Auslesen der übermittelten Daten | // Auslesen der übermittelten Daten | ||
////////////////////////////////////////////////// | ////////////////////////////////////////////////// | ||
- | char I2C_readData() | + | char I2C_readData() |
{ | { | ||
- | while (!(TWCR & (1<< | + | |
- | return TWDR; // übermittle Daten | + | return TWDR; // übermittle Daten |
} | } | ||
- | |||
</ | </ | ||
</ | </ | ||
- | \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ | + | \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ \\ |
'' | '' | ||
\\ \\ | \\ \\ | ||
- Hier wird die Frequenz des Quarz direkt eingestellt. | - Hier wird die Frequenz des Quarz direkt eingestellt. | ||
- | - Weiterhin wird eine Konstante für die I2C Frequenz definiert | + | - Weiterhin wird eine Konstante für die I2C Frequenz definiert \\ \\ |
- | - Die Header-Dateien und die Bit-ändernden Makros entsprechen denen der letzten Programme. | + | - Die Header-Dateien und die Bit-ändernden Makros entsprechen denen der letzten Programme. \\ \\ \\ \\ |
- Die weiteren Konstanten sind: | - Die weiteren Konstanten sind: | ||
- | - Kostante | + | - Konstante |
- | - Kostante | + | - Konstante |
- | - Konstante für die I2C Adresse | + | - Konstante für die Maskierung der Adresse \\ \\ \\ \\ \\ |
- | - Zwei globale Variablen beinhalten die I2C Adresse und die Daten | + | - Zwei globale Variablen beinhalten die I2C Adresse und die Maske für die eingelesene Adresse \\ \\ |
'' | '' | ||
- | - es wird zunächst die Pull-up Widerstände aktiviert, um die Schalter einlesen zu können | + | - Es werden alle Pins an Port B als Ausgang geschalten |
- | - in der Haupschleife läuft: | + | - Die I2C Adresse, |
- | - Zu Beginn eine Iitialisierung der I2C Schnittstelle. | + | - In der Haupschleife läuft nur das Setzen des Port B anhand der eingelesenen |
- | - Als nächstes wird die startende Flanke gesendet. | + | |
- | - Das erste Byte auf dem I2C Bus ist die Adressebyte. Dieses setzt sich aus der Adresse | + | |
- | - Nun wird der Zustand | + | |
- | - Diese werden per I2C übertragen. | + | |
- | - Und zum Schluss wird das Stopp Bit gesendet | + | |
- | '' | + | '' |
- | - im Statusregister werden die Bits '' | + | - Die Adresse |
- | - Der Überlauf-Interrupt durch den Timer2 | + | - Die Adressmaske |
- | - Auch das Kontrollregister | + | - Im Kontrollregister wird die " |
- | - im Bitraten Register | + | '' |
- | '' | + | - Hier wird solange gewartet, bis I2C Daten vorliegen |
- | \\ \\ \\ | + | - Nach dem Ändern des Konrollregisters muss die Abarbeitung abgewartet werden. Dies ist daran zu erkennen, |
- | - Es soll die I2C Schnittstelle | + | |
- | - Nach dem Ändern des Konrollregisters muss die Abarbeitung abgewartet | + | |
- | + | ||
- | '' | + | |
- | - Bevor Daten übertragen werden sollen, müssen diese erst in das I2C Datenregister geschrieben werden. | + | |
- | - Wieder | + | |
- | - auch hier muss wieder die Abarbeitung abgewartet werden | + | |
- | + | ||
- | \\ \\ \\ \\ \\ \\ | + | |
- | + | ||
- | '' | + | |
- | - Das Stoppbit | + | |
- | - Hier ist kein Warten notwendig | + | |
</ | </ | ||
Zeile 472: | Zeile 463: | ||
- | ==== komplexere Anwendung ==== | + | ==== komplexere Anwendung |
- | Als Beispiel wurde die Temperaturmessung gewählt | + | |
- | | + | Als Beispiel wurde hier die Temperaturmessung |
+ | Das Projekt und die Simulation ist hier zu finden | ||
+ | |||
+ | Bitte nutzen Sie diese als Vorlage, wen Sie eine I2C Schnittstelle implementieren wollen. Da in diesem Programmstand alles über Interrupts läuft, können auch weitere Funktionen abgearbeitet werden. | ||
+ | |||
+ | ===== weiterführende Unterlagen ===== | ||
+ | |||
+ | Die detaillierte Beschreibung zu I2C findet sich in des {{microcontrollertechnik: | ||
==== Bibliotheken ==== | ==== Bibliotheken ==== | ||
Zeile 486: | Zeile 484: | ||
* alternative und schlanke Implementierung des Slaves von [[https:// | * alternative und schlanke Implementierung des Slaves von [[https:// | ||
- | ===== Beispiele | + | ==== Beispiele ==== |
- | * Simulide: '' | + | * In Simulide |
- | * Software | + | * Eine vollständige Implementierung des Codes für den I2C Master ist in der Library von Peter Fleury |
- | * Library von Peter Fleury: [[http:// | + | * Eine Implementierung eines [[Software I2C Slave]], also eines I2C an einem beliebigen Pin durch Bitmaipulation, |
- | * [[Software I2C Slave]] | + | |
- | ===== weiterführende Unterlagen ===== | + | ==== Beschreibung |
- | | + | |
+ | Die " |