Forum: Mikrocontroller und Digitale Elektronik Atmega8 - Tastenbitmuster auf LCD


von Themis K. (themis)


Angehängte Dateien:

Lesenswert?

Hallo Zusammen,

ich beschäftige mich seit 3 Wochen (mit Hilfe des Tutorials) mit dem 
Atmega8. Dafür habe ich mir u.a. das AVR-P28 Entwicklungsboard zugelegt, 
dazu ein paar Taster und ein LCD Dot-Matrix-Modul (Art.-Nr.: LCD 162C BL 
bei Reichelt).

Nun möchte ich 7 Taster, die am Eingang PD0 ... PD6 des µCs 
angeschlossen sind, beliebig betätigen und das Betätigungsmuster, das 
als binäre Zahl zu betrachten ist, in die jeweilige dezimale Form 
konvertieren und auf dem LCD (angeschlossen am Ausgang PB0 ... PB3) 
darstellen.

Das Programm (in Assembler) habe ich mit Hilfe der Programmabschnitten 
aus dem Tutorial und ein paar simplen Sprung-/Verzweigungsbefehlen 
zusammengebastelt und es funktioniert auch, ... zwar nicht perfekt, aber 
für mich als Laien ein großer Erfolg...

Allerdings habe ich leider auch folgendes feststellen müssen:

Bei durchgehender Betätigung NUR der Taste 1 (PD0) wird auf dem Display 
durchgehend (wie erwartet) die 001 dargestellt. Drücke ich nun zwei 
Tasten zeitgleich, z.B. Taste 1 UND Taste 2, wird (wie erwartet) 
durchgehend die 003 angezeigt. Wenn ich jedoch NUR die Taste 2 (PD1) 
durchgehend betätige, wird zunächst die 002 angezeigt und erlischt 
anschließend nach Bruchteilen von Sekunden. Anschließend lässt sich 
nichts mehr auf dem Display darstellen, bzw. das Display regiert nicht 
mehr und das Programm muss nochml neu geladen werden.

Was könnte hier die Ursache sein? Das Programm in .asm-Format habe ich 
hier angehängt und hoffe auf Unterstützung. Wie schon am Anfang erwähnt: 
Ich beschäftige mich seit 3 Wochen damit :) Bitte um Verständnis!

Danke und Grüße

von Karl H. (kbuchegg)


Lesenswert?

Diese ganze (sich immer wieder wiederholende) Auswertung
1
wert001:  mov    temp2, temp1
2
      andi  temp2, 0b00000001
3
      cp    temp1, temp2
4
      brne  wert002
5
...
ist reichlich dubios. Das muss ich mir jetzt erst mal durch den Kopf 
gehen lassen, was da überhaupt (mit allen Nebenbedingungen) rauskommt.

auf jeden Fall würde man das (um die Grundidee deiner Ausgabe 
aufzunehmen) ganz einfach so schreiben
1
wert001: cpi  temp1, 1
2
         brne wert002
3
4
         ... deine Ausgabe für 001
5
6
wert002: cpi  temp1, 2
7
         brne wert003
8
9
         ... deine Ausgabe für 002
10
11
wert003: cpi  temp1, 3
12
         brne wert004
13
14
         ... deine Ausgabe für 003
15
16
wert003: cpi  ....

In Summe wärst du wesentlich besser beraten, wenn du dir anstelle dieser 
Copy & Paste Programmierung eine Funktion schreibst, die eine beliebige 
Zahl in einem Register als Dezimalzahl ausgeben kann. Das ist nicht 
besonders kompliziert und auch dafür findest du Anregungen bzw. 
Beispiele im AVR-Tutorial.

von Herr M. (herrmueller)


Lesenswert?

Auch wenn Du erst 3 Wochen dabei bist: Das ist absolut keine gute Art zu 
programmieren (Spaghetti-Code). Unabhängig von der Sprache muss man sich 
vorher Gedanken machen, wie man solch ein Problem löst. In Deinem Falle 
mag es gerade noch funktionieren, auch wenn man schon fast nicht mehr 
alles anschauen kann, aber wenn Du dann mal eine 16-bit Zahl darstellen 
willst, kannst Du nicht 65536 mal vergleichen, dafür reicht dann Dein 
Speicher nicht.
Wenn Du eine Zahl zwischen 1 und 1000 durch Fragen rausfinden sollst, 
fragst Du ja (hoffentlich) auch nicht: Ist es 1? Ist es 2? Ist es 3?...
sondern: Ist sie grösser als 500 ? grösser als 250 ...

Du braucht also Schleifen mit Vergleichen. In etwa so.
--------------------------
HundertZeichen=$30 ;'0'

Ist die Zahl >100   -> ja, dann HundertZeichen=$31  und 100 abziehen
HundertZeichen drucken

ZehnerZeichen=$30

Zehner:
Ist der Rest > 10  -> ja, dann ZehnerZeichen 1 hochzählen und vom Rest 
10 abziehen, wieder zu Zehner springen
              -> nein, dann ZehnerZeichen drucken

EinerZeichen=Rest+$30

EinerZeichen drucken
--------------------------------


Damit kommt man mit weit wenigen Programmzeilen aus, und es wird 
übersichtlicher.

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
Noch kein Account? Hier anmelden.