Forum: Mikrocontroller und Digitale Elektronik 3stellige Zahl auf 3 7Segmente


von Daniel (Gast)


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

von Peter II (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


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

von Anja (Gast)


Lesenswert?

Hallo,

siehe Artikel Batteriewächter

Dort halt für PIC18F2520

Gruß Anja

von Daniel (Gast)


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.

von Karl H. (kbuchegg)


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.

: Bearbeitet durch User
von Mega Troll (Gast)


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.

von Gaestchen (Gast)


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.

von Max H. (hartl192)


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.

: Bearbeitet durch User
von Heiner (Gast)


Lesenswert?

Als Assembler-Programmierer muss man sich ja wirklich selbst für die 
einfachsten Dinge echt einen abbrechen. Warum tut ihr euch das an?

von jz (Gast)


Lesenswert?

Gaestchen schrieb:
> Oder du must den Wert vorher in eine vorzeigenbehafteten 16Bit
> Variablen konvertieren.

Hast du schonmal Assembler aufm µC programmiert?

von Karol B. (johnpatcher)


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

: Bearbeitet durch User
von Fritz (Gast)


Lesenswert?

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.

von Sascha (Gast)


Lesenswert?

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