www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik [avrassembler] Division Problem mit Rest


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Fabian727 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi,

wie der Titel schon beschreibt, versuche ich momentan als total blutiger 
Anfänger einen Dividierer zu schreiben.

Ich habe vier Register r16, r17, r18 und r19. In diesen Registern habe 
ich eine einzige Zahl gespeichert, die durch 12 dividiert werden soll. 
Das höchstwertigste Register ist r19.

Leider konnte ich bis jetzt nur Schleifen programmieren die die 
einzelnen Register dividiert haben bis eine Zahl über geblieben ist, die 
kleiner war als der Divisor.

Mein Problem ist nun, dass diese Zahl ignoriert wird, wodurch mein 
Ergebnis zu ungenau wird. Z.B.: Ist in r19 die Zahl 11 gespeichert und 
wird durch 12 dividiert, kommt 0 raus und die 11 wird weggeschmissen.

Wie kann man das nun lösen, dass die 11 weiter verwendet wird?


Vielen Dank für deine Hilfe schon im voraus,

Fabi

Autor: Peter Dannegger (peda)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Fabian727 schrieb:
> Wie kann man das nun lösen, dass die 11 weiter verwendet wird?

Das kommt drauf an, wie Du möchtest, daß sie weiter verwendet wird.
Wegschmeißen tust Du sie ja.


Peter

Autor: Fabian S. (fabian727)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
ja, ich würde gerne die vier register dividieren (und als eine einzige 
Zahl verwenden), quasi wäre dann der Rest vom höheren Register dann das 
9., 10., 22. etc. bit vom niedrigereren Register, aber leider kann ich 
die ja nicht einfach anhängen :D.

Autor: Peter Dannegger (peda)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Deine Ausführungen werden immer konfuser.

Vielleicht willst Du ja das:
Multipliziere vorher mit 10, dann hat Dein Ergebnis eine gedachte 
Nachkommastelle.


Peter

Autor: spess53 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi

>Leider konnte ich bis jetzt nur Schleifen programmieren die die
>einzelnen Register dividiert haben bis eine Zahl über geblieben ist, die
>kleiner war als der Divisor.

Willst du jetzt aufrunden? Wenn ja, dann vergleiche den Rest einfach mit 
6.

MfG Spess

Autor: Fabian S. (fabian727)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
mein Problem ergibt sich durch folgendes:

Ich habe meine clock0 in einem attiny 2313, jedesmall wenn es einen 
clockoverflow gibt, wird r16 incrementiert. Wenn r16 voll ist wird r17 
danach r18 und dann r19 erhöht.

Irgendwann kommt dann ein Interrupt, was die clock0 anhält.

Jetzt will ich nach 1/12 der gemessenen Zeit die 1. LED anschalten, nach 
einem weiteren 12tel will ich die 2. LED anschalten und so weiter.

Dafür brauch ich die Division.

Aber mit deine Idee mit Register nach Links verschieben ist eine gute 
Idee, werde ich mal weiter nachverfolgen. Allerdings problematisch, wenn 
ich im Register 0xFF geladen habe und das dann verschiebe, weil ich dann 
die obersten 1er verliere.

Autor: L. K. (ladde)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Brauchst du wirklich 32bit Auflösung für die zu messende Zeit? In 
welchem Bereich (von - bis) liegen denn die zu messenden Zeiten?

Für 32bit ist wohl die entsprechende Dividier-Routine von elm-chan die 
einfachste Lösung:

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

Die könnte man sicher noch kürzen, da dein Divisor ja in ein einzelnes 
8bit-Register passt.

Wenn es nicht absolut genau sein muss, könnte man auch mit 21 
multiplizieren und dann das niederwertigste Register verwerfen. (x * 21 
/ 256 = x / 12,19...)

Autor: Fabian S. (fabian727)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
wie kommst du auf die zahl 21?

Wie groß die zeit min und max ist, hab ich mir noch nicht so viele 
Gedanken gemacht. Aber ich habe festgestellt, wenn ich einfach so 11 / 
12 teile und den rest wegschmeis, bleibt mir als ergebnis 0 über. Im 
"obersten / höchstwertigsten" Register ist das verdammt viel Zeit die 
ich wegwerfe, wodurch meine LED's zu früh angehen.

Autor: Fabian S. (fabian727)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
ich habe mir mal die vorgeschlagene 32-bit-divison angeschaut.

Leider bin ich noch blutiger anfänger (mit maximal 30 h "erfahrung")
und kann mit meinem Wissen diese Schleife noch nicht richtig deuten.

Ich habe mir erlaubt meine Kommentare noch weiter rechts hinzuschreiben.
Die bezifferten Kommentare sind fragen meinerseits, bzw versuchte 
Interpretationen, bei denen ich mein Wissen hingeschrieben habe, bei 
denen ich aber glaube, dass sie nicht richtig sind

Die weiter rechts sind einfach nur Kommentare von mir, um den 
Programmcode soweit möglich zu verstehen.
Bitte trotzdem wieder durchlesen und korrigieren.


Bitte helft mir das zu verstehen.
Und vielen dank für eure Hilfe bis hier hin.

fabi

Autor: Fabian S. (fabian727)
Datum:
Angehängte Dateien:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
achja der programmcode, als anhang

Autor: Sascha Weber (sascha-w)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
(1) don't care = egal !
und lc ist der Loopcounter 32 für eine 32Bit Division

(2) siehe 1

(3) PC=Programmcounter PC+6 müsste dann zu <dec lc> springen, warum hier 
keine Marken verwendet werden ??

(4) wie 3 nur das wenn lc noch nicht 0 zu <lsl var10> gesprungen wird

Sascha

Autor: Fabian S. (fabian727)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
vielen Dank für diene ekrlärung, hilft schon einiges weiter das programm 
zu verstehen

Autor: Karl Heinz Buchegger (kbuchegg) (Moderator)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Fabian Scheidig schrieb:

> Wie groß die zeit min und max ist, hab ich mir noch nicht so viele
> Gedanken gemacht. Aber ich habe festgestellt, wenn ich einfach so 11 /
> 12 teile und den rest wegschmeis, bleibt mir als ergebnis 0 über. Im
> "obersten / höchstwertigsten" Register ist das verdammt viel Zeit die
> ich wegwerfe, wodurch meine LED's zu früh angehen.

Das kommt halt auf die Zeit drauf an.
Wenn deine Register die Zeit in Millisekunden zählen, dann sind 11 
Millisekunden nicht so wahnsinnig viel Zeit.


Im übrigen. Ja natürlich. Das Problem hast du immer. Mathematiker nennen 
das das Schubladenargument: Es ist nicht möglich n Socken in m 
Schubladen zu verstauen, so dass in allen Schubladen gleich viele Socken 
drinnen sind. Es sei denn n ist ein ganzzahliges Vielfaches von m.

So ist das nun mal, wenn man mit ganzen Zahlen hantiert. Da musst du dir 
was einfallen lassen, wie du die Situation handhaben willst.

Autor: Fabian S. (fabian727)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
soweit, ich die divisions-schleife verstanden hab, ist die einfach nur 
genial und ich werde sie verwenden.

Mir ist klar, dass ich den allerletzten rest nicht verwenden kann, aber 
ich will halt den rest vom höchstwertigsten Register noch im 
2.höchstwertigsten verwenden, weil sonst einfach irre viel zeit weg 
geht.

Ich habs ausgerechnet, was für zeiten ich hab. Meine min:0,17 sec. und 
meine max: 1,7 sec.

Jetzt muss ich sie nur noch bis zum ende durch verstehen und dann für 
mich modifizieren. Vielen Dank, weitere Proleme kommen sicher bald, 
vielen Dank noch mal an alle


p.s. wo finde ich solche Schleifen?

fab

Autor: Jobst M. (jobstens-de)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Du kannst Deine 32-Bit Zahl mit 357913941 (auch 32 Bit) multiplizieren.
Von dem 64-Bit Ergebnis schmeisst Du die unteren 32 Bit einfach weg.
Evtl. verwendest Du von den unteren 32 Bit das MSB zum Runden.


Gruß

Jobst

Autor: Dennis H. (t1w2i3s4t5e6r)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Jobst M. schrieb:
> Du kannst Deine 32-Bit Zahl mit 357913941 (auch 32 Bit) multiplizieren.
> Von dem 64-Bit Ergebnis schmeisst Du die unteren 32 Bit einfach weg.
> Evtl. verwendest Du von den unteren 32 Bit das MSB zum Runden.

Auch wenn ich nicht der TO bin, interessiert mich dieses Thema auch 
gerade ziemlich und würde gern mal den Sinn hinter deinem geschriebenen 
verstehen wollen. Also wie kommst du auf die 357913941?


MfG Dennis

Autor: Jobst M. (jobstens-de)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Dennis H. schrieb:
> wie kommst du auf die 357913941?

2^32 / 12

Du Multiplizierst also mit 1/12 und schmeisst die Nachkommastellen weg.


Gruß

Jobst

Autor: Dennis H. (t1w2i3s4t5e6r)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Jobst M. schrieb:
> Dennis H. schrieb:
>> wie kommst du auf die 357913941?
>
> 2^32 / 12
>
> Du Multiplizierst also mit 1/12 und schmeisst die Nachkommastellen weg.
>
>
> Gruß
>
> Jobst

Das leuchtet sogar mir ein, das ist ja mal ein richtig interessanter 
Ansatz.

Aber du lässt da sozusagen die Nachkommastellen einfach unter den Tisch 
fallen? Also wenn ich 2^32/12 rechne, habe ich ja nach dem Komma noch 
.33333..33 stehen.

Vielen Dank für die gute Erklärung


MfG Dennis

Autor: Jobst M. (jobstens-de)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Eine genauere Auflösung als ein LSB hast Du eben nicht. Egal, ob Du 
teilst oder multiplizierst.
Ich hatte ja auch vorgeschlagen, das MSB der unteren 32-Bit zum runden 
zu benutzen.


Gruß

Jobst

Autor: spess53 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hi

Wo ist eigentlich das Problem? Du dividierst eine Zahl durch 12 und 
bekommst einen Rest von 0..11. Was willst du jetzt machen? War schon 
meine Frage hier:

Beitrag "Re: [avrassembler] Division Problem mit Rest"

MfG Spess

Autor: Jobst M. (jobstens-de)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
spess53 schrieb:
> Was willst du jetzt machen? War schon
> meine Frage hier:

Nur, daß es nun eine andere Person ist ;-)

Dennis H. schrieb:
> Auch wenn ich nicht der TO bin

;-)



Aber stimmt schon: Entweder rundest Du, schneidest ab, behältst einen 
Rest oder fügst Nachkommastellen an.



Gruß

Jobst

Autor: Dennis H. (t1w2i3s4t5e6r)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Jobst M. schrieb:
> Eine genauere Auflösung als ein LSB hast Du eben nicht. Egal, ob Du
> teilst oder multiplizierst.

Stimmt schon, und bei einer 32Bit Zahl sollte das nicht so ganz ins 
Gewicht fallen. Ich glaube, in den seltensten Fällen benötigt man so 
genaue Berechnungen, schwierig wirds bloß, wenn man mit dem errechneten 
Wert noch lange weiter rechnet, weil sich dann der Fehler schnell 
potenziert. Aber trotzdem vielen Dank für die ehrlich gesagt sehr 
elegante Lösung, die gefällt mir richtig gut.


MfG Dennis

Autor: fabian727 (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Auch von mir vielen dank an alle, die mir weiter geholfen haben.

Mein Problem war, dass ich vier Register durch 12 dividiert hatte und 
somit mir 4 mal ein Rest zwischen 0 und 11 übergeblieben ist. Wobei ich 
davon die "oberen oder höherwertigeren" Reste hätte noch verwenden 
können. Ich wusste aber nicht wie.
Mit der 32-Bit-Division, die oben als Textanhang dabei ist, hat sich 
mein problem gelöst und der letzte Rest kann einfach verfallen.

Vielen Dank noch einmal an alle,


fabi

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




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 erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net