TWI / I²C

I²C ist ein serieller Datenbus für eingebettete Systeme und wurde von Philips Semiconductors in den 1980er Jahren entwickelt.

Beim I²C Bus handelt es sich um einen synchronen seriellen Zweidraht-Bus für kleine Entfernungen (z.B. innerhalb eines Gerätes). Er verfügt über eine Leitung für Daten und eine Taktleitung. I²C steht für IIC = Inter IC Bus. Aus Lizenzgründen heißt der I²C Bus bei Atmel Controllern TWI (two wire interface).

In einem I²C-Bus gibt es mindestens einen Baustein der als I²C-Master fungiert und im einfachsten Fall nicht mehr als 128 I²C-Slaves. Bei den meisten Anwendungsfällen arbeitet der Mikrocontroller als Master und die externen Bausteine wie EEPROM, Sensoren, RTC, usw. sind die Slaves.

Das PEC-Framework stellt für den I²C-Bus zunächst abstrakte Interfaces bereit. Diese unterscheiden den I²C-Bus und das I²C-Device. Der Bus repräsentiert den Master und wird als Low Level Treiber für den oder die I²C Bausteine im verwendeten Mikrocontroller in den spezifischen Bibliotheken realisiert.

Die Devices setzen auf dem Low Level Treiber auf und realisieren die I²C Protokolle der entsprechenden Bausteine. Als Beispiel soll hier ein I²C-Temperatursensor LM75 verwendet werden.

Bei Verwendung der I²C-Klassen wird in der PEC automatisch ein I²C-Bus instanziiert. Da es beim AVR auch immer nur einen TWI Baustein gibt, braucht sich der Anwendungsentwickler um nichts weiter zu kümmern, als sich eine Instanz der gewünschten Klasse zu erzeugen und diese zu benutzen.

Bevor Sie beginnen, benötigen Sie ein neues Klassendiagramm. Dazu müssen Sie zurück in die oberste Ebene gehen (rechte Maustaste / nach oben oder einfach Taste ESC). Dort legen Sie ein neues Klassendiagramm an. Zur Erinnerung:

Die Beispielanwendung soll die aktuelle Temperatur vom Temperatursensor in Grad Celsius auslesen und per UART an den PC senden. Den Temperatursensor schließen wir als AddOn an das myAVR Board an.

Beachten Sie, dass die Adress-Jumper alle auf „0“ stehen und damit die Standard-Basis-Adresse 0x90 für den LM75 verwendet wird. Sollten Sie weitere LM75 im Bus verwenden, müssen diese mit ihrer konkreten Adresse an den Bus angemeldet werden. Für die korrekte Funktion des I²C-Bus müssen die Busleitungen mit Pull-Up-Widerständen nach High gezogen werden.

Gehen Sie wie folgt vor:

  1. ggf. ein Projekt und ein neues Klassendiagramm für PEC Anwendungen erstellen
  2. eine eigene Klasse Konsole anlegen
  3. die Klasse Konsole in der Klasse Controller aggregieren
  4. das Template PecUart an die Klasse Konsole binden
  5. ein Template für die gewünschte Baudrate an die Klasse Konsole binden
  6. das Hardware-Resource-Template uart0_avr an die Klasse Konsole binden
  7. eine eigene Klasse SensorBus anlegen
  8. die Klasse SensorBus in der Klasse Controller aggregieren
  9. das Template PecI2cBus an die Klasse SensorBus binden
  10. das Hardware-Resource-Template i2c0_avr an die Klasse SensorBus binden
  11. eine eigene Klasse TemperaturSensor anlegen
  12. die Klasse TemperaturSensor in der Klasse Controller aggregieren
  13. das Template PecLM75 an die Klasse TemperaturSensor binden

Die so vorbereitete Systemstruktur muss jetzt nur noch mit dem gewünschten Verhalten ergänzt werden.

Controller::onStart

  // das I2CDevice mit Adresse am I2C Bus anmelden
  sensorBus.connect(temperaturSensor,0x90);

Controller::onWork

  uint8_t temperatur;
  temperatur=temperaturSensor.getTemp();
  konsole.writeByte(temperatur);
  waitMs(100);

Wenn Sie die Zeile richtig eingegeben und das Modell korrekt erstellt haben, können Sie aus dem Klassendiagramm, wie gehabt, den Quellcode generieren, diesen übersetzen und auf den Controller übertragen. Das erfolgt über das Aktionsmenü in der Objektbibliothek. Wählen Sie dort den Menüpunkt Erstellen, Brennen & Ausführen.

Das Testen der Anwendung erfolgt mit dem SiSy-Controlcenter. Beachten Sie, dass die Einstellungen für die Kommunikationsschnittstelle korrekt sind. Durch Berühren sollte sich die Temperatur des Sensors um einige Grad ändern lassen.

Als nächster Schritt soll ein weiterer Temperatursensor an den Bus angeschlossen werden. Dazu ist es nötig, diesem eine andere Adresse zuzuweisen. Beachten Sie auch, dass möglichst nur einmal die PullUp-Widerstände zugeschaltet sind.

Im Klassendiagramm wird die Anzahl der Temperatursenoren auf zwei festgelegt. Um das zu erreichen, definieren Sie bei der Aggregation der Klasse TemperaturSensor die Multiplizität 2 für das Attribut +temperaturSensor.

Jetzt muss der Quellcode entsprechend angepasst werden. Der Codegenerator setzt die Multiplizität in ein Array der festgelegten Größe um. Das muss beim Ansprechen der Sensoren jetzt beachtet werden. Zusätzlich muss sichergestellt werden, dass die Sensoren unterschiedlich adressiert sind. Ändern bzw. ergänzen Sie die Quellcodes wie folgt:

Controller::onStart

  // vgl. Datenblatt des LM75
  // Sensoren mit unterschiedlichen Adressen am Bus anmelden
  sensorBus.connect(temperaturSensor[0],0x90);
  sensorBus.connect(temperaturSensor[1],0x9E);

Controller::onWork

  uint8_t temperatur;
  temperatur=temperaturSensor[0].getTemp();
  konsole.writeByte(temperatur);
  temperatur=temperaturSensor[1].getTemp();
  konsole.writeByte(temperatur);
  waitMs(100);

Zur Visualisierung sollte die Oszi-Ansicht des Controlcenters auf Punkte umgestellt werden. Tipp: Damit der zweite Sensor auch eine deutlich andere Temperatur hat, kann man diesen im Kühlschrank abkühlen ;-)

Videozusammenfassung

Und hier diesen Abschnitt als kurze Videozusammenfassung.

ACHTUNG VERALTETES VIDEO, WIRD DEMNÄCHST AKTUALISIERT

Nächstes Thema

  • SDCard (nur über eine SiSy-Lizenz verfügbar)
  • i2c.txt
  • Zuletzt geändert: 2022/02/15 13:54
  • von huwi