Forum: Mikrocontroller und Digitale Elektronik wie zähler größer als 255 realisieren?


von fksystems (Gast)


Lesenswert?

ich brauche einen zähler, den ich inkrementieren kann. (..in assembler)
er muß aber mehr als 255 werte speichern können.

wie macht man das? macht man das, indem man mehrere byte-stellen
zusammenfaßt?

wie sage ich dem, daß er im 2. byte die stelle um eins erhöhen soll,
wenn das 1. byte bei 255 übergelaufen ist?

macht man das mit dem Z- oder C-bit? welches davon ist das richtige?

und muß ich es nach dem auslesen zurücksetzen, oder wird dieses manuell
zurück gesetzt?

dann müßte ich noch eine if-anweisung realisieren, und zwar eine, bei
der mehrere bedingungen erfüllt sein müssen.

wie mache ich dann in assembler eine if-bedingung, die nur zu einer
stelle springt, wenn mehrere bedingungen erfüllt sind?

von Oliver (Gast)


Lesenswert?

Inkrement r2:r1
add r1, 1
adc r2, 0 ; Nur Carry wird addiert

if (1. Bed. nicht erfüllt) goto weg
if (2. Bed. nicht erfüllt) goto weg
if (3. Bed. nicht erfüllt) goto weg
...
Alle Bedingungen erfüllt; mach was

von Frank Linde (Gast)


Lesenswert?

Zähler mit beliebiger Bitbreite realisiert man durch Zusammenfassung
mehrerer Bytes. Bis 16 Bit kann man die X,Y,Z-Register verwenden.
Überträge können mittels Carry- oder Zero-Flag berücksichtigt werden,
das kommt auf die Art der Zählerprogrammierung bzw. die Vorlieben des
Programmierers an. Beide Varianten funktionieren. Welche Befehle die
Flags verändern oder unangetastet lassen, kannst Du der sehr
übersichtlichen Instruction Set Summary im Datenblatt entnehmen.

Verzweigungen mit mehreren Bedingungen realisiert man durch
entsprechende Aneinanderreihung. Einfaches Beispiel:

adc r16,r17
brcc Beding_ne
cpi r18,36
brne Beding_ne
...               ; Bedingung erfüllt
rjmp Weiter
Beding_ne:        ; Bedingungen nicht erfüllt
...
Weiter:

Gruß, Frank

von Michael (Gast)


Lesenswert?

" add r1, 1
" adc r2, 0 ; Nur Carry wird addiert

Beim AVR geht das nicht, weil 'er' diese Befehle nicht kennt !

Eine effektive Lösung vermeidet Verzweigungen und nutzt den
SUBx-Befehl; ein 32-Bit Zähler kann dann so inkrementiert werden:

SUBI R16,0xff
SBCI R17,0xff
SBCI R18,0xff
SBCI R19,0xff

Hierbei wird der Zähler um -1 vermindert, was ein Inkrement bewirkt.
Dies geht mit Registern R16-R31. Möchte man die unteren Register
nutzen, kann man das so machen:

CLR R15      // R15 = 0x00
DEC R15      // R15 = 0xff
SUB Rn,R15
SBC Rn+1,R15
SBC Rn+2,R15
SBC Rn+3,R15

Zweckmäßigerweise kann man auch R15 einmalig auf 0xff setzen und danach
als 'Konstante' verwenden.

von fksystems (Gast)


Lesenswert?

hm.. laß mal überlegen:
d.h., ich lasse einfach beispielsweise eine 16-bit addition
durchführen. und zwar lasse ich immer zu dem 16-bit wert + eins
addieren. wie man die addition mit 16-bit werten macht, hab eich
glaubeich wo gefunden.

d.h., das überlaufbit addiert man dann irgendwie mit adc oder so.

jetzt aber frage:
wenn irgendein ereignis das überlauf-bit setzt, und ich adc ausführe,
welches mir auch schön das überlaufbit dazuaddiert, müßte es dann nicht
beim nächsten aufrufe von adc, wenn gerade kein überlaufbit gesetzt
wurde, weil kein überlauf stattgefunden hat, das überlaufbit noch vom
letzten male gesetzt sein, obwohl es gar nicht gesetzt sein darf?

wer sorgt denn dafür, daß bei einer verarbeitung des überlaufbits
danach das überlaufbit vor der nächsten rechnung wieder auf 0 steht,
wenn bei der nächsten rechnung kein überlauf stattgefunden hat?

von fksystems (Gast)


Lesenswert?

update:

Hm.. ich habe unter flags "instruction set summary" jetzt
nachgeguckt.

da steht ja eine spalte flags, wo so Z, C, N, V, H und sowas
drinsteht.

sind das die flags, die der befehl 100%tig bei jedem aufrufen
(neu)setzen tut?

von Nico (Gast)


Lesenswert?

Hallo

die flags im sreg brauchst du nicht löschen.
wenn z.b. bei einem befehl ein überlauf stattfindet wird das
überlaufflag gesetzt. beim darrauffolgenden befehl findet kein überlauf
statt also wird das bit gelöscht.

gruß nico

von Steffen Finger (Gast)


Lesenswert?

Hallo
Das gleiche Prob hatte ich grade auch. Mit dem Befehl adiw r24,1 oder
SBIW r24,1 erhöht oder erniedrigt man das Registerpaar R24/25 um die
Konstante 1 d.h. man hat einen 16Bit Zähler realisiert.

von Rolf Magnus (Gast)


Lesenswert?

> SUBI R16,0xff
> SBCI R17,0xff
> SBCI R18,0xff
> SBCI R19,0xff

Zwei Dinge: Erstens würde ich nicht 0xff, sondern -1 schreiben.
zweitens: addiert dieses nicht eher 0x1010101 zum Wert dazu? Mmn müßte
es heißen:

SUBI R16, -1
SBCI R17, 0
SBCI R18, 0
SBCI R19, 0

@Steffen Finger:

> Mit dem Befehl adiw r24,1 oder SBIW r24,1 erhöht oder erniedrigt
> man das Registerpaar R24/25 um die Konstante 1 d.h. man hat einen
> 16Bit Zähler realisiert.

Das wollte ich auch gerade vorschlagen, da es die naheliegendste
Variante ist und noch nicht vorgeschlagen wurde.
Wenn man ein Register als Nullregister definiert hat (also eins, in dem
man immer den Wert 0 stehen hat), so wie der Compiler das auch macht,
kann man das dann problemlos mit einem ADC r26, ZEROREG bzw. SBC r26,
ZEROREG u.s.w. auf größere Bitanzahl erweitern.

von Hannes L. (hannes)


Lesenswert?

Wie wäre es denn mit:

 inc r12              ;unteres Byte
 brne keinuebertrag   ;nicht 0
 inc r13
 brne keinuebertrag
 inc r14
 brne keinuebertrag
 inc r15              ;oberes Byte
keinuebertrag:

...

von Werner B. (Gast)


Lesenswert?

@Rolf Magnus

Nein, du musst das komplette -1 subtrahieren, und das ist als 32 bit
komplement nun einmal $FFFFFFFF.

Wie war das nochmal mit lowlow(-1), lowhigh(-1) etc.?

von Rolf Magnus (Gast)


Lesenswert?

> Nein, du musst das komplette -1 subtrahieren, und das ist als 32
> bit komplement nun einmal $FFFFFFFF.

Hmm, wenn man es so betrachtet... hast du recht. Ich hatte ja schon
geahnt, irgendwas übersehen zu haben, hab mich doch dazu hinreißen
lassen, die Subtraktion von -1 als Addition von 1 zu sehen.

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.