Pin-Code Abfrage

#3992696
Lesenswert?

Ich verzweifel gerade an einer einfachen Aufgabe..
Ich möchte  einen Code über mein Tastenfeld einlesen und diesen dann auf 
meinem Display ausgeben...
Weiß gar nicht wie viele for- und while-Schleifen ich in den letzten 
Stunden programmiert habe, vielleicht sehe ich es auch einfach nicht 
mehr..

Das LCD wird mit der Lib aus dem Mikrocontroller Tutorial betrieben, als 
Code lese ich BCD ein, die Funktion "Einlesen();" wandelt mit das dann 
in ein char Element um. Allerdings schaffe ich es nicht, den Code in ein 
int-Array zu packen ...
Die Zahlen zeigt es richtig an, nur das Umwandeln harpert. Ich habe den 
Code schon so einfach runtergehandelt wie es mir möglich war.

Bin neu im Bereich Mikrocontroller, bezweifle aber, dass ich bei einem 
"normalen" C-Programm mal derartige Schwierigkeiten hatte, so eine 
simple Aufgabe zu lösen...

Ich muss das Problem leider weiter geben und vielleicht auch ins Bett^^ 
Hoffe es kann sich jemand die Sache mal anschauen.

Vielen Dank
Angehängte Dateien:
Persönliche Seite #3992879
Lesenswert?

So wie ich das verstehe möchtest du über X knöpfe die dazu entsprechende 
Zahl am Display anzeigen lassen?

möchtest du zb. eine 4bit zahl einlesen kannst du per Bitmanipulation 
einfach für jeden einzeln Button jeweils eine 1<<X verschieben.
so kannst du einfach eine zahl "zusammen basteln" ohne Größen Rechen und 
Speicher Aufwand.
zusätzlich könntest du über einen weiteren Button die zahl wieder 
zurücksetzten.

Beispiel
WHile(1){
if(PINA&(1<<1))
{
zahl = 1<<0; // 0 bit
}
if(PINA&(1<<2))
{
zahl = 1<<1;   // 1 bit
}
if(PINA&(1<<3))
{
zahl = 1<<2;   // 2 bit
}
if(PINA&(1<<4))
{
zahl = 1<<3;   // 3 bit
}



if(PINA&(1<<5))
{
zahl = 0;   REset
}

}

damit kannst du eine 4 bit zahl zusammen bauen. und zurücksenden.
evl noch einen 6 Button, um die zahl aufs Display zu senden.

edit:
Link für bitmanipulation
http://www.mikrocontroller.net/articles/Bitmanipulation
Gast #3993187
Lesenswert?

Hi,

ich finde den Code etwas umständlich. Du musst wissen, dass 
Zeichen(char) auch nur Zahlen sind. Das Stichwort ist hier 
ASCII-Tabelle. In Einlesen() bekommst du einen acht Bit Integer und 
machst daraus ein Zeichen.

Das geht kürzer:
1
uint8_t key = ....;
2
char zeichen = '0' + key;

Somit müsste auch klar sein, wie man aus einem Zeichen z.B. der Eins 
wieder die Zahl 1 machen kann.
1
uint8_t digit = zeichen - '0';

'0' steht hier für die Zahl 48. (Siehe ASCII-Tabelle)
#3994300
Lesenswert?

Ti Bo schrieb:

> Bin neu im Bereich Mikrocontroller, bezweifle aber, dass ich bei einem
> "normalen" C-Programm mal derartige Schwierigkeiten hatte, so eine
> simple Aufgabe zu lösen...

Wenn du 4 Zeichen speichern willst, dann solltest du
1
        uint8_t pin_code[3];
das Array auch mit einer Länge von 4 allokieren.

Genau aus dem Grund benutzt man zb Makros um derartige magische 
Konstanten nicht quer durch den Programmtext zu verstreuen, wo man sie 
nur schwer wiederfindet.

Mach dir ein
1
#define KEY_STROKES  4
und benutz dann KEY_STROKES überall an den Stellen, die von der Länge 
deines Codes abhängen. Und benutze for-Schleifen, wenn deine 
while-Schleife sich vernünftig in eine umformulieren lässt.
1
...
2
      lcd_string("Enter zum ");
3
      lcd_setcursor(0,4);
4
      lcd_string("Bestaetigen:");
5
      lcd_setcursor(0,2);
6

7
      uint8_t pin_code[KEY_STROKES];
8
      uint8_t i = 0;
9
      char pin;
10

11
      for( i = 0; i < KEY_STROKES; i++ ) {
12
        pin =  Einlesen();
13
        if(pin >= '0' && pin <= '9' ) {
14
          pin_code[i] = pin - '0';
15
          lcd_data(pin);
16
        }
17
      }
18

19
      lcd_clear();
20
      lcd_setcursor(0,1);
21
      lcd_string("Neuer Code:");
22
      lcd_setcursor(0,2);
23

24
      for( i = 0; i < KEY_STROKES; i++ ) {
25
        lcd_data (pin_code[0] + '0 ');
26
      }
27
    }
28
...

änderst du mal deine Meinung und willst 3 oder 5-stellige Codes anstatt 
der 4-stelligen, dann änderst du einfach das #define auf den Wert und 
den Rest des Programms passt der Compiler für dich an.
#3999097
Lesenswert?

Muss man nicht Platz lassen für das Terminierungszeichen '\0' wie bei 
C??? also eine Arraylänge von 5?

Mit dem einlesen des Ascii, bzw BCD-Codes hatte ich keine Probleme, for 
schleifen hatte ich jede Menge ausprobiert, find ich auch am Besten, 
erst als es nicht funktioniert hatte hatte ich einen so umständlichen 
Text schreiben müssen...

Allerdings... Ich hab das Problem gelöst, aber erst, als ich für meine 
Schleifen (egal ob for oder while), static integer benutzt habe... 
Sobald ich static weglasse zählt der uC nicht mehr nach oben, warum auch 
immer. In meinem Programm macht sich das bemerkbar, dass er vom Pin-Code 
immer die erste Zahl überschreibt...

Wenn ich den Pin-Code jetzt zurücksetzen will hab ich Probleme damit, 
ich kann den Code einlesen, speichern und durch mit einer Bestätigung 
vergleichen. Wenn ich ihn aber zurücksetzten will schaff ich es nicht 
das Array zu leeren oder sonst was..
#3999279
Lesenswert?

Ti Bo schrieb:
> Muss man nicht Platz lassen für das Terminierungszeichen '\0' wie bei
> C??? also eine Arraylänge von 5?

Kommt drauf an.
Wenn du das Ergebnis der EInleserei als String auffassen willst, dann 
ja.
Wenn du aber sagst, das ist einfach nur ein Datenfeld, bei dem jeder 
Character einer Eingabe entspricht, dann brauchst du kein \0. Nicht 
jedes char Array ist auch automatisch ein String bzw. muss als String 
angesehen werden.

Ganz abgesehen davon, sind ja im char Array wegen
1
          pin_code[i] = pin - '0';
ja auch gar keine ASCII Zeichen gespeichert. Das ist einfach nur ein 
Array, in dem die einzelnen Ziffern des Codes gespeichert sind. Man 
hätte dort natürllich auch direkt die Digits in Form ihres ASCII Codes 
speichern können.


Hängt halt eben alles davon ab, wie du als Programmierer die Dinge sehen 
willst.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren