3stellige Zahl auf 3 7Segmente

Gast #3785890
Lesenswert?

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
#3785897
Lesenswert?

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
Gast #3785904
Lesenswert?

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.
#3785912
Lesenswert?

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.
Gast #3785941
Lesenswert?

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.
Gast #3786012
Lesenswert?

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.
#3786020
Lesenswert?

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.
#3786237
Lesenswert?

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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren