Forum: Mikrocontroller und Digitale Elektronik Abfrage von Pfeiltasten im Terminal-Programm


von Jürgen H. (misteret)


Lesenswert?

Hallo,
ich habe über UART im HyperTerminal ein kleines Menü zur Anzeige 
gebracht. Nun wollte ich zweckmäßigerweise mit Pfeiltasten navigieren, 
und bin da auf unerwartete Probleme gestoßen, da diese nicht zur ASCII 
Tabelle gehören.

Ich dachte, naja, guck ich doch einfach mal, was mir HyperTerminal 
zurücksendet. Es werden immer zwei Bytes gesendet:
1. Byte 91d bzw 133okt
2. Byte 91d bzw 133okt

Egal, welche Taste ich drücke, es kommen immer diese beiden Bytes an!

Hat jemand ne Ahnung, wie man Pfeiltasten erkennen kann?

von Lehrmann M. (ubimbo)


Lesenswert?

Tastaturspeicher auslesen.

Unter C:
1
#include <bios.h>
2
3
void main()
4
{
5
int Tastaturcode, Funktionstaste;
6
char Buchstabe;
7
8
9
while (bioskey(1)==0) {}
10
//bioskey(1) gibt '0' zurück solange keine Taste gedrückt wird
11
Tastaturcode=bioskey(0);
12
//bioskey(0) gibt den Tastaturcode der gedrückten Taste zurück
13
Funktionstaste=biskey(2);
14
//bioskey(2) ermittelt den Tastaturcode der Sondertasten (alt, shift, strg)
15
16
switch (Tastaturcode)
17
{
18
case 7777: Buchstabe='a'; break;
19
//und so weiter
20
}

von user (Gast)


Lesenswert?


von Axel R. (Gast)


Lesenswert?

1
//***************************
2
// Decode incoming ESC sequence
3
//***************************
4
unsigned int Term_Get_Sequence()
5
{
6
    unsigned char val;
7
    unsigned int ret;
8
    
9
    val = Term_Get();
10
    if( val != 27 )                      // Received ESC ?
11
    {
12
        ret = val;                       // If not, return char
13
    }
14
    else
15
    {
16
        val = Term_Get();
17
        if( val != '[' )                 // Received '[' ?
18
        {
19
            ret = val;                   // If not, return char
20
        }
21
        else
22
        {
23
            val = Term_Get();
24
            
25
            if( val == 'A' ||
26
                val == 'B' ||
27
                val == 'C' ||
28
                val == 'D' )             // Arrow keys ?
29
            {
30
                ret = val << 8;          // Put code in upper byte
31
            }
32
            else
33
            {
34
                ret = val;               // If not, return char
35
            }
36
        }
37
    }
38
    return ret;
39
}

Pfeiltasten werden bei entsprechend gesetzteer Terminalemulation mit dem 
ESCAPE Zeichen (27) und "[" eingleitet und dann, je nach Pfeiltaste, mit 
"A", "B", "C" oder "D" beendet.

Aus ner Atmel Appnote Nr. vergessen:( "Terminaldriver.c" jedenfalls. 
Sollte sich im Netz finden lassen.

Term_Get() ist die normale USART Empfangsroutine, welche ein ASCII 
Zeichen von der seriellen empfängt, nichts weiter.

Gruß
Axelr.

von Jürgen H. (misteret)


Lesenswert?

Okay danke!
Also ich habe schon gewusst, dass mehrere Zeichen hinterheinander 
gesendet werden für die Pfeiltasten.

Ich habe die UART Abfrage im Moment so:
1
if(UCSR0A & (1<<RXC0))
2
{
3
   summe += UDR0;
4
}

So. Wenn ich das Programm starte, und eine der Pfeiltasten drücke, 
müsste ja eins von denen
27 + 91 + 65 = 183
27 + 91 + 66 = 184
27 + 91 + 67 = 185
27 + 91 + 69 = 186

herauskommen. Ich drücke, DANACH halte ich das Programm im Debugmodus an 
und drücke nochmal was. Dann sehe ich ja in der Variablen summe die 
Summe.
Hier steht - egal welche der Pfeiltasten ich drücke - immer eine 182 
drin.

von Karl H. (kbuchegg)


Lesenswert?

Jürgen Hems schrieb:
> Okay danke!
> Also ich habe schon gewusst, dass mehrere Zeichen hinterheinander
> gesendet werden für die Pfeiltasten.
>
> Ich habe die UART Abfrage im Moment so:
>
1
> if(UCSR0A & (1<<RXC0))
2
> {
3
>    summe += UDR0;
4
> }
5
>

Mit Verlaub, aber das ist Murks.

Empfange ein Zeichen.
Stell fest dass es den Wert 27 (= Escape) hat
Als Folge davon weißt du, das das noch nicht alles war -> nächstes 
Zeichen empfangen etc.

Da mit Summen zu hantieren ist Blödsinn.
Schon alleine daran zu erkennen, dass du keine Möglichkeit hast, 
vernünftiges Debugging zu betrieben wie zb: einfach mal das was 
empfangen wurde als Hex-Zahlen wieder auszugeben, um zu sehen was da 
über die Leitung kommt.

Dass du hier so dermassen im Nebel stocherst, ist eine direkte Folge 
davon, dass du dich um eine vernünftige Auswertung von empfangenen 
Zeichen drücken willst.

von Jürgen H. (misteret)


Lesenswert?

Also ich habe es im Debugmodus getestet, das erste empfangene Zeichen 
war 91 ;-(

von Karl H. (kbuchegg)


Lesenswert?

Jürgen Hems schrieb:
> Also ich habe es im Debugmodus getestet, das erste empfangene Zeichen
> war 91 ;-(

Ich kann mich nur wiederholen

> Dass du hier so dermassen im Nebel stocherst, ist eine direkte
> Folge davon, dass du dich um eine vernünftige Auswertung von
> empfangenen Zeichen drücken willst.

Mach dir ein Testprogramm, welches für jedes empfangene Zeichen seinen 
Hex Code ausgibt, drück auf die Taste und dann weißt du es ganz genau.

von Karl H. (kbuchegg)


Lesenswert?

Da 91 (also '[' in der Cursor-Tasten Sequenz ja tatsächlich vorkommt, 
hast du höchst wahrscheinlich irgendwo anders das Escape verschlampt.

Am besten machst du dir eine einzige Empfangsroutine, die ein 
empfangenes Escape auswertet.

Für die Cursorsteuerung definierst du dir programmintern eines der 
unteren ASCII-Steuerzeichen um. Zb. könntest du (für dich) definieren:

   Deine Zeichenempfangsroutine liefert  0x04   bei Cursor links
                                         0x05              rechts
                                         0x06              rauf
                                         0x07              runter

Die zentrale Empfangsroutine liefert jetzt alle Zeichen ganz normal, es 
sei denn sie bekommt ein Escape vorgesetzt. In dem Fall merkt sie sich 
diesen Escape (in globalen Variablen) und liefert zunächst mal ein 'Ich 
hab kein Zeichen für den Aufrufer' wenn es sich um eine nicht wartende 
Funktion handelt. Bei den nächsten Aufrufen werden dann die 
eintrudelnden Zeichen aufgrund des vorhergehenden Escapes anders 
ausgewertet, bis feststeht ob es eine Cursor-Taste war und wenn ja 
welche.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.