Forum: Mikrocontroller und Digitale Elektronik AVR Tutorium Multiplex Hilfe


von Marco V. (overmind)


Angehängte Dateien:

Lesenswert?

Hallo,
ich bin gerade dabei das AVR-Tutorial durch zu arbeiten. Zurzeit bin Ich 
im Kapitel 7-Segmentanzeigen / Multiplexing und Ich werde nicht so recht 
schlau aus folgendem Codeteil: siehe Datei.

Im Grunde soll dieser Teil doch dafür sorgen, dass der Z-Pointer auf den 
richtigen Eintrag in der Codetabelle zeigt und somit das gewünschte 
Bitmuster, für die Ansteuerung der 7-Segmentanz., in den RAM ablegt?
So wie der Code geschrieben ist wird eine 0001 ausgegeben, sehe ich das 
richtig (Habe AtmelStudio zum simulieren und noch keinen praktischen 
Aufbau mit µC)?

Zum Verständniss, was wird hiermit bezweckt:
1
           
2
_out_tausend:
3
           inc     temp2
4
           subi    temp, low(1000)      ; -1000
5
           sbci    temp1, high(1000)
6
           brcc    _out_tausend

Wieso oder wie wird hier 1000 subtrahiert bzw. warum?
temp hat hier den Wert 1 und temp1 den Wert 0, nach der Subtraktion hat 
temp den Wert 0x19 ,und temp1 den Wert 0xFC, wie kommt man daruf?
low(1000) und high(1000) ist das Low- bzw. Highbyte der Konstanten 1000 
als 16 Bit-Zahl?

MfG
Marco

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Marco V. schrieb:

> Wieso oder wie wird hier 1000 subtrahiert bzw. warum?

weil die Zahl in die einzelnen Stellen zerlegt werden muss.
Aus der Zahl 5278 müssen die Ziffern 5, 2, 7 und 8 extrahiert werden, 
weil diese Einzelziffern ja auf den einzelnen Anzeigen auftauchen 
müssen.

Wie stellst du fest, welcher Wert an der Tausender stelle aufscheinen 
muss. Oder einfach gesagt: woher weißt du, dass bei der Zahl 5278 die 5 
an der Tausenderstelle auftauchen muss?
Die Frage ist doch: wieviele (ganze) Tausender sind in 5278 enthalten. 
Das kann man natüclich rechnen, indem man 5278 durch 1000 dividiert.
Aber auch ein Kleinkind kann das, wenn es mit den Fingern rechnet und 
noch nicht dividieren kann.
es versucht einfach 1000 abzuziehen, wenn das geht und zählt (mit den 
Fingern mit) wie oft das möglich ist.

5278 ist größer als 1000, also kann man 1000 abziehen, 1 - mal
4278 ist größer als 1000, also kann man noch mal 1000 abziehen. 2 - mal
3278, jep geht noch immer. 3 - mal
2278, geht immer noch, 4 - mal
1278, auch da kann man 1000 abziehen - 5 -mal
278. Nope. Da geht nichts mehr

Man konnte also 5 mal genaz 1000 abziehen. Also sind 5 Tausender in 
5278. An der Tausenderstelle muss also eine 5 aufleuchten.

Edit:
wobei es hier konkret so gemacht wird, dass man von 278 noch mal die 
1000 abzieht und nach der Subtraktion einfach prüft ob es einen 
Unterlauf gab. Das ist einfacher, als mit 1000 zu vergleichen um zu 
entscheiden, ob man 1000 abziehen kann oder nicht. Man Subtrahiert 
einfach und sieht sich hinterher an, ob es gut ging.

: Bearbeitet durch User
von Marco V. (overmind)


Lesenswert?

Ah ok, Ich verstehe und bei der Hunderterstelle wird dann addiert, da ja 
die 16 Bit-Zahl hier negativ geworden ist (die letzte Subtraktion wurde 
ausgeführt, auch wenn nicht mehr zurückgesprungen wurde). Bei der 
Zehnerstelle wird wieder subtrahiert bis das Carryflag gesetzt wird->16 
Bit-Zahl wieder negativ->Einerstelle wird wieder addiert (mit 10) bis 
Carryflag = 0 -> Rest= Einerstelle=temp


5576-6000=-424 -> Tausender 5 -> -424+500=76-> Hunderter 5 -> 76-80=-4 
-> Zehner 7 -> -4+10=6 -> Einer 6

Hm ok habs verstanden, danke für die schnelle Antwort.

Eine Frage hab Ich noch, warum wird bei low() subi und bei high() subci 
verwendet?

von Karl H. (kbuchegg)


Lesenswert?

Marco V. schrieb:

> Eine Frage hab Ich noch, warum wird bei low() subi und bei high() subci
> verwendet?

Weil subi eine 8 Bit Subtraktion ist, du aber eine 16 Bit Subtraktion 
brauchst. Also muss ein eventueller Übertrag, der bei der Subtraktion 
der unteren 8 Bit entstanden sein könnte, für die Subtraktion der oberen 
8 Bit mitgenommen werden. subci macht genau das.

Machst du ja beim händischen Subtrahieren auch.
1
    193
2
  -  78

Deine erste händische Rechnung lautet (wenn du das so gelernt hast wie 
ich:
8 und wieviel ist 13? (13 deswegen, wel 3 ja kleiner als 8 ist).
8 und 5 ist 13.  5 angeschrieben, 1 weiter
1
    193
2
  -  78
3
     1
4
 ------
5
      5

1 und 7 macht 8, 8 und wieviel ist 9?
8 und 1 ist 9. 1 angeschrieben, 0 weiter
1
    193
2
  -  78
3
    0
4
 ------
5
     15

0 und 0 macht 0, 0 und wieviel macht 1?
0 und 1 macht 1
1
    193
2
  -  78
3
    0
4
 ------
5
    115

beachte: bei der ersten Subtraktion gab es noch keinen zu 
berücksichtigenden  Übertrag aus den kleineren Stellen. Daher musste da 
auch nichts berücksichtigt werden.

Konzeptionell ist das ganz genau das gleiche wie hier.
Das Carry Flag transportiert einen möglichen Über- Unterlauf von einer 
'Berechnungsposition' zur nächsten, wenn die Berechnung in mehrere Teile 
aufzuteilen ist (wie bei dir 16 Bit Subtraktion auf 8 Bit Subtraktion, 
oder eben händisch die Subtraktion mehrstelliger Zahlen auf die 
Subtraktion einzelner Ziffern. Die erste Subtraktion ist ein SUBI, alle 
weiteren sind ein SBCI)

: Bearbeitet durch User
von Marco V. (overmind)


Lesenswert?

Alles klar, danke.

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.