Hallo,
Ich habe eine Zahl, die in einer Variablen ist und die sich von 0-255
verändern kann, nun will ich diese Zahl auf 3 7Segmentanzeigen anzeigen
lassen. Meine Idee war die 3stellige Zahl auf 3 einstellige Zahlen
aufzuteilen, aber mit dem Aufteilen klappt es nicht so bei mir, da ich
keinen richtigen Ansatz habe der funktioniert.
Ich verwende einen PIC-16F877A und programmiere in Assembler.
Hätte evtl. Vorschläge wie ich dieses Problem mit einem möglichst kurzem
Programmcode löschen kann?
mfg
Daniel
Daniel schrieb:> aber mit dem Aufteilen klappt es nicht so bei mir, da ich> keinen richtigen Ansatz habe der funktioniert.
wie würdest du es dann mit einem Taschenrechner machen? Und wie hast du
es denn versucht?
Daniel schrieb:> Hallo,> Ich habe eine Zahl, die in einer Variablen ist und die sich von 0-255> verändern kann, nun will ich diese Zahl auf 3 7Segmentanzeigen anzeigen> lassen. Meine Idee war die 3stellige Zahl auf 3 einstellige Zahlen> aufzuteilen, aber mit dem Aufteilen klappt es nicht so bei mir, da ich> keinen richtigen Ansatz habe der funktioniert.
Nicht?
237 / 100 -> 2 ( also 2 Hunderter )
237 % 100 -> 37 ( der Rest bei der Division durch 100 )
37 / 10 -> 3 ( also 3 Zehner )
37 % 10 -> 7 ( der Rest bei der Division durch 10 )
In Summe haben wir also:
7 in der Einerstelle
3 in der Zehnerstelle
2 in der Hunderterstelle
An / und % hab ich auch schon gedacht aber in Assembler geht das doch
nicht oder? Wenn doch könnt ihr mir die Befehle schreiben?
Ich habe es versucht indem ich solange -100 rechnen lasse bis die zahl
negativ wird und solange dann bei einer anderen Variablen +1 rechnen
lasse aber da das Zero-Flag nur bei exakt 0 gesetzt wird hört er dann
nicht mit Rechnen auf.
Ansonsten hab ich +100 und am Ende das Carry-Flag überprüft aber da er
bei 255 überläuft habe ich die Idee auch schnell verworfen.
Daniel schrieb:> An / und % hab ich auch schon gedacht aber in Assembler geht das doch> nicht oder? Wenn doch könnt ihr mir die Befehle schreiben?
Nein geht nicht.
IN Assembler ist ein gute Strategie, eine Division durch sukzessive
Subtraktionen in einer Schleife zu ersetzen und mitzählen, wie oft
abgezogen werden kommte.
Wieviele Zehner gibt es in 35?
1
Zähler: 0
2
3
35 - 10 geht ohne Unterlauf.
4
Neues Ergebnis 25, Zähler: 1
5
6
25 - 10 geht ohne Unterlauf
7
Neues Ergebnis 15, Zähler: 2
8
9
15 - 10 geht ohne Unterlauf
10
Neues Ergebnis 5 Zähler: 3
11
12
5 - 10 das ergibt einen Unterlauf
13
14
-> damit ist das Endergebnis:
15
die Division liefert 3 und es bleiben 5 Rest
> Ich habe es versucht indem ich solange -100 rechnen lasse bis die zahl> negativ wird und solange dann bei einer anderen Variablen +1 rechnen> lasse aber da das Zero-Flag nur bei exakt 0 gesetzt wird hört er dann> nicht mit Rechnen auf.
Logisch. Das Zero Flag ist ja auch genau dafür gedacht, eine Gleichheit
mit 0 festzuhalten.
Da musst du dir halt mal die anderen Flags ansehen, wofür die so gedacht
sind. Hinweis: Oft heisst so ein Flag das Carry Flag. Bei einer Addition
stellt es einen Überlauf fest, bei einer Subtraktion einen Unterlauf.
Mein Vorschlag:
Es währe Sinnvoll für jede Segmentziffer ein Element in einem Array
vorzusehen. (bzw. in eine Speicherstelle innerhalb des RAM´s um es in
"Assambler Talk" auszudrücken)
Außerdem macht es Sinn, einen Algorithmus zu entwerfen, der nur die
entsprechende Ziffer aus einer Zahl ermittelt, welche im Zehnersystem
den Größten Wert hat - also z.B. die 3 aus 3621. Kleines Stichwort :
"Teile und Herrsche"
Das währe die erste Aufgabe, die du lösen und in ein anspringbares
Codesegment (das was in C ungefähr einer Funktion entspricht) gießen
solltest.
Die nächste Denkaufgabe die es zu knacken gilt ist, was der Laufindex
deines ASM Arrays mit den einzelnen Ziffern deiner Zahl zu tun hat und
dem Umstand, dass laufzeittechnisch eine Multiplikation und eine
Subtraktion relativ billig zu haben sind. Dann kommst du auch dahinter
wie, du den oben zu entwerfenden Algorithmus auch für deine ganze Zahl
von max. 255 benutzten kannst.
Daniel schrieb:> Ich habe es versucht indem ich solange -100 rechnen lasse bis die zahl> negativ wird und solange dann bei einer anderen Variablen +1 rechnen> lasse aber da das Zero-Flag nur bei exakt 0 gesetzt wird hört er dann> nicht mit Rechnen auf.
Du darfst nicht auf negativ abfragen, sondern die Subtraktion nur machen
wenn der Wert >99 bzw >=100 ist. dann funktioniert das Verfahren.
Du hast in deinem Zahlenbereich ja keine negativen Zahlen sondern nur
die Werte 0..255.
Oder du must den Wert vorher in eine vorzeigenbehafteten 16Bit
Variablen konvertieren.
Gaestchen schrieb:> Oder du must den Wert vorher in eine vorzeigenbehafteten 16Bit> Variablen konvertieren.
Hast du schonmal Assembler aufm µC programmiert?
Max H. schrieb:> 8bit binär to ASCII haben wir in der Schule (auch auf einem 16F877A) so> gelöst:
Zumindest meiner Meinung nach, ist es nur bedingt hilfreich, hier
einfach ein unkommentiertes Assembler-Listing rein zu klatschen. Durch
Kommentare hingegen ist Assembler sogar relativ gut lesbar bzw.
verständlich, auch für jemanden, der damit nicht tagtäglich zu tun hat.
Heiner schrieb:> Warum tut ihr euch das an?
Das führt notgedrungen zur Assembler Pro und Contra Diskussion, die hier
schon so oft geführt worden ist. Ich persönlich bin größtenteils auch
nur mit Hochsprachen beschäftigt und halte Assembler für
"unpraktikabel", aber warum soll nicht jemand anders in Assembler
programmieren dürfen, und wenn es nur aus Spaß bzw. Interesse heraus
passiert ;).
Mit freundlichen Grüßen,
Karol Babioch
Heiner schrieb:> Warum tut ihr euch das an?
Was tut man sich denn an? Sich einmalig geeignete Routinen zu schreiben
oder frei verfügbare zu verwenden? Zumindest soweit es diese Frage hier
betrifft, ist das kein echtes Problem.