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
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
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_tkey=....;
2
charzeichen='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_tdigit=zeichen-'0';
'0' steht hier für die Zahl 48. (Siehe ASCII-Tabelle)
Für 1 << 3 schreibt man besser BIT_3. Vorher hat man einmalig das Ding
#define BIT_3 0x08 gebaut. Das ist für die Lesbarkeit das Gleiche wie
bei unsigned int und uint16_t auf dem 8bitter.
??? Bit3 ist Bit3, wie soll das mit einem Shift einfacher zu verstehen
sein? Der Portpin heißt auch nicht PINA<<3, oder?
Pack mal ein paar der Konstrukte in eine if Abfrage mit mehreren
Bedingungen. Dann kommst du auch noch drauf. ;-)
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_tpin_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_tpin_code[KEY_STROKES];
8
uint8_ti=0;
9
charpin;
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.
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..
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.
Eine eigene Frage?
Dieser Thread ist über 11 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.