|
|
// 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");
}
|
|