www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR ASM 16 Bit / 180 teilen


Autor: boese (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mahlzeit,

ich benötige für eine Zeitkritische Geschichte eine Routine (ASM) womit 
ich auf einem ATmega1281 eine 16 Bit Variable durch eine Konstante (in 
diesem Fall 180) teilen kann.

Hat jemand vielleicht etwas Code-Geschnippsel da? Ich glaub mein 
Mathe-Verständnis reicht dafür nicht aus um durch 180 zu teilen (und nur 
Addition, Sub. sowie Div und Mul mit Potenzen von 2 (shift)) zu 
verwenden.

Ich hoffe jemand kann mir auf die Sprünge helfen :)


Viele Grüsse

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
du kannst die 16 Bit Zahl einfach mit 364 multiplizieren und dann die 
obersten 16 Bits des Ergebnisses verwenden.
x / 180 = (x * (65536 / 180)) / 65536 = (x * 364,088888...) >> 16

Je nach geforderter Präzision geht das am Schnellsten.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder du rechnest:
Ergebnis=Zahl/256+Zahl/512-Zahl/4096 usw.
Geht komplett ohne Multiplikation oder Division, nur durch Schieben. 
Wird aber vermutlich langsamer sein als die Lösung von Kai.

Autor: boese (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmmm,

rein von der Idee her schon gut... Nur dann brauch ich wieder 32 Bit 
Variablen, da wird dadd ganze natürlich wieder sehr Komplex :(...

Zumal wenn man nur die High-bytes nimmt, dass das ergebnis wieder nur 8 
Bit ist... und 65535 / 180 = 364 ;)


Viele Grüsse

Autor: Jochen Müller (taschenbuch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So wie Kai es beschrieben hat geht es.
Oder als universelle und schnelle Division in Assembler:

http://elm-chan.org/docs/avrlib/div16.txt
http://elm-chan.org/docs/avrlib/div08.txt
http://elm-chan.org/docs/avrlib/div24.txt
http://elm-chan.org/docs/avrlib/div32.txt

Jochen Müller

Autor: boese (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ihr seit top... Jörgs Variante braucht grad mal 20 Takte.... Sowas nenn 
ich doch mal Klasse ;D

Bascom hätte dafür mal locker über das 10-Fache gebraucht....

Vielen Dank an euch!!!!

Autor: boese (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wieso is nu Kais Assembler-Schnippsel weg?

Autor: boese (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörgs meinte ich...

Autor: Joerg Wolfram (joergwolfram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dad * 364 kann man noch vereinfachen, indem man *182 nimmt und dann nach 
links schiebt...

(16-Bit-Wert in X, Ergebnis in r22/r23)
        clr r22
        ldi r23,182
        mul XL,r23
        movw r20,r0
        mul XH,r23
        add r21,r0
        adc r22,r1
        clr r23
        lsl r20
        rol r21
        rol r22
        rol r23
        sbrc r21,7
        subi r22,0xff
        brne label
        subi r23,0xff
label:

auf die Schnelle, ohne Garantie...

Gruß Jörg

Autor: Joerg Wolfram (joergwolfram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sorry, mir ist noch eingefallen, dass ich mir die Benutzung von r16 
sparen kann, deshalb die schnelle Löschung des vorherigen Codes.

Gruß Jörg

Autor: Joerg Wolfram (joergwolfram)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und prompt ist noch ein kleiner Fehler drin, ich hoffe, jetzt stimmts:
        clr r22
        ldi r23,182
        mul XL,r23
        movw r20,r0
        mul XH,r23
        add r21,r0
        adc r22,r1
        clr r23
        lsl r20
        rol r21
        rol r22
        rol r23
        ldi r20,0x80
        add r21,r20
        clr r20
        adc r22,r20
        adc r23,r20

Gruß Jörg

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch nur auf die Schnelle:

lsl r20
kann raus, da der Wert nicht mehr gebraucht wird.

Die Rundung am Ende kann durch eine Addition mit 91 am Anfang ersetzt 
werden - das spart u.U. noch mal ein Bisschen. Je nach Anforderung kann 
die auch komplett entfallen.

Ansonsten lässt sich da vermutlich nicht mehr viel dran machen.

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>und prompt ist noch ein kleiner Fehler drin, ich hoffe, jetzt stimmts:
Dann les' ich jetzt nochmal :)

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.