Forum: Mikrocontroller und Digitale Elektronik 5-Byte-Zahl hochzählen


von Johannes Permoser (Gast)


Angehängte Dateien:

Lesenswert?

hi,

für einen zeitstempel muss ich eine zahl, die aus 5 byte besteht immer
um 1 hochzählen. die zahl ist wie folgt aufgebaut: t5 YH YL ZH ZL

angehängt habe ich mal meine version, allerding ist diese nicht gerade
ressourcenschonend (haufenweise vergleiche)

kann man das auch eleganter lösen? mit flags ausm SREG?

mfg, Johannes

von Laeubi (Gast)


Lesenswert?

ldi temp, 1
add ZL, temp
ldi temp, 0
addc ZH, temp
addc YL, temp
addc YH, temp
addc t5, temp

Würde gehen :)

von Spess53 .. (hardygroeger)


Lesenswert?

Hi

noch kürzer:

clr tmp,0
adiw ZH:ZL,1
adc YL,tmp
adc YH,tmp
adc t5,tmp

MfG HG

von Spess53 .. (hardygroeger)


Lesenswert?

erste Zeile ist natürlich:   clr tmp

von H.joachim S. (crazy_horse)


Lesenswert?

subi r20, -1
sbci r21, -1
sbci r22, -1
sbci r23, -1
sbci r24, -1

sollte auch gehen, wenn Register ab r16 verwendet werden. Registernamen
natürlich anpassen.

von Johannes Permoser (Gast)


Lesenswert?

funktioniert alles super, danke euch.

jetzt wärs noch nett, wenn mir jemand die version von Hartmut Gröger
erklären könnte

von Hannes L. (hannes)


Lesenswert?

> jetzt wärs noch nett, wenn mir jemand die version von Hartmut Gröger
> erklären könnte

Dann schau dir doch einfach mal den Hilfetext zu "adiw" im AVR-Studio
an. Dazu setzt du den Editorcursor auf den Befehl und betätigst die
F1-Taste.

...

von Dennis Strehl (Gast)


Lesenswert?

@H.Joachim Seifert:

subi r20, -1
sbci r21, 0
sbci r22, 0
sbci r23, 0
sbci r24, 0

Ich denke so funktioniert es besser ;)
Wir wollen ja nicht um
0000000100000001000000010000000100000001
hochzählen.

------------------

clr tmp,0
adiw ZH:ZL,1
adc YL,tmp
adc YH,tmp
adc t5,tmp

Zuerst wird eine 0 in tmp geladen, die wird später verwendet.
adiw addiert einen Immediate-Wert (also eine Konstante) zu einem Word,
also zwei Registern.
Danach wird das Carry mit adc YL,tmp (wobei tmp=0 ist)
weiterverrechnet.

--------------------

Meine Lösung:

adiw ZL, 1
sbci YL, 0
sbci YH, 0
sbci t5, 0

von Johannes Permoser (Gast)


Lesenswert?

> Danach wird das Carry mit adc YL,tmp (wobei tmp=0 ist)
weiterverrechnet.

und das verstehe ich nicht. was sagt das carry-flag? warum ändert sich
was am wert, wenn ich irgendwo 0 dazuzähle?

> Meine Lösung:

wird ja immer schöner, danke

von Jadeclaw D. (jadeclaw)


Lesenswert?

Ok, nehmen wir uns das Teil mal:
clr tmp,0
adiw ZH:ZL,1  ;Hier wird 1 dazuaddiert.
Läuft das Register dabei über, wird das Carry-Flag gesetzt.
Carry gesetzt ist wie 1 gemerkt.
adc YL,tmp   ; 0 + Carry(1/0) dazuaddiert.
Ist Carry gesetzt, addiert ADC 0+1 dazu, ist Carry gelöscht,
so wird 0 + 0 dazuaddiert,
d.h. der Wert im Register ändert sich nicht.
Falls das Register durch die aus dem Carry bestehende 1 überläuft,
wird Carry gesetzt.
adc YH,tmp    ; Dito
adc t5,tmp    ; Dito.
Bei passendem Zählerstand, kann auf diese Weise das Carryflag bis zum
Ende durchgereicht werden.

Gruss
Jadeclaw.

von H.joachim S. (crazy_horse)


Lesenswert?

@dennis:
ich glaube, da bist du auf dem Holzweg, man müsste es gleich mal durch
den Simulator laufen lassen. Aber ich bin mir ziemlich sicher, dass es
so richtig war.
Wenn du natürlich am Anfang einen Additionsbefehl nimmst, muss im
weiteren nur eine 0 addiert werden, das ist richtig.
Mit adiw geht es natürlich in diesem speziellen Fall (unterstes Byte
liegt im unteren Byte von x,y oder z)

von Dennis Strehl (Gast)


Lesenswert?

Sorry, hattest wirklich recht.
Ich war davon ausgegangen dass subi r20, -1 das gleiche sei wie addi
r20, 1. (Ich weiß, den Befehl gibt es nicht).

von H.joachim S. (crazy_horse)


Lesenswert?

Dein Beispiel funktioniert gar nicht, würde nur mit adi gehen. Bleibt
dir nach adiw also nur adc, also ein weiteres Register benutzen. Damit
bleibt die Lösung mit adiw ohne jeden Vorteil, aber 2 Nachteilen.

von Philipp B. (philipp_burch)


Lesenswert?

Hab' grade getestet, die Variante von Joachim funzt zweifellos.

von Karl H. (kbuchegg)


Lesenswert?

> was sagt das carry-flag?

Das cary flag sagt dass es einen Überlauf gegeben hat.
So wie in 9 + 1 ergibt 0, 1 Übertrag.

von Hannes L. (hannes)


Lesenswert?

@Johannes:

Wenn du in Assembler programmieren willst, dass musst du die Bedeutung
der Flags im SREG kennen. Denn sämtliche Verzweigungen sind ja
"bedingte Sprünge", ohne Verzweigungen kommst du nicht weit. Du hast
also Operationen (und Vergleiche), die die Flags verändern, und
bedingte Sprünge, die anhand der Flags springen oder eben nicht (BRxx).
Das Carry-Flag ist das Überlauf/Unterlauf-Flag, das nutzt man nicht nur
als Verzweigungsbedingung, sondern auch zur Addition/Subtraktion mit
Übertrag. Deshalb gibt es neben ADD (ohne Carry) auch ADC (mit Carry),
neben SUB auch SBC und neben SUBI auch SBCI.

Welche Befehle die Flags beeinflussen und welche Befehle vom Zustand
der Flags beeinflusst werden, erfährst du als Übersicht in der Tabelle
"Instruction Set Summary" am Ende des (vollständigen) Datenblatts
deines AVRs und etwas detailierter in der separaten Datei
"AVR-Instruction-Set" von der ATMEL-Homepage, sowie in der
Onlinehilfe des AVR-Studios.

Es ist völlig klar, dass du nicht vom ersten Tage an alles wissen
kannst, aber gelegentlich kann man da mal nachsehen und erfährt und
versteht Einiges, was man beim letzten Lesen noch nicht richtig
verstanden hat.

Bit- & Bytebruch...
...HanneS...

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.