Das Programm kann so nicht arbeiten.
keycode ist bei dir einmal eine Variable (lcd_putchar(keycode);), die
im angegebenen Code nirgends definiert ist (ich erwarte einen
Syntaxfehler beim Kompilieren) und einmal eine Funktion (unsigned char
keycode(void)...).
Ich vermisse auch in main() die sog. Hauptarbeitsschleife, in der
laufend der Scancode eingelesen und auf das LCD ausgegeben wird. Im
Moment passiert das exakt einmal, dann ist main() zu Ende. In etwa in
der Art (Spielen an der clock nicht von mir auf Sinn kontrolliert!)
Stefan "stefb" B. wrote:
> keycode ist bei dir einmal eine Variable (lcd_putchar(keycode);), die> im angegebenen Code nirgends definiert ist (ich erwarte einen> Syntaxfehler beim Kompilieren)
Warum sollte es einen Syntaxfehler geben? keycode ist ein gültiges
Symbol, nämlich die Adresse der Funktion. Es gibt höchstens eine Warnung
"makes integer from pointer without a cast".
Gibt mir keinen Fehler aus, ist doch nur ein Funktionsaufruf oder?
Die Endlosschleife hab ich wieder rausgeschmissen, dann schreibt er mir
halt das ganze Display voll
hab aber noch immer das gleiche Problem dass er mir nur ein r ausgibt
ohne dass ich was drücke, weiß jemand wo der Fehler liegt?
Lars wrote:
> Gibt mir keinen Fehler aus, ist doch nur ein Funktionsaufruf oder?
Nein, ist es eben nicht, da hatte "stefb" schon Recht.
Du übergibst an lcd_putchar die Adresse der Funktion keycode, nicht
den Rückgabewert.
> hab aber noch immer das gleiche Problem dass er mir nur ein r ausgibt> ohne dass ich was drücke
Das ist halt die ASCII-Repräsentation vom Low-Byte der Adresse.
Stefan Ernst wrote:
> Warum sollte es einen Syntaxfehler geben? keycode ist ein gültiges> Symbol, nämlich die Adresse der Funktion. Es gibt höchstens eine Warnung> "makes integer from pointer without a cast".
Du hast vermutlich Recht. Ich habe mir wegen des fehlenden Codes
(lcd_putchar()) nicht genau überlegt, was der Compiler da konkret
schmeisst - Error oder Warning.
Stefan "stefb" B. wrote:
> Du hast vermutlich Recht. Ich habe mir wegen des fehlenden Codes> (lcd_putchar()) nicht genau überlegt, was der Compiler da konkret> schmeisst - Error oder Warning.
Da fehlt kein Code, an lcd_putchar wird das Low-Byte der
Funktionsadresse übergeben.
Kann mir bitte jemand einen Tipp geben was das jetzt heißt bzw was ich
ändern muss damit er mir das richtige Zeichen ausgibt und nicht von
selbst, sondern erst wenn ich eine Taste drücke
Danke
> Hab andere Beiträge hier im Forum zur Hilfe genommen...
Schon, aber leider den fehlerhaften Code, nicht wahr? :-o
Lies den angesprochenen Fred mal genau durch, insbesondere die Anmerkung
zum Timing des PS2-Intefaces.
BTW:
Das geht auch kompakter.
1
:
2
:
3
bits[i]=get_data();
4
while(get_clock()==0)//waren auf steigende Flanke
5
;
6
i++;
7
}
8
9
if(bits[1]==1){
10
code|=(1<<0);
11
}
12
13
if(bits[2]==1){
14
code|=(1<<1);
15
}
16
17
if(bits[3]==1){
18
code|=(1<<2);
19
}
20
21
if(bits[4]==1){
22
code|=(1<<3);
23
}
24
25
if(bits[5]==1){
26
code|=(1<<4);
27
}
28
29
if(bits[6]==1){
30
code|=(1<<5);
31
}
32
33
if(bits[7]==1){
34
code|=(1<<6);
35
}
36
37
if(bits[8]==1){
38
code|=(1<<7);
39
}
40
:
z.B. so
1
:
2
shortbits
3
:
4
:
5
6
while(get_clock()==0);// warten auf steigende Flanke
7
bits=(bits>>1)|(get_data()?0x8000:0);// Bit einschieben
8
}
9
code=(unsignedchar)(bits>>7);// evtl. auch 6 oder 8 --> ausprobieren
Ja wegen Timing, hab in manchen Beiträgen gelesen dass die Clock Leitung
immer eine gewisse Zeit auf high bzw low sein muss (glaub so ca. 50µs),
d.h die ganzen if Abfragen haben zur Folge dass das Timing nicht mehr
passt?
Ein Funktionsaufruf ist prinzipiell etwas, das ein Programm nicht
schneller macht. Statt
>> while(get_clock() == 1) //warten auf fallende Flanke>> ;
wäre
>> while(CLOCK_PIN & (1<<CLOCK_LINE)) //warten auf fallende Flanke>> ;
meistens schneller.
Das könnte besser funken:
Hallo,
Sorry, ich kann dir mit deinem Code nicht weiterhelfen. Achso,
kannst du deinen Code nicht auch als Anhang mitsenden. Da bleibt die
Formatierung erhalten und die Forumsoftware macht sogar noch Syntax
highlighting.
Das erleichtert es anderen die besser helfen können.
Vielleicht hilft dir ja ein Blick auf eine andere Implementierung.
Ich hab mir für dieselbe Aufgabe das Projekt "PS2 (PC-AT) keyboard
Interface (GCC)", zu finden bei AVR Freaks[1]_, angepasst.
Das Projekt basiert auf der AN313 von Atmel. Man kann damit allerdings
keine Daten senden. Das Senden braucht man auch nicht unbedingt, wenn
man sich mit dem Scancode Set 2 zufrieden gibt und es auch nicht stört,
das die LED's nicht leuchten.
Ich fand den Code superleicht an mein Projekt anzupassen. Die Scancodes
sind vordefiniert. Man muss sie nur noch an das deutsche Tastaturlayout
anpassen. Desweiteren muss man eventuell die Portpins an den verwendeten
Controller anpassen. Man braucht allerdings einen freien Pin mit
externen
Interrupt.
gruss ralf
.. [1] http://www.avrfreaks.net
> Die Eingabe funktioniert jedoch wird mir noch immer das> falsche Zeichen ausgegeben.
Dir ist aber schon klar, dass wenn du auf der Tastatur das 'A' drückst,
dass dann nicht der ASCII-Code vom 'A' übertragen wird, oder?
und wie komm ich dann vom Scancode zum Zeichen? Ich möchte eigentlich
dass er mir genau das Zeichen ausgibt dass ich auch eingetippt habe?
hab mir das so gedacht:
z.B für das Zeichen A
Tastatur liefert mir den Scancode 1E (sind die 8 Datenbits oder?), dies
entspricht 30, dann zähl ich die 35 dazu um auf die 65 zu kommen und gib
das aus,
aber ich hab noch immer das Problem das mir für die Tasten die ich
drücke der falsche Scancode zurückgeliefert wird. Hat jemand eine Idee?
> z.B für das Zeichen A> Tastatur liefert mir den Scancode 1E (sind die 8 Datenbits oder?),> dies entspricht 30, dann zähl ich die 35 dazu um auf die 65 zu kommen> und gib das aus
Das stimmt nur für den Scancode-Set 1.
Bei normalen AT-Tastaturen ist das Scancode-Set 2 üblicher.
Hier wird der Break mit einem zusätzlichen Byte 0x0f gekennzeichnet.
Und ein 'A' ist 0x1C
Siehe http://www.marjorie.de/ps2/start.htm
und http://de.wikipedia.org/wiki/Scancode
Also klären:
Welche Tasten liefern welche Scancodes?
Kommt, wenn du 'A' drückst immer derselbe Scancode?
wenn ich A drücke wird meist ein Leerzeichen ausgegeben, jedoch nicht
immer, manchmal auch andere Buchstaben (u.a Kappa glaub ich usw, hab
jetzt nicht geschaut welchen scancode die genau haben)
D.h es kommen also nicht immer die gleichen Scancodes
arbeite doch mit 4MHz,
was heißt dass wenn ich verschieden Scancodes erhalte für ein und
dieselbe Taste? was heißt das für meinen Code?
Danke für die Hilfe
> code = (unsigned char)(bits>>6); // hab 6, 7, 8 ausprobiert> clock_low(); ######> lcd_putchar(bits); // <===> clock_low(); ######
Lass mal die Spielereien mit der Tastatursperre und Initialisierung weg,
das hilft dir erst mal nicht weiter und macht die Sache nur noch ein
wenig undurchschaubarer.
Wandle die Zahl, die du als code bekommst doch mal in eine Hex- oder
Dezimalzahl und gib die aus. Dann kannst du ein Bitmuster auf ein Blatt
Papier malen und auf Regelmäßigkeiten untersuchen. Einfach nur 1 Zeichen
hilft dir jetzt nicht weiter. Insbesondere, wenn du nicht weißt, was das
für ein Binärwert ist.
Als Alternative kannst du den Scancode z.B. einfach mal auf 8 LEDs
ausgeben.
> was heißt dass wenn ich verschieden Scancodes erhalte für ein und> dieselbe Taste? was heißt das für meinen Code?
Erst mal, dass er noch nicht richtig funktioniert ;-)
Mach mal um die Tasteneinleserei und die Ausgabe eine while(1)-
Schleife, dann mußt du nicht immer den Reset drücken.
hallo lothar, habe das gleiche Problem,
hab jetzt mal deinen Code ausprobiert,
code = (unsigned char)(bits>>6); // hab 6, 7, 8 ausprobiert
Ergebnis für die Leertaste bei 6: 4124041
nach scancode set 2 müsst die Leertaste den make code 29 (hex) haben -->
entspricht 41 dezimal.
bei Enter: 9024090
nach scancode set 2 müsst Enter den make code 5A haben --> entspricht 90
dezimal
ok bekomm jetzt für jede Taste immer den gleichen Wert, warum auf
einmal?
Regelmäßigkeiten, ja die 240 und die Wiederholung der 3 Stellen vom
Anfang am Ende.
d.h anscheinend erkennt er jetzt welche Taste ich drücke, wo kommen die
240 her? warum die Wiederholung des Dezimalwerts am Anfang und am Ende?
> wo kommen die 240 her? warum die Wiederholung des Dezimalwerts am Anfang und am
Ende?
Was ist denn 240 in Hex? eine 0xF0, der "break code"
Taske drücken = "make code" = 0x5A
Taste loslassen = "break code" = 0xF0 + 0x5A
Zitat von http://heim.ifi.uio.no/~stanisls/helppc/make_codes.html
set 2, each key sends one make scan code and two break scan
codes bytes (F0 followed by the make code). This scan code
set is available on the IBM AT also.
Werner
> bei Enter: 9024090
Sind 90 240 90 alias 0x5A 0xF0 0x5A.
Taste gedrückt: Scancode CR = 90 = 0x5A
Taste losgelassen: BREAK = 240 = 0xf0, Scancode CR = 90 = 0x5A
Super, geht doch.
Gratulation, du verwendest das Scancodeset 2 (wie schon gesagt).
EDIT: freut mich, dass mein Code läuft,
dann muss ich den schon nicht selber ausprobieren... ;-)
Super danke für eure Hilfe,
eine Frage hätt ich noch, hab jetzt mal probiert ein entsprechendes
ASCII Zeichen auszugeben
Code:
while(j < 16) {
if(bits & (1<<j)) {
//lcd_putchar('1');
if(j>4 && j<14)
{
array[j-5]=1;
}
}
else {
//lcd_putchar('0');
if(j>4 && j<14)
{
array[j-5]=0;
}
}
j++;
}
//Ergebnis für z.B. Leertaste: 01001010001, Start bit:0, parity bit
0(da gerade Anzahl von 1en), stop bit:1
for (i=0; i<=78; i++)
{
if (array == keydata[i])
{
if (9<i && i<36) key=i+87;//a to z
lcd_putchar(key);
}
}
a++;
}
while(1);
zuerst nur mal für a bis z, in keydata.h stehen alle Scancodes zu den
entsprechenden Tasten auf der entsprechenden i-ten Stelle, aber
funktionieren tut das ganze leider nicht so wirklich, warning: vergleich
zwischen integer und pointer, es lässt sich jedoch compilieren, aber das
entsprechende Zeichen wird nicht angezeigt
Warum soooo kompliziert?
Du brauchst nicht die Zahl in ein Binärarray umzubiegen. Der Controller
kann mit einer Binärzahl von sich aus schon recht gut umgehen.
Wenn du also z.B. sowas da drin stehen hast:
lcd_putchar(keydata[code]);// Zeichen aus Tabelle holen und ausgeben.
14
}
Zeig doch mal deinen keydata.h
Ich denke, du hast noch die invertierte Denkweise und deine Daten in der
falschen Reihenfolge sortiert...
Und somit suchst du nach einem Scancode für ein Zeichen. Aber wenn du
sicher weißt, was da rauskommt, ist eine Suche unnötig: du mußt nur die
Daten einmal (nämlich in der Deklaration in der Headerdatei) richtig
anordnen.
Du hast (keine Ahnung warum) den bitinvertierten Scancode eingetragen:
Scancode dein Tabelleneintrag
0 = 0x45 = 0b01000101 <= 0b10100010
a = 0x1c = 0b00011100 <= 0b00111000
z = 0x35 = 0b00110101 <= 0b10101100
space = 0x29 = 0b00101001 <= 0b10010100
Und damit machst du dir das Leben unnötig schwer. Wenn du z.B. für die
Space-Taste schon einen Wert von 41(dez) = 0x29 bekommst, musst du nicht
mehr viel machen (schon gar nicht die Bits umdrehen, damit 0x94
herauskommt). Bau die Tabelle entsprechend auf und nimm (wie gesagt)
diesen Scancode-Wert einfach als Index für eine Tabelle. Fertig.
Da ist in meinem Post noch ein kleiner Typo:
>>>>>>> 'w' /* Scancode x06 */
Besser so:
1
/* Scancode-Lookup-Tabelle mit 128 Einträgen */
2
unsignedcharkeydata[]={'-'/* Scancode x00 */,
3
'-'/* Scancode x01 F9 */,
4
'-'/* Scancode x02 */,
5
'-'/* Scancode x03 F5 */,
6
'-'/* Scancode x04 F3 */,
7
'-'/* Scancode x05 F1 */,
8
'-'/* Scancode x06 F2 */,
9
:
10
:
11
'z'/* Scancode x1A */,
12
's'/* Scancode x1B */,
13
'a'/* Scancode x1C */,
14
'w'/* Scancode x1D */,
15
'2'/* Scancode x1E */,
16
'-'/* Scancode x1F */,
17
'-'/* Scancode x20 */,
18
'c'/* Scancode x21 */,
19
'x'/* Scancode x22 */,
20
'd'/* Scancode x23 */,
21
'e'/* Scancode x24 */,
22
:
23
'-'/* Scancode 0x7F SCROLL */
24
}/* - = nicht druckbar */
Und dann mußt du dir noch etwas für die erweiterten Scancodes (z.B.
Cursortasten) ausdenken, die mit 0xE0 signalisiert werden ;-)
Ein Tipp: sieh dir das Thema Zahlensysteme (insbesondere das
Hexadezimalsystem) etwas genauer an. Das erleichtert das
Programmierer-Leben ungemein.