mikrocontroller.net

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


Autor: fksystems (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Frank Linde (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: fksystems (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: fksystems (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Nico (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Steffen Finger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht 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:

...

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.?

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.