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.
:
Bearbeitet durch User
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.
8bit binär to ASCII haben wir in der Schule (auch auf einem 16F877A) so gelöst:
1 | movf zahl,w |
2 | movwf z1er |
3 | clrf z10er |
4 | clrf z100er |
5 | l100 |
6 | movlw .100 |
7 | subwf z1er,w |
8 | SKPC |
9 | goto s100 |
10 | movwf z1er |
11 | incf z100er, f |
12 | goto l100 |
13 | s100 |
14 | |
15 | l10 |
16 | movlw .10 |
17 | subwf z1er,w |
18 | SKPC |
19 | goto s10 |
20 | movwf z1er |
21 | incf z10er, f |
22 | goto l10 |
23 | s10 |
24 | |
25 | ;convert to ASCII |
26 | movlw '0' |
27 | addwf z1er,f |
28 | addwf z10er,f |
29 | addwf z100er,f |
Wenn du die Stellen nicht als ASCII sondern als Binärzahl haben willst kannst du die letzten Zeilen ab "movlw '0' " weglassen.
:
Bearbeitet durch User
Als Assembler-Programmierer muss man sich ja wirklich selbst für die einfachsten Dinge echt einen abbrechen. Warum tut ihr euch das an?
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
:
Bearbeitet durch User
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.
Kuck dir mal diese beiden Seiten an: http://www.sprut.de/electronic/pic/programm/index.htm (kennst du vielleicht schon) http://www.piclist.com/techref/microchip/routines.htm Alle möglichen und unmöglichen Routinen, hab aber schon 1-2 erwischt (Divisonsroutinen) die nicht korrekt funktioniert haben.
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.