Einen weiteren nützlichen Baustein am I²C-Bus (TWI) stellen Port-Expander dar. Wer schon einmal unter "chronischem Pinmangel" in einer seiner Applikationen gelitten hat, weiß was ich meine.

Meine Wahl ist hier auf den PCF8574 gefallen, einen 8-Bit I/O Expander. Auch in diesem Abschnitt gilt analog zu den anderen über I²C-Bausteine: Falls ihr noch nie etwas mit dem TWI gemacht habt, dann lest euch bitte zuerst die entsprechende Rubrik durch. Danach wird das Verstehen wesentlich einfacher fallen.

Die Funktionsweise ist schnell beschrieben: Ein seriell an den Baustein gesendeter Wert wird auf dessen Pins parallel ausgegeben. Es gibt drei Adresspins (A0:2), an welchen man die Adresse in Hardware einstellen kann (Pins jeweils auf Masse bzw. Vcc legen). Es können also maximal 2^3 = 8 Bausteine direkt am Bus betrieben werden. Eine Kaskadierung sollte jedoch möglich sein.

An den Pins P0:7 kann ein 8 Bit Wert ausgegeben bzw. eingelesen werden. SDA und SCL dienen der Kommunikation über den I²C-Bus. /INT dient dazu, eingehende Daten an den Pins des Bausteins zu signalisieren. Man kann diesen Pin direkt an einen der Pins (externe Interrupts: INT0, INT1) des MC legen. Da der Expander mit einem Open-Drain Ausgang daher kommt, empfiehlt es sich einen Pull-Up gegen Betriebsspannung zu schalten. So kann der Slave dem Master Signale ohne den Umweg über den I²C übermitteln. Man kann ihn natürlich auch einfach offen lassen. Die Pins P0:7 können bis zu 20mA aufnehmen bzw. bis zu 25mA treiben. Der gesamt abgegebene/aufgenommene Strom sollte 100mA nicht überschreiten.

Gestartet wird die Kommunikation durch das Senden der Start-Bedingung gefolgt vom Adressbyte.

Das Adressbyte:

 0    1    0    0    A2    A1    A0    0  

Dem Adressbyte folgt das obligatorische R/W-Bit, welches festlegt, ob ein Lese- oder Schreibzugriff ausgeführt werden soll (R/W=0 Schreiben, R/W=1 Lesen).

Wurde ein ACK empfangen, d.h. hat sich ein Slave angesprochen gefühlt, so kann man nun ein Datenbyte senden (R/W=0) oder den Status der Eingänge einlesen (R/W=1), also ein Datenbyte empfangen. Wurde ein Byte gesendet, so bestätigt der Baustein dieses mit ACK. Der Anwender kann nun festlegen, ob er das nächste Byte senden möchte oder ein STOP senden. Wurde ein Byte gelesen, so hat der Master dieses per ACK zu bestätigen, so er denn gleich das nächste empfangen möchte. Ansonsten kann hier das ACK entfallen und ein STOP gesendet werden.

Stellt sich nur noch die Frage, wie regelt man nun, ob ein Pin als Ein- oder Ausgang arbeiten soll. Soviel gleich vorweg: So etwas wie die Datenrichtungsregister des AVRs gibt es hier nicht, man muss ohne sie auskommen.
Den Ausgangspegel der Pins definiert man über einen Schreibzugriff. Sendet man beispielsweise nach der Adresse gefolgt vom ACK des Bausteins 0xF0, so bedeutet das, dass P0:3 nun L-Pegel haben und P4:7 H-Pegel.
Will man den Zustand der Eingänge wissen, so wird empfohlen, die entsprechenden Eingänge zunächst auf H-Pegel zu setzen. Führt man nun einen Lesezugriff durch, so stehen im gelesenen Byte die Pegel der Pins.

Routinen zum Ansteuern des Baustein können hier herunter geladen oder alternativ über die Rubrik Programme bezogen werden.

Anwendung soll ein solcher Expander bei mir natürlich auch finden. Am meisten hat mich beim Anschluss von LCDs immer deren Pin-Hunger im 4-Bit-Modus gestört. Samt der Steuereingänge kostet einen das 7 Pins. Da ein LCD selten viel zu tun hat, sollte die Verwendung eines solchen Bausteines kein Problem darstellen. Um nicht wieder bei Null anzufangen, werde ich einfach die oben erwähnten Low-Level-Routinen in die vielfach bewährte LCD-Bibliothek von Peter Pfleury einbinden. Allerdings hat dieses kleine Projekt momentan noch den Status ToDo.

 

Zurück zur Startseite.