I2C – LCD/Tastatur

 

 

 


Eingabetest von der Tastaturmatrix


 

 

 






 

Software-Interrupt aus ..

Bezeichnung ..

Parameter ..

 


I2C API

I2C Init

int AAh, AH= 80h



I2C API

I2C Scan

int AAh, AH= 81h


 

I2C API

I2C Transmit

int AAh, AH= 82h

 


I2C API

I2C Release

int AAh, AH= 84h



TCP/IP API

API sleep

int ACh, AH= 09h


 

 

 





Ziel-Hardware: Jeder dESµ SC12-Server, bei dem über den I2C-Bus das I2C-LCD/Tastatur Funktionsmodell angeschlossen ist.
Bei diesem Funktionsmodell wurde über 7Bits eines PCF8574 TorBaustein, eine 3*4 Telefon Tastaturmatrix angeschlossen. Mit dem 8.Bit kann einen Leuchtdiode betrieben werden.

Beschreibung:
Dieses Programm initialisiert den i2c-Bus, schaltet dann die Leuchtdiode des LCD/Tastatur FunktionsModells ein und wieder aus, und holt dann Zeichen von der Tastenmatrix, bis die Taste [#] gedrückt wird.


Die Abfragegeschwindigkeit der Tastenmatrix wird durch die API-Funktion sleep() verringert. Das macht es anderen Programmen des Multitask-Betriebssystems möglich, ebenfalls Rechenzeit zu erhalten.









// TAST_init.CPP
// -------------   Version 10.03.2002
//                Borland IDE C++ 3.1 oder 5.2
//                Model: SMALL
//                char:  unsigned
//                bearbeitet: BBS WiLu, D.Schwarzer
// -----------------------------------------------------
// Ziel-Hardware: jeder dESµ SC12 bei dem am I2C-Bus das
// I2C-LCD/Tasatatur Funktionsmodell angeschlossen ist.

// Funktion: Das Programm fragt die 3 x 4 Telefon-
// Tastenmatrix der Platine ab

// Hardware: Die TastenMatrix wird mit 3Bit Spaltenaus-
// gängen und 4Bit Zeileneingängen an einem PCF8574
// betrieben. An Bit7 dieses Tores ist eine LED ange-
// schlossen.

// Verteilung der Signale am PCF8574 Tor:
//       TorBit:   7   6  5  4   3  2  1  0
//       LcdPin:  led  s3 s2 s1  z4 z3 z2 z1

#define i2c_tast  0x4C   // Adr: PCF8574 Tor 6, Tastatur
#define i2c_lcd   0x4E   // Adr: PCF8574 Tor 7, LCD

#define OFF 0            // LED einschalten
#define ON  1            // LED ausschalten


#include <stdio.h>
#include <dos.h>

static union  REGS  inregs;
static union  REGS  outregs;

// -------------------------------------------------------
// SoftINTs des I2C-Bus

void i2c_init(void)
{
 inregs.h.ah = 0x80;
 int86(0xAA,&inregs,&outregs);
}
void i2c_release(void)
{
 inregs.h.ah = 0x84;
 inregs.h.al = 0;
 int86(0xAA,&inregs,&outregs);
}
int i2c_scan( int start_addr, int end_addr)
{
 inregs.h.ah = 0x81;
 inregs.h.al = start_addr;
 inregs.h.cl = end_addr;
 int86(0xAA,&inregs,&outregs);
 return (outregs.h.al);
}
int i2c_transmit(char slave, char c)
{
 inregs.h.ah = 0x82;
 inregs.h.al = slave & 0xFE;
 inregs.h.cl = c;
 int86(0xAA,&inregs,&outregs);
 if(outregs.x.flags & 0x01){
  return (int)outregs.h.al & 0x00FF;
 }
 return(0);
}
int i2c_receive (char slave, char* c, char lastchar)
{
 inregs.h.ah = 0x82;
 inregs.h.al = slave | 0x01;
 if(lastchar)inregs.h.cl = 1; // mehrere Zeichen holen
 else        inregs.h.cl = 0; // nur ein Zeichen holen
 int86(0xAA,&inregs,&outregs);

 if(outregs.x.flags&0x01){
  *c = 0;
  return (int)outregs.h.al & 0x00FF;
 }
 *c = (char)outregs.h.ch;
 return(0);
}

void api_sleep(int ms)
{
 inregs.x.ax = 0x0900;
 inregs.x.bx = ms;
 int86(0xAC, &inregs, &outregs);
}

// -------------------------------------------------------

// TastInit()
// setzt alle Bits des Tastaturtores auf log1. Dadurch
// können externe Eingabequellen das Tor auf log0 her-
// unterziehen. Diese Initialisierung ist nur notwendig,
// wenn die Gefahr besteht, dass auf einem der Eingänge
// zuvor eine log0 ausgegeben wurde. Dies sollte
// normalerweise nicht eintreten.
// So wird diese Funktion hier nicht benutzt
void TastInit(void)
{
 i2c_transmit(i2c_tast, 0xFF);
}

// led()
// schaltet die LED ein (status=1) oder aus (status=0).
// Hardwaremässig bedingt, besitzt die LED ein inver-
// tiertes Verhalten.
void led(int status)
{
 char c=0;
 i2c_receive (i2c_tast,&c,0);
 i2c_release();
 if (status) i2c_transmit(i2c_tast, c&0x7F);  // ein
 else        i2c_transmit(i2c_tast, c|0x80);  // aus
 i2c_release();
}

// ScanToAscii()
// übersetzt den Tastatur-Scancode in ASCII-Code. Diese 
// Tabelle kann entfallen, wenn direkt mit den Scancodes
// gearbeitet werden soll. Dies ist bei der hier
// vorliegenden, sehr kleinen Matrix kein Nachteil.
char ScanToAscii (char scan)
{
 switch (scan){
   case 0x37: return('1');
   case 0x57: return('2');
   case 0x67: return('3');
   case 0x3B: return('4');
   case 0x5B: return('5');
   case 0x6B: return('6');
   case 0x3D: return('7');
   case 0x5D: return('8');
   case 0x6D: return('9');
   case 0x3E: return('*');
   case 0x5E: return('0');
   case 0x6E: return('#');
  }
  return(0);
}

// ScanTast()
// scannt die Tastaturmatrix einmal und kehrt zurück.
// Wird hierbei eine gedrückte Taste gefunden, wird diese
// nach 10ms erneut gelesen und dann ihr Code
// zurückgegeben (Tastenentprellung). Zwischen zwei
// gleichen Tastendrucken, muss die Taste losgelassen
// werden. Die LED leuchtet, wenn eine Taste gedrückt wird.
// Damit andere Programm noch Ausführungszeit erhalten,
// wird pro Durchlauf eine Zeit von 30ms gewartet.

// Rückgabe:  0 = keine Taste gefunden
//           !0 = ASCII-Code der Tasten

int ScanTast(void)
{
 static char LastHit=0;
 char c=0, t=0, h=0, z[]={0x3F,0x5F,0x6F,0x00}, n=0;

 led(OFF);
 i2c_receive (i2c_tast,&c,0);       // status lesen
 i2c_release ();
 // die Schleife setzt die Spaltentorbits s1,s2,s3
 // und vergleicht, ob in den Zeilen ein Wert!= 1111b
 // enthalten ist
 do{
    i2c_transmit(i2c_tast,(c&0x8F)|z[n]); // zeile setzen
    i2c_release();
    i2c_receive (i2c_tast,&t,0);    // status lesen
    i2c_release ();
    t=t&0x7F;                       // LED-Bit ausmaskiert
    if((t&0x0F)==0x0F) n++;         // kein Tastendruck
    else {                          // ein Tastendruck ..
     if (t==LastHit){               // .. gleich wie zuvor
      api_sleep(30);
      continue;
     }
     else{                           // .. neu
      led(ON);
      api_sleep(10);
      i2c_receive (i2c_tast,&h,0);   // 2.mal lesen
      i2c_release();
      h=h&0x7F;                      // LED-Bit ausmaskiert
      if (h==t) {
       LastHit=h;
       return(ScanToAscii(h));
      }
     }
    }
 } while(z[n]!=0);

 api_sleep(30);
 LastHit=0;
 return(0);
}


// Testprogramm zu TASTinit.EXE
// ----------------------------
// Initialisiert den i2c-Bus, schaltet die Leuchtdiode
// des LCD/Tastatur FunktionsModells ein und wieder aus,
// holt dann Zeichen von der Tastenmatrix, bis die Taste #
// dedrückt wird. 
void main (void)
{
 char ascii=0;
 printf("\r\n TastInit [Start]\r\n");
 i2c_init();     // I2C-Bus initialisieren
                    // Test ob LCD vorhanden
 if(i2c_scan(i2c_tast, i2c_tast)!=i2c_tast){
  i2c_release();
  printf ("PCF8574 der Tastatur nicht gefunden");
  return;
 }
                    // Test der LED
 led(ON);
 api_sleep(1000);
 led(OFF);
                    // Tastendruck holen bis # gedrückt
 do{
  ascii =ScanTast();
  if(ascii!=0) printf ("%c",ascii);
 } while (ascii!='#');

 i2c_release();
 printf("\r\n TastInit [Ende]\r\n");
}

 


 

 

 

 


Hinweise zum Programm
Das vorliegende Programm zeigt in weitgehend linearer Programmierung die Abfrage des ScanCode einer TastaturMatrix, und der Umwandlung des Scancodes in ASCII-Code. Die Kommunikationsschnittstelle zum Steuerrechner wird durch ein bidirektionales 8-Bit Tor gebildet. Hier durch den I2C-Torbaustein PCF8574.

Von den 8Bits des Tores am PCF8574, ist Bit 7 an einer LED angeschlossen. Bit 6,5,4 sind mit den Spaltenleitungen der Matrix verbunden und die Bits 3,2,1,0 mit deren Zeilenleitungen. Die Zeilen- und Spaltenleitungen liegen im Ruhezustand über Pull Up Widerstände auf log1.


Das der I2C-Bus vor seinem Einsatz initialisiert werden muss, wurde bereits in vorhergehenden Beispielen mehrfach betrachtet. Ebenso die Unterprogramme, mit denen der Datentransfer zu den angeschlossenen Bausteinen möglich ist. Im Bedarfsfall kann hierzu die Beschreibung der Soft-INTs herangezogen werden.

Zur Abfrage der Tastaturmatrix muss gewährleistet sein, dass die Torbits 3,2,1,0 als Eingänge betrieben werden können. Dies ist nach dem Einschalten der Spanungsversorgung der Fall. Alle TorPins führen über Pull-Up Widerstände ein 1-Signal und können in beiden Richtungen, als Ausgang oder als Eingang auf 0 gezogen werden. Dies ist nicht der Fall, wenn das Tor intern auf 0 gelegt wurde (als Ausgangs benutzt wurde) und ein externes Gerät den gleichen Torpin als Eingang benutzen möchte. Das externe Gerät wird in diesem Fall kein log1-Signal am Torpin erzeugen können. Um diesen Zustand zu verhindern, bzw. aufzuheben muss am Torpin eine 1 als Ausgangssignal erzeugt werden, worauf das externe Gerät den Pin als Eingang benutzen kann


 

 

 

 


  zip.Download

 

GoBlack [10.03.2002]