Tastaturabfrage mit dem I/O-Expander

Mit Hilfe des PCF8574 I/O-Expanders können sie Daten ausgeben und die Zustände „Low“ und „High“ an den Pins einlesen. Das Einlesen der Daten erfolgt, indem zur I²C-Bus Adresse + „Read“ gesetzt wird.

Erstellen sie das Projekt aus Tabelle 46, das den Zustand der Tasten S9 bis S16 ein­liest und das Er­geb­nis an Port 2 ausgibt. Wird eine Taste gedrückt, soll die entspre­chen­de LED dazu ausgehen.

Stellen sie mit den Steckbrücken eine Ver­bin­dungen zwischen XTa0-7 mit XP4D0-7 her.

F !! Vergessen sie nicht die Jumper J14 bis J20 zu entfernen, da sonst die LCD mit am Port des I/O-Expanders hängt und sich somit undefinierte Ergebnisse ergeben. !!

Um die Portpins am PCF8574 be­schrei­ben und auslesen zu kön­nen, sollen die Funk­tio­nen „v_PCF8574WriteVal()“ und „v_PCF8574ReadVal()“ im Sourcemodul PCF8574-_LIB.c erstellt werden (siehe Listing 39).

In der Funktion „main()“ wird zuerst die Initialisierung des I²C-Busses (siehe Listing 40, ), die Freigabe des Interrupts (siehe ) und die Konfiguration des Port 2 durchgeführt (sie­he ƒ). Da die Ports am PCF8574 als Eingänge arbeiten sollen, müssen die Portpins noch mit einer „1“ beschrieben werden (siehe ). In der while-Schleife wird nun kon­ti­nu­ierlich der Port des PCF8574 ausgelesen (siehe ), und das Ergebnis an Port 2 aus­ge­ge­ben (siehe ).

Projektname

Verzeichnis

Verwendete Sourcemodule

Test_IOExp_Lib

Test_PCF8574_Lib

TestIOExp_Lib.c

 

..\Library

PCF8574_LIB.c, I2C_LIB.c, PortConfig.c

Tabelle 46  Projekt Test_IOExp_Lib

 

 

// Funktionsdeklarationen

void v_PCF8574WriteVal(unsigned char ucVal);

void v_PCF8574ReadVal(void);

Listing 38  Inhalt von PCF8574_LIB.h

 

 

#include <I2C_LIB.H>

#include <PCF8574_Lib.h>

 

void v_PCF8574WriteVal(unsigned char ucVal)

{

  Slave.Adr = 0x40;      // Adresse PCF8574 + WR

  v_SetNextI2CVal(ucVal); //ein Byte wird geschrieben

  v_StartI2CandWait();  

}

 

void v_PCF8574ReadVal(void)

{

  Slave.Adr = 0x40 + 1; // Adresse PCF8574 + RD

  Slave.DataLen = 1;    // ein Bytes wird gelesen

  v_StartI2CandWait();

}

Listing 39  Inhalt von PCF8574_LIB.c

 

 

 

 

 

 

 

ƒ

 

 

 

 

#include <REG932.H>

#include <I2C_LIB.H>

#include <PortConfig.H>

#include <PCF8574_Lib.h>

 

void main(void)

{

  v_InitI2C();

  EA = 1;                  // allgemeine Interruptsperre aufheben

  v_PortConfig(Port2, AllPins, BiDir);

  v_PCF8574WriteVal(0xFF); // Alle Portpins auf 1 setzen

 

  while(1)

  {

     v_PCF8574ReadVal();   // Wert einlesen

     P2 = Slave.Val[0];    // Ergebnis an Port 2 ausgeben

  } 

}

Listing 40  Inhalt von TestIOExp_Lib.c

Auswertung mit Interrupt des PCF8574

Der PCF8574 verfügt über ein Interruptsignal, wenn sich an den Porteingängen der Zustand ändert. Die Zustandsänderung für das Auslösen des Interrupts bezieht sich auf den eingeschriebenen und an den Ausgängen übernommenen Wert. Das Experimentier­board kann über den Jumper 11 eine Verbindung zwischen dem Interruptsignal des PCF8574 und dem externen Interrupt 1 herstellen.

Erstellen sie das Projekt aus Tabelle 47, das den externen Interrupt 1 auswertet, in der ISR den Wert aus dem PCF8574 einliest und die Ergebnisse wieder an Port 2 ausgibt. Bei dieser Aufgabe ist zu be­achten, dass die Priorität des I²C-Bus Interrupts hochgesetzt wird (siehe Listing 41, ). Ansonsten kann der PCF8574 (I²C-ISR) nicht ausgelesen werden, da der ext. Inter­­rupt 1 in der Abarbeitungssequenz höher angesiedelt ist. Eine ausführliche Be­schrei­bung zu den Interrupt Prioritäten finden sie in Kapitel 10.8 „Interrupt Priorität“ [3].

Damit die Zustandsänderung beim Loslassen der Taste wieder einen Interrupt beim PCF8574 auslöst, wird der eingelesene Wert in der ISR wieder in den PCF8574 ein­ge­schrieben (siehe ).

Projektname

Verzeichnis

Verwendete Sourcemodule

Test_IOExp_Int

Test_PCF8574_Int

TestIOExp_Int.c

 

..\Library

PCF8574_LIB.c, I2C_LIB.c, PortConfig.c

Tabelle 47  Projekt Test_IOExp_Int

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

#include <REG932.H>

#include <I2C_LIB.H>

#include <PortConfig.H>

#include <PCF8574_Lib.h>

 

void main(void)

{

  v_InitI2C();

 

  IT1 = 1; // ext. Interrupt 1, flankengetriggert

  EX1 = 1; // ext. Interrupt freigeben

  EA = 1;  // allgemeine Interruptsperre aufheben

  v_PortConfig(Port2, AllPins, BiDir);

  v_PCF8574WriteVal(0xFF); // Alle Portpins auf 1 setzen

  IP1 =0x01;               // Interruptprio für I²C-Bus hochsetzen

  while(1);                // Endlosschleife

}

 

void v_ExtInt1(void) interrupt 2 using 1

{

  unsigned char ucVal;

  v_PCF8574ReadVal();       // Wert einlesen

  ucVal = Slave.Val[0];     // Ergebnis an Port 2 ausgeben

  v_PCF8574WriteVal(ucVal);

  P2 = ucVal; 

}

Listing 41  Inhalt von TestIOExp_Int.c