www.mikrocontroller.net

Forum: Compiler & IDEs atmega32 +scancode an LCD anzeigen


Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!
Habe folgendes Problem:
Möchte den Scancode einer beliebigen Taste einer Standard -Tastatur am 
LCD ausgeben.
Hab andere Beiträge hier im Forum zur Hilfe genommen (Daten von PS2 
auslesen, Beitrag "Daten von PS2 auslesen"), mein aktueller 
Code

#include <defines.h>
#include <stdbool.h>
#include <stdint.h>
#include <avr/io.h>
#include <util/delay.h>
#include <lcd.h>
#include <ctype.h>
#include <stdio.h>
#include <avr/pgmspace.h>

#include <hd44780.h>

#define DATA_DDR DDRD
#define DATA_PORT PORTD
#define DATA_PIN PIND
#define DATA_LINE PD3

#define CLOCK_DDR DDRD
#define CLOCK_PORT PORTD
#define CLOCK_PIN PIND
#define CLOCK_LINE PD2





static void delay_1s(void)
{
  uint8_t i;

  for (i = 0; i < 100; i++)
    _delay_ms(10);
}

//FILE lcd_str = FDEV_SETUP_STREAM(lcd_putchar, NULL, 
_FDEV_SETUP_WRITE);

void data_high(void) {
  DATA_DDR &= ~(1<<DATA_LINE);
  DATA_PORT &= ~(1<<DATA_LINE);
}

void data_low(void) {
  DATA_DDR |= (1<<DATA_LINE);
  DATA_PORT &= ~(1<<DATA_LINE);
}

void clock_high(void) {
  CLOCK_DDR &= ~(1<<CLOCK_LINE);
  CLOCK_PORT &= ~(1<<CLOCK_LINE);
}

void clock_low(void) {
  CLOCK_DDR |= (1<<CLOCK_LINE);
  CLOCK_PORT &= ~(1<<CLOCK_LINE);
}


unsigned char get_data(void) {
  unsigned char state = (DATA_PIN & (1<<DATA_LINE));
  if(state != 0) {
    return 1;
  }
  return 0;
}
unsigned char get_clock(void) {
  unsigned char state = (CLOCK_PIN & (1<<CLOCK_LINE));
  if(state != 0) {
    return 1;
  }
  return 0;
}



unsigned char keycode(void) {
  unsigned char bits[11];
  unsigned char i = 0;
  unsigned int code = 0;
  while(i < 11) { //11Bits (Start, 8xDaten, Parity, Stop)
    while(get_clock() == 1) //warten auf fallende Flanke
      ;
          bits[i] = get_data();
    while(get_clock() == 0) //waren auf steigende Flanke
        ;
    i++;
  }


  clock_low(); //ich bin bescäftigt


  if(bits[1] == 1) {
    code |= (1<<0);
  }

  if(bits[2] == 1) {
    code |=  (1<<1);
  }

  if(bits[3] == 1) {
    code |=  (1<<2);
  }

  if(bits[4] == 1) {
    code |=  (1<<3);
  }

  if(bits[5] == 1) {
    code |= (1<<4);
  }

  if(bits[6] == 1) {
    code |=(1<<5);
  }

  if(bits[7] == 1) {
    code |=(1<<6);
  }

  if(bits[8] == 1) {
    code |=(1<<7);
  }



  //clock_high(); irgendwann musst du clock wieder freigeben
  return code;
}

void init(void) {
  lcd_init();
  data_low(); //Tastatur initalisieren
  clock_low(); //Tastatur initalisieren
  delay_1s(); //Tastatur initalisieren
  data_high(); //Tastatur initalisieren
  clock_high(); //Tastatur initalisieren
}



int main(void) {
  init();



      lcd_putchar(keycode);
      clock_low();





}

Hab versucht nur mal ein Zeichen auszugeben. Komischerweise gibt er mir 
immer ein r aus, und ich muss nicht mal was drücken, was geht da schief? 
Hat jemand eine Idee? Danke im Vorraus

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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!)

int main(void) 
{
  init();

  while(1)                    // <===
  {
    lcd_putchar(keycode());   // <===
    clock_low();
  }
}


Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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".

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.
:
:
          bits[i] = get_data();
    while(get_clock() == 0) //waren auf steigende Flanke
        ;
    i++;
  }

  if(bits[1] == 1) {
    code |= (1<<0);
  }

  if(bits[2] == 1) {
    code |=  (1<<1);
  }

  if(bits[3] == 1) {
    code |=  (1<<2);
  }

  if(bits[4] == 1) {
    code |=  (1<<3);
  }

  if(bits[5] == 1) {
    code |= (1<<4);
  }

  if(bits[6] == 1) {
    code |=(1<<5);
  }

  if(bits[7] == 1) {
    code |=(1<<6);
  }

  if(bits[8] == 1) {
    code |=(1<<7);
  }
:

z.B. so
:
short bits
:
:
          
    while(get_clock() == 0);  //    warten auf steigende Flanke
    bits = (bits>>1) | (get_data()?0x8000:0); // Bit einschieben
  }
  code = (unsigned char)(bits>>7); // evtl. auch 6 oder 8 --> ausprobieren
: 

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
:
 unsigned short bits;
 unsigned short data;
 unsigned char  i;
:
: 
  for(i=0; i<11; i++) {                       // 11Bits (Start, 8xDaten, Parity, Stop)
    while(CLOCK_PIN & (1<<CLOCK_LINE))        // warten auf fallende Flanke
       ;
    if(DATA_PIN & (1<<DATA_LINE)) data = 0x8000;
    else                          data = 0;  
    bits = data | (bits>>1);                  // Bit einschieben
    while(!(CLOCK_PIN & (1<<CLOCK_LINE)))     // warten auf steigende Flanke
       ;
  }
  code = (unsigned char)(bits>>7);            // evtl. auch 6 oder 8 --> ausprobieren
:

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo! Danke für eure Hilfe. Hab jetzt eure Vorschläge ausprobiert. Die 
Eingabe funktioniert jedoch wird mir noch immer das falsche Zeichen 
ausgegeben.
Arbeite mit 16MHz, noch immer falsches Timing?

Aktueller Code


#define DATA_DDR DDRD
#define DATA_PORT PORTD
#define DATA_PIN PIND
#define DATA_LINE PD3

#define CLOCK_DDR DDRD
#define CLOCK_PORT PORTD
#define CLOCK_PIN PIND
#define CLOCK_LINE PD2

static void delay_1s(void)
{
  uint8_t i;

  for (i = 0; i < 100; i++)
    _delay_ms(10);
}
void data_high(void) {
  DATA_DDR &= ~(1<<DATA_LINE);
  DATA_PORT &= ~(1<<DATA_LINE);
}

void data_low(void) {
  DATA_DDR |= (1<<DATA_LINE);
  DATA_PORT &= ~(1<<DATA_LINE);
}

void clock_high(void) {
  CLOCK_DDR &= ~(1<<CLOCK_LINE);
  CLOCK_PORT &= ~(1<<CLOCK_LINE);
}

void clock_low(void) {
  CLOCK_DDR |= (1<<CLOCK_LINE);
  CLOCK_PORT &= ~(1<<CLOCK_LINE);
}


unsigned char get_data(void) {
  unsigned char state = (DATA_PIN & (1<<DATA_LINE));
  if(state != 0) {
    return 1;
  }
  return 0;
}
unsigned char get_clock(void) {
  unsigned char state = (CLOCK_PIN & (1<<CLOCK_LINE));
  if(state != 0) {
    return 1;
  }
  return 0;
}
int main(void) {
    PORTD = 0xff;//pull ups aktivieren
  lcd_init();
  data_low(); //Tastatur initalisieren
  clock_low(); //Tastatur initalisieren
  delay_1s(); //Tastatur initalisieren
  data_high(); //Tastatur initalisieren
  clock_high(); //Tastatur initalisieren
  _delay_us(60);
  //Clockline muss high sein damit keyboard senden kann
  /*unsigned int bits;
  unsigned char i = 0;
  while(i < 11) { //11Bits (Start, 8xDaten, Parity, Stop)
    while(get_clock() == 1) //warten auf fallende Flanke
      ;

    }
    while(get_clock() == 0) //waren auf steigende Flanke
      if(get_data() == 1) { //Bit
      bits |= (1<<i); //übernehmen
    i++;
  }*/
  /*unsigned char bits[11];
    unsigned char i = 0;
    while(i < 11) { //11Bits (Start, 8xDaten, Parity, Stop)
        while(get_clock() == 1) //warten auf fallende Flanke
        {
        _delay_us(5);
                   if(get_data() ==1) {
                            bits[i] = get_data();
                                i++;}
        }

           while(get_clock() == 0) //waren auf steigende Flanke
           ;

  }*/

  unsigned short bits;
 unsigned short data;
 unsigned char  i;
 unsigned char code;

    for(i=0; i<11; i++)
    {                       // 11Bits (Start, 8xDaten, Parity, Stop)
        while(CLOCK_PIN & (1<<CLOCK_LINE))        // warten auf fallende 
Flanke
        ;
                    if(DATA_PIN & (1<<DATA_LINE)) data = 0x8000;
                                    else                          data = 
0;
                    bits = data | (bits>>1);                  // Bit 
einschieben
                        while(!(CLOCK_PIN & (1<<CLOCK_LINE)))     // 
warten auf steigende Flanke
                        ;
    }
  code = (unsigned char)(bits>>6);            // hab 6, 7, 8 ausprobiert

clock_low();

                   // <===

    lcd_putchar(bits);   // <===
    clock_low();

}

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry lcd_putchar(code) hab ich gehabt

Autor: Ralf W. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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?

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja aber ich müsst zumindest den richtigen Scancode übertragen bekommen 
oder?

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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?

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Christoph Unterrieder (udo12345)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was heißt das jetzt?

Autor: Lars (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>  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.
int main(void) {
  unsigned short bits;
  unsigned short data;
  unsigned char  i;
  unsigned char code;
  unsigned char buffer[20];
  PORTD = 0xff; // pull ups aktivieren
  lcd_init();
  while(1) {
    for(i=0; i<11; i++)
    {                       // 11Bits (Start, 8xDaten, Parity, Stop)
       while(CLOCK_PIN & (1<<CLOCK_LINE))  
           ;
       if(DATA_PIN & (1<<DATA_LINE)) data = 0x8000;
       else                          data = 0;
       bits = data | (bits>>1);                 // 
       while(!(CLOCK_PIN & (1<<CLOCK_LINE)))    //
           ;
    }
    code = (unsigned char)(bits>>6);   // hab 6, 7, 8 ausprobiert
    itoa(code,buffer);   // code in ASCII-String umwandeln
    lcd_puts(buffer);    // String ausgeben
  }
}

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Werner B. (werner-b)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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... ;-)

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
unsigned char keydata[] = { '-' /* Scancode x00     */ ,
                            '-' /* Scancode x01  F9 */ ,
                            '-' /* Scancode x02     */ ,
                            '-' /* Scancode x03  F5 */ ,
                            '-' /* Scancode x04  F3 */ ,
                            '-' /* Scancode x05  F1 */ ,
                            '-' /* Scancode x06  F2 */ ,
                            :
                            :
                            'z' /* Scancode x1A    */ ,
                            's' /* Scancode x1B    */ ,
                            'a' /* Scancode x1C    */ ,
                            'w' /* Scancode x06    */ ,
                            :
                            '-' /* Scancode 0x7F SCROLL */ 
                          } /* - = nicht druckbar */

Dann kannst du einfach sagen
  while(1) {
    for(i=0; i<11; i++) // 11Bits (Start, 8xDaten, Parity, Stop)
    {                       
       while(CLOCK_PIN & (1<<CLOCK_LINE))  
           ;
       if(DATA_PIN & (1<<DATA_LINE)) data = 0x8000;
       else                          data = 0;
       bits = data | (bits>>1);                  
       while(!(CLOCK_PIN & (1<<CLOCK_LINE)))    
           ;
    }
    code = (unsigned char)(bits>>6);   
    lcd_putchar(keydata[code]);  // Zeichen aus Tabelle holen und ausgeben.
  }


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.

Autor: Michael (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hier ist mein keydata.h

lg

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Auszug aus deiner Datei:
:
0b10100010,//0     0     //0 to 9
:
0b00111000,//10    a      //a to z
:
0b10101100,//35     z  
:
0b10010100,//55     Space    [7]  
:

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:
/* Scancode-Lookup-Tabelle mit 128 Einträgen */
unsigned char keydata[] = { '-' /* Scancode x00     */ ,
                            '-' /* Scancode x01  F9 */ ,
                            '-' /* Scancode x02     */ ,
                            '-' /* Scancode x03  F5 */ ,
                            '-' /* Scancode x04  F3 */ ,
                            '-' /* Scancode x05  F1 */ ,
                            '-' /* Scancode x06  F2 */ ,
                            :
                            :
                            'z' /* Scancode x1A    */ ,
                            's' /* Scancode x1B    */ ,
                            'a' /* Scancode x1C    */ ,
                            'w' /* Scancode x1D    */ ,
                            '2' /* Scancode x1E    */ ,
                            '-' /* Scancode x1F    */ ,
                            '-' /* Scancode x20    */ ,
                            'c' /* Scancode x21    */ ,
                            'x' /* Scancode x22    */ ,
                            'd' /* Scancode x23    */ ,
                            'e' /* Scancode x24    */ ,
                            :
                            '-' /* Scancode 0x7F SCROLL */ 
                          } /* - = 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.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok danke für deine hilfe

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.