Winavr: Float -> LCD, brauche Beispiel Im Unterforum Microcontroller - Beschreibung: 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 ]
|
|
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
|