www.mikrocontroller.net

Forum: Compiler & IDEs rechnen ohne float


Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe das vergangene Wochenende an meinem Problem getüftelt, bin
aber nicht so recht weiter gekommen. Bestimmt kann mir jemand helfen,
damit ich nicht noch ein Wochenende über mein Problem brüte.

Also, ich habe an einen ATMega32 einen 24-Bit ADC (LTC2400)
angeschlossen, das funktioniert auch alles soweit. Nun möchte ich die
gemessene Spannung auf ein LED-Display ausgeben (das LED-Display wird
von einem MAX7221 angesteuert / acht 7-Segment Anzeigen). Die
Referenzspannung für den ADC beträgt genau 5 Volt. Also muss ich
folgende Berechnung durchführen: Referenzspannung geteilt durch 1677216
(Auflösung 24-Bit) mal gelieferte Bits von ADC. Oder auch
(5/16777216)*Bits vom ADC. Das möchte ich ohne Float Operationen
programmieren, ich benötige auch nur 4 Stellen hinter dem Komma.

Kann mir jemand helfen, hat jemand eine Idee ...

Vielen Dank für eine Antwort

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daumenregel für solche Rechnungen, wenn per Integer: Erst
multiplizieren, dann dividieren. Sonst kommt meist 0 raus. Aber
Wertebereich beachten, gibt gerne Überlauf.

Erster Ansatz: (ADC-Wert-24bit  5  10000) / 1677216 => 0..49999.
Problem: Produkt passt nicht in 32 Bits. Entweder 64-Bit-Rechnung,
oder:

Zweiter Ansatz: Vom ADC-Wert das letzte Byte weglassen, weil bei 4
Nachkommastellen allenfalls für die Rundung der letzten Stelle von
Belang. Dann also: (ADC-Wert-16bit  5  10000) / 65536. Das geht nun
mit 32-Bit-Rechnung.

Autor: Alexander (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das dividieren eventuell noch durch Schiebeoperationen ersetzen.

/65536
>>16

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und hast du dir den generierten Code mal angeguckt?

Der ist identisch.

Autor: MSE (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Jörg:
Ist das immer so oder 'nur' wenn man Optimierungen einschaltet?

Gruß, Michael

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich neige auch dazu, solche Feinheiten den Compilern zu überlassen. Aber
ich dachte bis vor Kurzem auch, dass schon die Compiler vor 20 Jahren
diesen Trick beherrschten, das müsste heute also selbstverständlich
sein. Ist jedoch leider nicht immer so. Der IAR/ARM Compiler entblödet
sich nicht, sowas (% mit 2-er-Potenz, unsigned, also nix anderes als
AND) allen Ernstes per Laufzeit-Division abzuwickeln.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Der IAR/ARM Compiler...

Deswegen sind wir ja hier auch im GCC-Forum g

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die Hilfe, ich bin jetzt allerdings auf das
"Folgeproblem" gestossen. Beim Compilieren gibt mir der Compiler
(WinAVR) die Warnmeldung aus: warning: integer overflow in expression,
und das Ergebnis stimmt auch nicht.

qword = (6711445*5*10000)/16777216; // Berechnung Volt

Die Variable qword ist mit uint64_t als 64 Bit-Zahl deklariert, also
kann man Ganzzahlen zwischen 0 und 18446744073709551615 in dieser
Variable dastellen (mein ich zumindest). Das Produkt der Multiplikation
ligt aber unterhalb deieser Grenze. Warum funktioniert das nicht, kann
mir vielleicht jemand einen Tipp geben.

Vielen Dank

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Produkt von Zahlen, die alle in 32 Bits passen, ist in C ein 32 Bit
Typ, egal ob's der Compiler berechnet, oder der Prozessor zur
Laufzeit. Und egal was links von der Zuweisung steht. Abhilfe: "LL"
an die Zahlen dranhängen, damit es 64 Bit Werte werden.

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt geht es, vielen Dank A.K.

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.