Forum: Mikrocontroller und Digitale Elektronik Komma Berechnungen mit dem AVR (ATtiny oder ATmega)


von Ralf B. (Gast)


Lesenswert?

Hallo,

aufgrund gewisser Algorithmen sehe ich mich im Moment gezwungen mich
mit dem Thema "Berechnungen mit Kommastellen auf einem AVR
Mikrocontroller"  zu beschäftigen.

Die Grundvoraussetzungen:

a= 0...255
b= 0...255
c = 0...255
d = 0...255

Die Formeln:

x = ( 4 + ( (a-b) / (c-d) ) *60
y = (c - d) / c

Das Ergebniss der ersten  Formel hat einen Wertebereich von 0...360 (
die 4 könnte auch eine 0 oder 2 sein).
Die zweite Formel ergibt einen Wertebereich von 0...1

Mein Problem ist nun das folgende:

Da ich in assembler programmiere, bin ich es schlicht und einfach nicht
gewohnt mit Kommazahlen zu programmieren. Genauer gesagt, mir fehlt
defakto ein Gedankenansatz dafür.

Aufgrund der Tatsache das ich die Ergebnisse später weiter verwenden
möchte schwebt mit eine Genauigkeit von 4 oder 5 Nachkommastellen vor.

Meine Frage dazu: Wie könnte man soetwas realisieren ?! (kein Code
sondern Gedankenansätze)


Grüße,

Ralf B.

von hans dieter (Gast)


Lesenswert?

fixkomma 8 + 8 bit
dividieren und multiplizieren kann man mit add und shift in einer
schleife.
schreib dir mal ein paar einfache beispiele in binär auf unsd dann
dividiere wie in der grundschule

von Profi (Gast)


Lesenswert?

Wenn Du die 360 mit 5 Nachkommastellen brauchst, also 8 gültige Stellen,
brauchst Du 26 Bits (36000000 = 0x2255100).
Wenn Du sagst, 4-5 Nachkommastellen, genügen evtl. 24 Bits (3 Bytes).

Für 0..1 mit 4-5 Stellen sind 16 bits (2 Bytes) ausreichend.

Multiplizieren geht mit ein paar MUL- und ADD-Befehlen, Dividieren mit
einer Schleife.

Was passiert mit den Ergebnissen? Davon hängt es auch noch ab, wie die
Zahlen optimal dargestellt werden.

Beim Fixkomma-Rechnen skaliert (multipliziert) man alle Größen (meist
mit einem Vielfachen von 2).

Lies mal den Thread "Rechnen mit dem AVR", da habe ich ein wenig dazu
geschrieben.

von Dietmar (Gast)


Lesenswert?

@Ralf:
Die Klammerung eines Ausdruckes stimmt nicht.
4 offene Klammern, 3 geschlossene.
Da gibt es mehrere Möglichkeiten, ich kann nicht raten, wie es richtig
sein sollte.

Darum mache ich mal ein eigenes Beispiel (das ist schon gut 10 Jahre
her mit dem 8051, ist aber beim AVR sicher gleiches Prinzip, mal sehen,
ob ich das vom Prinzip noch hinkriege):

Angenommen, man will x = a * b / c.

Kommastellen treten nur durch die Division auf.
Sei a = 10d; b = 10d; c = 3d. (Postfix d = dezimal)
Das Ergebnis soll 33,3333d sein.

Jetzt rechne ich zuerst den Zähler des Bruches: x = a * b
in einer Binärmultiplikation. In x steht das Teilergebnis 100d oder in
Binärform 64h.

Pro erwünschter Nachkommastelle muß man das Ergebnis vor der Division
mit dem Faktor 10d erweitern, also für 4 Nachkommastellen mit 10000d
multiplizieren: x = x * 10000d.
Gebe ich im Assembler 10000d o.ä. Syntax (dezimal) an, wandelt der die
Konstante automatisch nach binär bzw. hexadezimal (2710h).
In 4 Einzelschritten nacheinander mit 10d (0ah) multiplizieren ist
genauso möglich, je nachdem was die Rechenroutine zuläßt.
Jetzt steht in x das Teilergebnis 1000000d, aber in Binärform als
0F4240h.

Erst danach dividiert man: x = x / c.
Erfordert eine Divisionsroutine 32bit/16bit oder 32bit/32bit o.ä..
Ergibt 333333d, steht noch in Binärform (051615h) im Speicher x.

Dann wandelt man das Ergebnis von Hexadezimal (binär) nach Dezimal.
Dafür brauchst du eine Wandlungsroutine bin-bcd, am besten mit
einstellbarer Bitbreite. Entweder du schreibst sie selbst oder suchst
im Netz danach.

Beim Ergebnis, sind die 4 Stellen rechts jetzt Nachkommastellen. D.h.,
gibt man sie z.B. am Display aus, muß man den Dezimalpunkt von der
niedrigstwertigen Stelle 4 Stellen nach links schieben.

Ich hoffe, das hilft zumindest mal fürs Verständnis. Mit den
Bitbreiten mußt du dich dann noch etwas herumärgern:-)

Gruß

Dietmar

von Ralf B. (Gast)


Lesenswert?

Nuja, die Klammer die fehlte kommt vor die + 60 ... is mir gar net
aufgefallen, das ich die übersehen habe ....

Hmm, das liest sich soweit ganz simpel und schlüssig ... trotzdem
bleiben mir jede Menge Fragen offen ...

z.B. wo definiere ich das Komma ?!
a) im Binären oder
b) im Dezimalem Bereich ?!

nuja .. ich glaube, das werde ich mal in aller Ruhe auskaspern ... bei
nem Bier oder so.

Grüße,

Ralf B.

von Dietmar (Gast)


Lesenswert?

@Ralf:

Ich hoffe, das Bier hat geschmeckt.......

Das Komma ist völlig Wurscht: Das ist bei Binärzahl und Dezimalzahl
gleich.

Gruß:-)

Dietmar

von Ralf B. (Gast)


Lesenswert?

Hallo,

Nuja, das Prinzip hab ich glaube erst mal verstanden ...

Ich muss mir meine Formeln nur so umbauen, das ich die Anzahl der
gewünschen Nachkommastellen im Ganzzahlenbereich hab (mit nem Faktor).


Eine Frage hab ich nun allerdings noch,

ist der Faktor absolut egal ?
Also kann ich anstatt z.B. 100d auch 100h nehmen ?

Grüße,

Ralf B.

von Profi (Gast)


Lesenswert?

"Also kann ich anstatt z.B. 100d auch 100h nehmen ?"

Ja, habe ich doch oben schon geschrieben:
Was passiert mit den Ergebnissen? Davon hängt es auch noch ab, wie die
Zahlen optimal dargestellt werden.

Beim Fixkomma-Rechnen skaliert (multipliziert) man alle Größen (meist
mit einem Vielfachen von 2).


Kommt darauf an, in welchem Wertebereich die Eingangsvariablen liegen
und  was Du danach mit dem Ergebnis machen willst.

Anzeigen, weiterrechnen, abspeichern, vergleichen??

von Ralf B. (Gast)


Lesenswert?

Die Ergebnisse werden in gewissen anderen Berechnungen weiterverwendet
und im Endeffekt auch ausgegeben.

Nuja .. ich setz mich jetzt erst mal hin und bau die Formeln um ...
besser ist das.

Grüße.

Ralf B.

von Dietmar (Gast)


Lesenswert?

@Ralf:

Wie im Beispiel oben beschrieben, so ähnlich habe ich z.B. das Ergebnis
einer AD-Wandlung 10 bit einer Spannungsmessung auf einem LCD-Display
ausgegeben.

Für eine weitere Verwendung des Ergebnisses, spielen wiederum die
Anforderungen an die weitere Anwendung, z.B. Genauigkeit, eine Rolle.
Und die Überlegungen mit Bitbreiten und Skalierungen beginnen von
neuem. Berechnungen in Assembler sind gegenüber C jedoch eine reine
Sysiphusarbeit. Für ein industrielles Projekt lohnt sich daher auf
Dauer auch der hohe Anschaffungspreis eines C-Compilers, da man dann
mit den Umsetzungen und Umwandlungen nichts mehr am Hut hat. Den Preis
holt man durch Zeitersparnis wieder rein.

Vielleicht kannst du auch mal einen Gedanken daran verschwenden,
Fließkomma in Assembler zu programmieren. Das ist zwar ein schöner
Aufwand, aber dann hat man wenigstens mit den Bitbreiten nichts mehr am
Hut, da die dort fest sind (z.B. 24 bit Mantisse, 8 bit Exponent). Und
der Wertebereich ist enorm. Vielleicht findet sich sogar was fertiges
im Netz.

Wenn ich mich recht erinnere, gibt es z.B. von Microchip, kostenlos
downloadbar, Fließkomma-Routinen in Assembler für den PIC.

Langsam muß Fließkomma auch nicht sein: Bei meinen gegenwärtig
verwendeten Philips LPC2000 (ARM7, 32 bit) rechnet Fließkomma schneller
als die Rechnung mit Integer-Werten. Das kannte ich bisher nicht, und es
ist wirklich enorm!

Gruß

Dietmar

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.