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
:
Bearbeitet durch User
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)
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.
Schönschrift schrieb: > Für 1 << 3 schreibt man besser BIT_3 aber über <<3 kann man es einfacher verstehen, was hinter dem Befehl liegt.
??? 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_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.
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.
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.