mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik dtostrf optimieren


Autor: Alexander L. (alexl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo.

Ich suche einen Weg die Funktion dtostrf platzsparender unterzubringen. 
Die Funktion dtostrf ist dafür da, einen Float-Wert in einen Ascii-Wert 
umzurechnen, damit er bspw. auf einem LCD wiedergegeben werden kann.

Da ich Einsteiger in Sachen MC bin wollte ich mal fragen, ob es möglich 
ist diese Funktion mit wenigen Befehlen selbst zu schreiben... der 
Platzbedarf im Speicher des MCs ist nämlich enorm.

Anwendung:
Ich messen ein Spannung am ADC und möchte diesen im mV Bereich auf einem 
LCD ausgeben. Da das Programm recht groß ist komme ich langsam an die 
Grenzen des Speichers...

Vielen Dank für eure Antworten,

Alex

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das kommt ein wenig darauf an, welchen µC im Einsatz ist und wie dein 
float-Typ aufgebaut ist. Vielleicht hast Du ja noch ein paar weitere 
Informationen.

Autor: Alexander L. (alexl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Natürlich. Ich benutze einen AtMega8538


volatile double Spannung; //Ergebnis der Spannungsumrechnung
volatile double Spannungs; //Speichervariable für max. gemessenen Spannungswert
volatile uint16_t Messwert; //Gemessener Wert
char u[9];

while (bit_is_set(PINC,PINC0)!=0) {
Messwert = ReadChannel(3); //ADC Messung an PORTA Bit 3
Spannung=(float) 2*Messwert/1.023; //Hinweis: AREF=2V
if (Spannungs<Spannung) Spannungs=Spannung; //Nur Maximalwert ausgeben
dtostrf(Spannungs,7,2,u); //<= Sehr Speicherintensiv
lcd_gotoxy(0,0);
lcd_puts("Mik. ");
lcd_puts(u);
lcd_puts("mVss");
delay_ms(50);
}

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alexander L. wrote:

> Ich suche einen Weg die Funktion dtostrf platzsparender unterzubringen.

Diese Funktion benötigt die float Library und diese ist so 
speicherintensiv (AVR-GCC: etwa 2kB).

Wenn der Speicher knapp wird, mußt Du nen größeren nehmen oder in int 
(long) rechnen.

Z.B. um 2 Nachkommastellen anzuzeigen, zu Anfang mit 100 multiplizieren 
und dann für die Ausgabe x/100 bzw. x%100 (positive Zahlen).


Peter

Autor: Alexander L. (alexl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:
>Z.B. um 2 Nachkommastellen anzuzeigen, zu Anfang mit 100 multiplizieren
>und dann für die Ausgabe x/100 bzw. x%100 (positive Zahlen).

Hallo Peter!

Erst mal Danke für Deine Hilfe!

Wie meinst Du das genau? Entsteht durch x/100 nicht wieder ein 
Float-Wert? Vielleicht verstehe ich nicht, was Du meinst.
volatile uint16_t Spannung; //nun Ganzzahl
[...]
Spannung=2*Messwert;
//bei Spannung=0,02V wäre die Var Spannung=20;
//Wie bekomme ich nun das Ergebnis als Float anzeigt?


Gruß,

Alex

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In dem Du eine Int-Anzeige machst, aber in den erzeugten String an der 
passenden Stelle einen Dezimalpunkt einfügst.

Autor: Alexander L. (alexl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
aaah - jetzt verstehe ich es.

float Spannung
int Ganzzahlteil

Spannung=100,23mV
Ganzzahlteil=Spannung
Ausgabe Ganzzahlteil + "."
Spannung=Spannung-Ganzzahlteil

Spannung=Spannung*100
Ausgabe Spannung

Vielen Dank! Ihr habt mir echt weitergeholfen!

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt hast du ja wieder float drin.

Das ganze ist eher so gemeint, dass du statt float nen ganzzahligen 
Typen verwendest, nur dass du zum Beispiel "3,45V" zum Beispiel als 
"3450mV" "abspeicherst". Da ist kein Komma drin, ergo auch kein float 
nötig. In deiner anzeigen Routine musst du jetzt nur regeln, dass nach 
der dritten Stelle von Hinten ein Komma eingefügt wird. Schon wird aus 
dem als mV abgelegten Wert, wieder ein Kommawert mit der Einheit Volt.

PS: Um das nochmal klar zu machen: Nicht dtostrf braucht viel Speicher, 
sondern die Float-lib. Die holst du dir sofort ein, wenn du eine 
float-Variable deklarierst, die nicht im Vorhinein (während des 
Kompilierens) bestimmt werden kann und zur Laufzeit ausgerechnet werden 
muss.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, eher so:

  int Spannung;

  int Vorkomma;
  int Nachkomma;

  Spannung = 10023;

  Vorkomma = Spannung / 100;
  Nachkomma = Spannung % 100;

  Ausgabe Vorkomma + "."

  Ausgabe Nachkomma (mit führenden Nullen!)

Autor: Alexander L. (alexl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Simon Küppers wrote:
> Jetzt hast du ja wieder float drin.
>
> Das ganze ist eher so gemeint, dass du statt float nen ganzzahligen
> Typen verwendest, nur dass du zum Beispiel "3,45V" zum Beispiel als
> "3450mV" "abspeicherst". Da ist kein Komma drin, ergo auch kein float
> nötig. In deiner anzeigen Routine musst du jetzt nur regeln, dass nach
> der dritten Stelle von Hinten ein Komma eingefügt wird. Schon wird aus
> dem als mV abgelegten Wert, wieder ein Kommawert mit der Einheit Volt.
>
> PS: Um das nochmal klar zu machen: Nicht dtostrf braucht viel Speicher,
> sondern die Float-lib. Die holst du dir sofort ein, wenn du eine
> float-Variable deklarierst, die nicht im Vorhinein (während des
> Kompilierens) bestimmt werden kann und zur Laufzeit ausgerechnet werden
> muss.

Da habe ich was anderes festgestellt. Wenn ich die dtostrf-Funktion 
drinnen habe sind nach dem Compilieren 98,5% belegt - wenn ich diese 
rausnehme und durch mein oben genanntes Beispiel ersetzte bin ich bei 
85,5%.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Prozentangaben sagen nichts*, hier zählen absolute Werte.

Hast Du Dir mal die von mir gepostete reine Int-Version angesehen?



*) bei einem Mega8 sind 95% was anderes als bei einem Mega128 ...

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.