Ich helfe einem Freund bei einem kleinen Elektronikprojekt mit einem PIC-Mikrocontroller 16F877 (A), den ich mit mikroC programmiere.
Ich bin auf ein Problem gestoßen, nämlich dass ich eine Gleitkommazahl in einer Variablen habe, sagen wir zum Beispiel 1234.123456, und sie in Variablen aufteilen muss, die jede einzelne Zahl enthalten, damit ich Char1 = 1, Char2 = 2 usw. usw. für die Anzeige bekomme auf LCD. Die Zahl wird immer auf 3 oder 4 Dezimalstellen gerundet, daher sollte es notwendig sein, die Position des Dezimalpunkts zu verfolgen.
Jeder Rat, wie man diese Aufteilung erhält, wäre sehr willkommen.
Es gibt zahlreiche Möglichkeiten, dies zu tun. Möglicherweise hat Ihr Compiler eine Bibliotheksfunktion, die das für Sie erledigt. Es kann möglich sein mit:
Alternativ ist es nicht allzu schwer, dafür eine eigene Routine zu schreiben. Es geht nur darum, zuerst herauszufinden, wie viele Stellen vor dem Komma vorhanden sind, es so oft durch 10 zu dividieren, dann den ganzzahligen Teil wiederholt zu nehmen und dabei mit 10 zu multiplizieren, wobei darauf zu achten ist, dass das Komma an der richtigen Stelle hinzugefügt wird.
In Pseudo-Code kann es also so aussehen:
If the value < 0.0:
Insert - into string
Subtract value from 0.0 to make it positive.
While the value <= 10.0:
Divide by 10
Increment decimal counter
For each digit of required precision:
Take the integer portion of the value and place it in the string
Subtract the integer portion from the value
Decrement decimal counter
If decimal counter is 0:
Insert decimal point
Multiply the value by 10.
Verwenden Sie sprintf(). Es funktioniert genau wie printf(), aber "druckt" in eine Zeichenfolge (auch bekannt als ein Array von Zeichen).
do: char stringvar[10]; sprintf(stringvar, "%9.4f", floatvar);
Auf einer kleinen MCU ohne Hardware-Fließkommaunterstützung sollten wir so wenig Fließkommaberechnungen wie möglich durchführen, und wenn Sie die printf-Funktionsfamilie nicht wirklich benötigen, versuchen Sie, sie zu vermeiden, da sie den Code aufbläht und verlangsamt.
Ich schlage vor, den Float in eine Ganzzahl umzuwandeln, indem Sie den Float zuerst mit 1.000,0 multiplizieren (vorausgesetzt, Sie möchten drei Dezimalstellen) und ihn dann in eine lange Ganzzahl konvertieren und gegebenenfalls abrunden. Wenn Sie das Ergebnis auf einem 7-Segment- oder Punktmatrix-LCD anzeigen möchten, ist dieses Format meiner Meinung nach ideal.
Nehmen wir an, dass der Float im Bereich 0 bis 999,999 liegen kann (negieren, wenn negativ, Vorzeichen für spätere Anzeige speichern).
Pseudocode:
dig6 = -1 // Init MSDigit
while number >= 0
number = number - 100,000
dig6 = dig6 + 1
number = number + 100,000 // Restore number, Dig 6 is done
dig5 = -1
while number >= 0
number = number - 10,000
dig5 = dig5 + 1
number = number + 10,000 // number can be switched to 16-bit here for speed
... dig4 and 3 in similar fashion
dig2 = -1
while number >= 0
number = number - 10
dig2 = dig2 + 1
dig1 = number + 10
An dieser Stelle haben Sie alle sechs Ziffern in je einem Byte gespeichert und das Minuszeichen gespeichert. Wenn Sie ein 7-Segment-LCD verwenden, übergeben Sie die Ziffern an eine 7-Segment-Encoderfunktion, bevor Sie sie auf das LCD schreiben. Wenn Sie ein Punktmatrix-Display mit serieller Schnittstelle verwenden, fügen Sie für die ASCII-Codierung 0x30 zu jeder Ziffer hinzu. Wir müssen uns auch den Dezimalpunkt zwischen dig4 und dig3 merken.
Dieser Algorithmus ist ziemlich schnell, da es keine Multiplikation und Division gibt. Ich habe es auf winzigen 4-Bit-MCUs mit guten Ergebnissen verwendet.
Majenko
Peter Bennett
Majenko
Austin
Majenko
Austin