Winavr: Float -> LCD, brauche Beispiel

Im Unterforum Microcontroller - Beschreibung: Hardware - Software - Ideen - Projekte

Elektronik Forum Nicht eingeloggt       Einloggen       Registrieren




[Registrieren]      --     [FAQ]      --     [ Einen Link auf Ihrer Homepage zum Forum]      --     [ Themen kostenlos per RSS in ihre Homepage einbauen]      --     [Einloggen]

Suchen


Serverzeit: 26 2 2026  23:42:13      TV   VCR Aufnahme   TFT   CRT-Monitor   Netzteile   LED-FAQ   Oszilloskop-Schirmbilder            


Elektronik- und Elektroforum Forum Index   >>   Microcontroller        Microcontroller : Hardware - Software - Ideen - Projekte


Autor
Winavr: Float -> LCD, brauche Beispiel
Suche nach: lcd (4712)

    







BID = 642142

Harald73

Schreibmaschine


Falsches Format
*.gif oder *.jpg
verwenden!
Beiträge: 1016
 

  


Hi,

ich verzweifele hier langsam.
Problem:
Winavr, Programmers Notepad 2, C-code, AVR (ATMEGA 48), per fprintf eine Gleitkommazahl auf LCD ausgeben.
Die Abfrage der Compilerversion per avr-gcc –v an der Kommandezeile liefert
gcc version 4.3.2 (WinAVR 20090313)

Kommunikation mit dem LCD klappt,



Code :

fprintf(&lcd_str, "Pout= %dW\n",1346);


liefert auf dem Display:
Pout= 1346W

Aber


Code :

fprintf(&lcd_str, "Pout= %fW\n",1346.5);

oder
fprintf(&lcd_str, "Pout= %fW\n",(double)123.5);


liefert immer nur
Pout= ?W

Laut der Anleitung bedeutet das „?“, dass eine nicht float-fähige print-Routine eingebunden ist. Deswegen muss dann
PRINTF_LIB = -Wl,-u,vfprintf -lprintf_flt
MATH_LIB = -lm
ins makefile.

Ist aber schon drin (aber vielleicht an der falschen Stelle)! Fehlermeldungen gibt es nicht während „make all“.


Kurzum: ich bin am Ende!

Hätte vielleicht jemand ein Beispielprojekt für mich (also .c und Makefile), bei dem ich sehen kann, wie es sein muss?
"Einfach nur" ein "Hello World 12.45", das wäre super!!


Gruß
Harald


_________________
*..da waren sie wieder, meine 3 Probleme: 1)keiner 2)versteht 3)mich
* Immer die gültigen Vorschriften beachten und sich keinesfalls auf meine Aussagen verlassen!

BID = 642188

DonComi

Inventar



Beiträge: 8604
Wohnort: Amerika

 

  

Hallo Harald,

Das wird leider nichts mit 4kByte Speicher.
Die Gleitkommabibliothek ist recht groß (annähernd 4kByte ), sodass du dir was anderes ausdenken musst.

Oft, eigentlich in den meisten Fällen, benötigt man wahre Gleitkommaarithmetik gar nicht.
Man kann sich behelfen, in dem man z.B. mit größeren Ganzzahlen rechnet und in der Ausgabe dann entsprechend das Komma setzt.
Mit C++ ließe sich eine eigene Klasse erstellen, die dann mehr oder weniger wie Gleitkommazahlen nutzbar wäre, also mit überladenen Operatoren etc.

Nur, wie gesagt: Wenn du wirklich float/double benötigst, muss entweder der µC größer sein, oder dein Konzept überarbeitet werden .

Alternativ:
Hast du es mal zu Fuß versucht, also ohne Make?
Bei mir klappt das hervorragend...



Code :


all: main.o

main.o: main.c
avr-gcc -mmcu=atmega644 -DF_CPU=16000000 -Wl,-u,vprintf -lprintf_flt -o main.o main.c




_________________


[ Diese Nachricht wurde geändert von: DonComi am 20 Okt 2009 21:27 ]

BID = 642198

Harald73

Schreibmaschine


Falsches Format
*.gif oder *.jpg
verwenden!
Beiträge: 1016

Hallo,

am Speicher soll es nicht scheitern, dann stecke ich halt einen ATMega88 rein, oder mache es mit einem 644er, hab ich alles hier. Ob der µC nun 2Euro oder 5 Euro kostet ist mir im Vergleich zum restlichen Aufwand echt egal.
Ich hatte damit schon oft Probleme und habe es immer über irgendwelche Festkomma-Umwege und /10 Modulo 10-Konstruktionen gemacht.
Da ich jetzt aber eine Art Tabelle brauche (immer gleiche Zeichenanzahl) wollte ich mich mal an die Float-Ausgabe per print wagen.
Das es anders gehen kann mag sein, aber ich muss es einfach mal schaffen.

Ich bin nicht der einzige, der diese Probleme hat, ich finde zig Beiträge dazu. Aber ich bin offensichtlich nicht in der Lage, die Sachen richtig einzubinden. Sonst würde ich ja auch eine Fehlermeldung zum Speicherplatz bekommen, gell?
Je nach Forum gibt es dann auch schon mal echt hilfreiche Tipps, wie z.b. man solle das Manual lesen. Aber ein fertiges Projekt finde ich einfach nicht.
So was brauche ich aber, ein einfaches Beispiel.



Gruß
Harald

edit: Du hattest noch was dazugeschrieben, hab ich gerade erst gesehen.
Heisst dass, dass es bei dir über das Makefile NICHT geht?
Und: wie geht das von Hand? Woe gehört dein Code hin? Comandozeile???
Sag ruhig DAU zu mir...aber ich kann nicht mehr...


_________________
*..da waren sie wieder, meine 3 Probleme: 1)keiner 2)versteht 3)mich
* Immer die gültigen Vorschriften beachten und sich keinesfalls auf meine Aussagen verlassen!

[ Diese Nachricht wurde geändert von: Harald73 am 20 Okt 2009 21:54 ]

BID = 642206

DonComi

Inventar



Beiträge: 8604
Wohnort: Amerika

Guten Abend


Zitat :


edit: Du hattest noch was dazugeschrieben, hab ich gerade erst gesehen.
Heisst dass, dass es bei dir über das Makefile NICHT geht?
Und: wie geht das von Hand? Woe gehört dein Code hin? Comandozeile???
Sag ruhig DAU zu mir...aber ich kann nicht mehr...

Also das Programm make ruft ja auch nur die zur Erzeugung angegebener Ziele definierten Programme auf (z.b. gcc).
Also liegt es nicht an den Aufrufen von make, sondern an der fehlerhaften Regelsetzung innerhalb des Makefiles bzw schlichtweg falscher Parameter, z.B. für den Compiler...

Mein "Code" oben ist ein Auszug aus dem Makefile.
all ist das Ziel, und das ist abhängig von main.o.
main.o ist wiederum abhängig von main.c.

Jetzt sucht make die Regel, um main.o zu erzeugen. Dann geht es rekursiv vor, bis es das finale Ziel bauen kann (all).

Das mit dem Makefile funktioniert wie gesagt super, du musst obigen Auszug entsprechend an dein Makefile anpassen, alternativ sagst du mir die Randbedingungen, und ich tippe dir das Makefile dazu!
Randbedingungen wären dann oben in den Kopf einzutragen.
Wichtig für mich: wieviele Quellen hast du (C-Dateien), wie heißen sie genau und wie sollen sie verbunden (gelinkt) werden!

Zu Fuß heißt, du machst die Compileraufrufe manuell, aus der Shell.
Das klappte bei mir auch problemlos.

Mit den fertigen Makefiles kenne ich mich nicht aus - ich schreibe die immer selbst, dann kommt einem der Kram anderer Leute nicht so fremd vor bzw. man weiß genau, warum etwas nicht funktioniert.

Edit: hier sieht man das.
Das Kompilieren klappte prima (main.c enthält irgendein sinnbefreites Rumrechnen mit Gleitkommazahlen.)

_________________




[ Diese Nachricht wurde geändert von: DonComi am 20 Okt 2009 22:29 ]

BID = 642215

Harald73

Schreibmaschine


Falsches Format
*.gif oder *.jpg
verwenden!
Beiträge: 1016

Hi,

einen "Guten Abend" hätte ich auch gerne gehabt, aber Du trägts ja zu einer guten Nacht bei. Danke!

Ich würde gerne auf Dein Angebot der Makefile-Erstellung zurückgreifen.
Also, hier mein Code

Code :

/* ----------------------------------------------------------------------------

* "THE BEER-WARE LICENSE" (Revision 42):
* <joerg@FreeBSD.ORG> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
* ----------------------------------------------------------------------------
* Anzeige der ADC-Messwerte auf dem Display
* Das Display (Displaytech404B) hat zwei Kontroller und darum 2 Enable-Leitungen
*/

#include "defines.h"
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "lcd.h"
#include "uart.h"
#include "HD44780.h"

static void
ioinit(void)
{
uart_init();
lcd_init();
}

int
main(void)
{
uint16_t AD0 = 0; // Lokale Spannungsmessung
uint16_t AD1 = 0; // Lokale Strommessung

double Uout = 0.0;
double Iout = 0.0;
double Pout = 0.0;
double AD0Scale = 0.009; // max 10 V -> 1023, also 0.009775V pro LSB
double AD1Scale = 0.0009; // max 1 V -> 1023, also 0.0009775V pro LSB

//init
ioinit();

// Umleitung
FILE lcd_str = FDEV_SETUP_STREAM(lcd_putchar, NULL, _FDEV_SETUP_WRITE);
stderr = &lcd_str;

// Ewige Schleife
for (;;)
{
AD0 = 900; //Beispiel = 8.79V. Hier kommt spaeter die ADC-Abfrage hin
AD1 = 300; // = 0.29A

Uout = (float)AD0 * AD0Scale;
Iout = (float)AD1 * AD1Scale;
Pout = Uout * Iout;
fprintf(stderr, "Pout= %fW\n",Pout); // Liefert "Pout= ?W"
//fprintf(stderr, "Pout= %dW\n",(uint16_t)Pout); //Klappt
_delay_ms(250);
}
return 0;
}


, der mit diesem Makefile


Code :

PRG            = Multimeter_ATM48_4x40_01

OBJ = Multimeter_ATM48_4x40_01.o hd44780_DualKS66.o lcd.o uart.o
MCU_TARGET = atmega48
OPTIMIZE = -Os
PRINTF_LIB = -Wl,-u,vfprintf -lprintf_flt
MATH_LIB = -lm

DEFS =
LIBS =

# You should not have to change anything below here.
CC = avr-gcc

CFLAGS = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)
LDFLAGS = -Wl,-Map,$(PRG).map

OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump


all: $(PRG).elf lst text
# original all: $(PRG).elf lst text eeprom
$(PRG).elf: $(OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)


clean:
rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak
rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)

lst: $(PRG).lst

%.lst: %.elf
$(OBJDUMP) -h -S $< > $@

# Rules for building the .text rom images

text: hex bin srec

hex: $(PRG).hex
bin: $(PRG).bin
srec: $(PRG).srec

%.hex: %.elf
$(OBJCOPY) -j .text -j .data -O ihex $< $@

%.srec: %.elf
$(OBJCOPY) -j .text -j .data -O srec $< $@

%.bin: %.elf
$(OBJCOPY) -j .text -j .data -O binary $< $@

# Rules for building the .eeprom rom images

eeprom: ehex ebin esrec

ehex: $(PRG)_eeprom.hex
ebin: $(PRG)_eeprom.bin
esrec: $(PRG)_eeprom.srec

%_eeprom.hex: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@

%_eeprom.srec: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@

%_eeprom.bin: %.elf
$(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@

# Every thing below here is used by avr-libc's build system and can be ignored
# by the casual user.

JPEGFILES = stdiodemo-setup.jpg

JPEG2PNM = jpegtopnm
PNM2EPS = pnmtops
JPEGRESOLUTION = 180
EXTRA_CLEAN_FILES = *.hex *.bin *.srec *.eps

dox: ${JPEGFILES:.jpg=.eps}

%.eps: %.jpg
$(JPEG2PNM) $< |\
$(PNM2EPS) -noturn -dpi $(JPEGRESOLUTION) -equalpixels \
> $@


fehlermeldungsfrei compiliert und sich per AVR Studio + STK500 auf den ATMega laden lässt, aber nur "?" statt der Zahl liefert.
Im makefile steht noch irgendwelcher JPEG-Kram drin, den brauch ich nicht, aber ich wollte jetzt nicht noch mehr ändern. (Never change...)

Es wäre echt toll, wenn Du mir das Makefile reparieren könntest

Edit: "Die Randbedingungen": Es wird also neben den Hauptprogramm
* Multimeter_ATM48_4x40_01.o (.c)
noch
* hd44780_DualKS66.o (.c)
* lcd.o (.c) und
* uart.o (.c)
benötigt.
Optimierung ist absichtlich aus, den Rest vom Makefile verstehe ich selber auch nicht, hat bisher aber immer geklappt.

Danke und Gute Nacht!

Gruß
Harald




_________________
*..da waren sie wieder, meine 3 Probleme: 1)keiner 2)versteht 3)mich
* Immer die gültigen Vorschriften beachten und sich keinesfalls auf meine Aussagen verlassen!

[ Diese Nachricht wurde geändert von: Harald73 am 20 Okt 2009 23:20 ]

BID = 642222

DonComi

Inventar



Beiträge: 8604
Wohnort: Amerika

Moin!


Offtopic :

Mein Tag war auch nicht grade der Oberknaller... Aber was solls


Die Lösung ist denkbar einfach:
Im Kopf wird zwar PRINTF_LIB definiert, auch mit den richtigen Parametern, aber dieses Makro wird nirgends genutzt .

Mache mal aus den Zeilen:

$(PRG).elf: $(OBJ)

$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)


folgendes:

$(PRG).elf: $(OBJ)

$(CC) $(CFLAGS) $(PRINTF_LIB) $(LDFLAGS) -o $@ $^ $(LIBS)


Um die libm mitzulinken noch folgendes Ergänzen:

$(PRG).elf: $(OBJ)

$(CC) $(CFLAGS) $(PRINTF_LIB)
-lm $(LDFLAGS) -o $@ $^ $(LIBS)

So sollte es dann klappen .
Viel Erfolg.

Edit: Die Ergänzungen bitte nicht per Copy&Paste erledigen, Make benötigt unbedingt z.B. korrekte Tabulatoreinrückungen! Einfach beide Parameter dazuschreiben, dann klappt es .

_________________


[ Diese Nachricht wurde geändert von: DonComi am 21 Okt 2009  0:01 ]

BID = 642225

Harald73

Schreibmaschine


Falsches Format
*.gif oder *.jpg
verwenden!
Beiträge: 1016



Super, das war's, musste nur noch den Typ auf ATmega88 stellen, reinstecken und schwuuuups, schon habe ich
Pout = 2.187000W auf dem Display.


Aber sag mal, muss ich jetzt das Gefühl haben total doooof zu sein, dass ich das nicht selber gefunden habe? Vielleicht sollte ich wieder meine alte Conrad C-Control rauskramen und in Basic programmieren...

Gruß
Harald

PS:
Zitat :
Mein Tag war auch nicht grade der Oberknaller... Aber was solls

Wärme Dich an dem wohligen Gedanken mir echt geholfen zu haben!

_________________
*..da waren sie wieder, meine 3 Probleme: 1)keiner 2)versteht 3)mich
* Immer die gültigen Vorschriften beachten und sich keinesfalls auf meine Aussagen verlassen!

BID = 642232

DonComi

Inventar



Beiträge: 8604
Wohnort: Amerika

Freut mich

Edit:

Zitat :
Aber sag mal, muss ich jetzt das Gefühl haben total doooof zu sein, dass ich das nicht selber gefunden habe?

Würd ich nicht sagen. Schließlich erwecken diese Programme, die z.B. Makefiles generieren, den Eindruck, dass man die erzeugten Makefiles nicht selbst editieren muss, damit es dann klappt.
Gut, man mag vielleicht noch im Header/Kopf des Makefiles was nachträglich definieren, aber bis zum Rumpf ließt doch keiner...
Und das fiese ist ja, dass hier nicht gemeckert wird! Normalerweise kommen ja wenigstens Fehlermeldungen ...

Gerade um sowas zu vermeiden habe ich mir das Konzept von make angeeignet, inkl. natürlich die entsprechende Syntax und Logik.
Im Prinzip ist das kinderleicht.

Es geht immer nach dem Schema:
Ziel: Quelle
Regel, um Ziel aus Quelle zu erzeugen

Diese Abhängigkeiten von Ziel zu Quelle werden selbstständig aufgelöst, entweder, bis Fehler auftreten (Ziel hat keine Quelle) oder bis alles aufgelöst und rekursiv erzeugt wurde.
Dazu kommen dann noch heftige Dinge, die make übernehmen kann.


_________________


[ Diese Nachricht wurde geändert von: DonComi am 21 Okt 2009  1:01 ]


Zurück zur Seite 0 im Unterforum          Vorheriges Thema Nächstes Thema 


Zum Ersatzteileshop


Bezeichnungen von Produkten, Abbildungen und Logos , die in diesem Forum oder im Shop verwendet werden, sind Eigentum des entsprechenden Herstellers oder Besitzers. Diese dienen lediglich zur Identifikation!
Impressum       Datenschutz       Copyright © Baldur Brock Fernsehtechnik und Versand Ersatzteile in Heilbronn Deutschland       

gerechnet auf die letzten 30 Tage haben wir 12 Beiträge im Durchschnitt pro Tag       heute wurden bisher 5 Beiträge verfasst
© x sparkkelsputz        Besucher : 189625771   Heute : 14760    Gestern : 16450    Online : 133        26.2.2026    23:42
9 Besucher in den letzten 60 Sekunden        alle 6.67 Sekunden ein neuer Besucher ---- logout ----viewtopic ---- logout ----
xcvb ycvb
0.214914083481