Forum: Mikrocontroller und Digitale Elektronik Float to String ATMega 16


von Timo (Gast)


Lesenswert?

Hallo ..
Das also ist mein erster Beitrag ... zu meiner Person muss ich sagen, 
dass ich eher die Hardwareseite bevorzuge ... mich dennoch für die 
Programmierung und die Umsetzung von Ideen interessiere ... für meine 
Belichtungsanlage benötige ich nun einen Timer ... Dieser Timer sollte 
Zentelsekunden zählen (auch wenn´s nur Spielerrei ist ...) ... also ich 
habe dass Programm für einen ATMega 16 der mit 8 MHz läuft ausgelegt ... 
Zu meiner Entwicklungsumgebung muss ich sagen, dass es sich um AVR - 
Studio handelt ... Programmiersprache C

Nun ein paar Fragen ...

1. Ich benutze einen Timer, der nach 0.1 Sekunden ein Interrupt auslöst 
... dieses Führt dazu, dass ein Zähler eine Variable herunter zählt ... 
( also bis die eingestelle Belichtungsdauer verstrichen ist ... ) ... 
ich habe am AVR ein Display angeschloßen ... korrekt eingestellt und 
getestet ...

Wie gebe ich nun die Werte auf dem Display aus ? Also z.B. den Wert 
100.00 ... und so weiter ... ich zähle z.B. von 100.00 in 0.1 Schritten 
herunter ... bei 0 schaltet ein Tyristor durch ... ich habe es mit 
sprintf versucht ... hiermit sollte ein float-Wert in einen String 
umgewandelt werden ... sprich ...

char Ergebins [100];
int num=24;
sprintf( Ergebnis, "%3.2f", num );

Doch ein wird auf dem Display nur ein Fragezeichen ausgegeben ... 
dennoch steht auf dem Display nach den 100 Sekunden "Time over ..." wie 
gewollt ... nun habe ich gelesen, dass es am Compiler liegen mag ... hat 
jemand eine Lösung ... ?
Bin absoluter Anfänger ... also bitte auf "flacher" Ebene Zwinkern ...

2. Meine letzte Frage ... wie Frage ich beim AVR einzellne Pins ab? Also 
Dass DDR habe ich richtig eingestellt ...

Anschließend kommt ja ..

Pin = 0x01;

für den ersten Pin ... aber kann ich auch direkt einen einzellnen 
abfragen ?

Beispielsweise ...

if (Pin = 0x01 = "High" .. ) oder so in der Art ... (ich weiß, dass das 
kein korrektes C ist ...)

Vielen Vielen Dank für eure Hilfe ... Mit freundlichen Grüßen Timo

von holger (Gast)


Lesenswert?

>int num=24;
>sprintf( Ergebnis, "%3.2f", num );

float num=24
dürfte die richtige Ausgabe machen.

von crazy horse (Gast)


Lesenswert?

klar kommt es auf auch auf den Compiler an - wenn du das schon weisst, 
warum verräts du nicht, welchen du verwendest? In der Grundversion 
werden oft nur char/int-Werte für printf/sprintf() unterstützt, für long 
und float musst du andere Compilereinstellungen wählen. Das hat einfach 
den Grund, dass sie seltener gebraucht werden, aber die Codegrösse 
aufblähen - hier wird noch in Byte und nicht in MByte abgerechnet :-)

zu 2: auch da gibt es compilerspezifische Eigenheiten, die echte 
C-conforme Ausdrucksweise verstehen aber alle.

von Karl H. (kbuchegg)


Lesenswert?

Noch was:

Für diese Anwendung brauchst du float überhaupt nicht.
Hintergrund: Mit float handelst du dir einen ganzen Sack
anderer Probleme ein.

Wenn du auf Zehntel-Sekunden genau anzeigen willst, dann
mach ganz einfach eine Zehntelsekunde zu deiner Basiseinheit
und benutzte int oder long.

int Time = 24;

würde dann eine Zeit von 24 Zehntelsekunden oder 2,4 Sekunden
bedeuten. 10387 wären dann demenstprechend 1038,7 Sekunden.

Alles was du tun musst, ist also bei der Ausgabe zwischen
die Zehner-er Stelle und die Einer-Stelle ein Komma
einschmuggeln. Fertig.

Das geht aber ganz leicht: zuerst gibst du alles vor
dem Komma aus. In dem Beispiel mit Zehntelsekunden wäre
das

     Zahl / 10      (aus 10387  wird dadurch 1038)

Danach gibst du das Komma aus
und anschliessend kommt noch der 'Nachkommaanteil' der
ürsprünglichen Zahl, sprich die Einerstelle.
Die kriegt man wiederrum mit

    Zahl % 10


Deine komplette Ausgabe könnte zb so aussehen

    sprintf( Ergebnis, "%d.%01d", num / 10, num % 10 );

Willst du 2 Nachkommastellen (also: Die Zahl in num ist
gerechnet in Hunderstelsekunden)

    sprintf( Ergebnis, "%d.%02d", num / 100, num % 100 );


von Timo (Gast)


Lesenswert?

Hey ...

Wollte vielen Dank sagen ... hät echt nicht so schnell mit einer Antwort 
gerechnet ... naja war ja auch mein erster Beitrag hier ...

Zu  "crazy horse":

Ich habe es zunächst mit AVR - Studio versucht ... diese Umgebung 
"stürzte" jedoch beim Einbinden des Headers für "sprintf" ab ... danach 
verwendete ich dass mit dem AVR-Studio mitgelieferte Programm "MFile" 
und schrieb den Quellcode in "Programmers Notepad" ...

Naja versuche nun einmal die Tips, die Ihr mir gegeben habt in die Tat 
umzusetzen ... denke mal, dass ich denn mal den Quelltext mit ins Forum 
stellen werde ... mal sehen ob wer Verbesserungsvorschläge hat ...

Bin ja wie gesagt am Lernen ...

Also ein frohes Osterfest wünsche ich allen zusammen ...

Mit freundlichen Grüßen Timo P.

von TechInfo (Gast)


Lesenswert?

In diesem Zusammenhang würde mich mal interessieren, wieso der Autor 
einfach sprintf für Displayausgaben benutzen kann, anstatt den String in 
das IO-Register zu schreiben an dem das Display hängt.

Danke.

von Karl H. (kbuchegg)


Lesenswert?

TechInfo wrote:
> In diesem Zusammenhang würde mich mal interessieren, wieso der Autor
> einfach sprintf für Displayausgaben benutzen kann, anstatt den String in
> das IO-Register zu schreiben an dem das Display hängt.
>
> Danke.

Weil er noch keinen String hat.
Er hat nur eine Zahl. Und irgendwie muss er die Zahl
in einen String formatieren.
Man kann das mit sprintf machen, muss es aber nicht.

Was du anscheinend auch übersiehst: mit sprintf
wird nichts aufs Display geschrieben. sprintf funktioniert
wie printf, nur das es sein Ergebnis (den String) im
1. Argument ablegt.

von TechInfo (Gast)


Lesenswert?

Ja danke, hab mal schnell in der C-Referenz nachgeschaut und bin auf das 
gleiche Ergebnis gekommen ;)

Man kann aber doch sicher den stdout von printf auf ein Display umlegen, 
oder?

von Karl H. (kbuchegg)


Lesenswert?

TechInfo wrote:
> Ja danke, hab mal schnell in der C-Referenz nachgeschaut und bin auf das
> gleiche Ergebnis gekommen ;)
>
> Man kann aber doch sicher den stdout von printf auf ein Display umlegen,
> oder?

Sicher kann man.
Wenn man weis wies geht :-)

Beim avr-gcc benutzt man dazu die fdev_open(). Mit
dieser Funktion schmuggelt man eine Character-Ausgabe
unter den printf hinein. printf() gibt ja nicht selbst
aus, sondern benutzt wieder eine weitere Funktion, die ein
einzelnes Zeichen ausgibt. Mittels fdev_open() kann man
da eine andere Funktion dafür angeben.

Bei anderen Compilern funktioniert das wieder anders.

von Timo (Gast)


Lesenswert?

Welcher Compiler lässt denn zB das Wandeln von Float zu String zu? Also 
mit der sprintf () Funktion ?

Gruß Timo

von Uhu U. (uhu)


Lesenswert?

Das ist weniger eine Frage des Compilers, als der Umgebung, in der das 
Programm läuft.

*printf() ist keine Eigenschaft des Compilers, sondern eine 
Bibliotheksfunktion, wie man sie auch selbst schreiben könnte.

von Timo (Gast)


Lesenswert?

Achso ...

Ähmm momentan benutze ich ja die Umgebung AVR - Studio ... diese kann 
die Funktion nicht verarbeiten ... da diese zuviel Speicherplatz in 
anspruch nimmt ... dannach habe ich es wie erwähnt mit 'Programmers 
Notepad' versucht ... in dieser Umgebung kann ich mit sprintf () 
beispielsweise int - Werte convertieren ... doch für float benötige ich 
eine andere Umgebung ... habt ihr ne Idee welche ich da nehmen kann ... 
? Vorzugsweise Freeware ...

Gruß Timo

von Simon K. (simon) Benutzerseite


Lesenswert?

Timo wrote:
> Achso ...
>
> Ähmm momentan benutze ich ja die Umgebung AVR - Studio ... diese kann
> die Funktion nicht verarbeiten ... da diese zuviel Speicherplatz in
> anspruch nimmt ... dannach habe ich es wie erwähnt mit 'Programmers
> Notepad' versucht ... in dieser Umgebung kann ich mit sprintf ()
> beispielsweise int - Werte convertieren ... doch für float benötige ich
> eine andere Umgebung ... habt ihr ne Idee welche ich da nehmen kann ...
> ? Vorzugsweise Freeware ...
>
> Gruß Timo

Höä? Du hast in beiden Fällen den gleichen Compiler verwendet... 
Lediglich der Editor, womit du das Programm geschrieben hast, ist ein 
anderer.

von Karl H. (kbuchegg)


Lesenswert?

Timo wrote:
> Achso ...
>
> Ähmm momentan benutze ich ja die Umgebung AVR - Studio ... diese kann
> die Funktion nicht verarbeiten ...

AVR Studio hat damit überhaupt nichts zu tun.

AVR Studio: IDE von Atmel (also Programmierumgebung)

In dieses AVR-Studio können sich nun ein paar Plugins
einhängen. Eines davon ist ein spezielles Plugin, dass
ein zweites Produkt (das nicht von Atmel stammt) in
diese IDE einbindet und zwar den WinAvr.
Der WinAvr ist ein C Compiler + Linker + Bibliothek.

WinAvr und AVR STudio haben rein gar nichts miteinander
zutun ausser der Tatsache, dass AVR-Studio so konfiguriert
werden kann, dass der WinAVR Compiler und Linker direkt
aus dem AVR Studio heraus aufgerufen werden kann.

> da diese zuviel Speicherplatz in
> anspruch nimmt ...

Im AVR Studio gibt es einen Einstellungsdialog, mit
dem man den WinAVR Compiler auch konfigurieren kann.
Hast du da mal die Optimierungen auf -Os hochgedreht?

> dannach habe ich es wie erwähnt mit 'Programmers
> Notepad' versucht ... in dieser Umgebung kann ich mit sprintf ()
> beispielsweise int - Werte convertieren ... doch für float benötige ich
> eine andere Umgebung ... habt ihr ne Idee welche ich da nehmen kann ...
> ? Vorzugsweise Freeware ...

Du brauchst keine andere Umgebung. Du musst nur deinen Linker
die richtigen Einstellungen mitgeben, dann sorgt der dafür,
dass für sprintf eine Version mitgelinkt wird, die auch float
unterstützt.

Beitrag "sprintf() Funktion - kleines Problem"

(Eigentlich hab ich einen anderen Beitrag gesucht
und nicht mehr gefunden. In irgendeinem Beitrag, in
dem es um genau das geliche Problem geht, habe ich mal
beschrieben, wie man diese Einstellungen im AVR Studio macht)

von Timo (Gast)


Lesenswert?

... Zitat:

"klar kommt es auf auch auf den Compiler an - wenn du das schon weisst,
warum verräts du nicht, welchen du verwendest? In der Grundversion
werden oft nur char/int-Werte für printf/sprintf() unterstützt, für long
und float musst du andere Compilereinstellungen wählen."

Es handelt sich wie erwähnt um den Compiler WinAVR ... bzw der dort mit 
enthalten ist ...

1. Wie gehe ich nun vor, wenn ich den Compiler so einstellen möchte, 
dass dieser auch die Umwandlung von Float - Werten mit der sprintf() 
Funktion zulässt? Was muss ich dafür anklicken ... :) ...

Mit freundlichen Grüßen Timo

von Karl H. (kbuchegg)


Lesenswert?

Das war AVR-Studio. Richtig?

Du gehst auf
  "Project"  "Configuration Options"

Im Dialog wählst du links aus:
  Libraries

danach klickst du in 'Available Link Objects' aus
   libprintf_flt.a
   libm.a

und jedesmal Add. Dadurch werden die Floating Point Library
und eine spezielle (größere) Version der printf() Library
zu deinem Projekt gelinkt.

Weiter: Du wählst links aus
   Custom Options

In den Custom Compilation Options wählst du aus:
[Linker Options]
rechts unten gibst du ein:
-Wl,-u,vfprintf
und drückst auf 'Add'

Danach den Dialog mit 'OK' verlassen und das Projekt neu generieren.

von Karl H. (kbuchegg)


Lesenswert?

@Regulars

Nachdem diese Frage häufig vorkommt, habe ich sie in meine
C-FAQ aufgenommen:

http://www.mikrocontroller.net/articles/FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio

von Timo (Gast)


Lesenswert?

Danke euch Allen ... hat sehr schön geklappt ... Frohes Osterfest

von Duspol (Gast)


Lesenswert?

ich habe die Einstellungen oben gemacht.Es funktioniert.
Sobald ich das #include <util/delay.h> einfüge,weil ich 
verzögerungsschleife bauen will,dann gehts nicht mehr.Dann zeigt mein 
Lcd schwarze balken,irgendwelche Zahlen oder nicht an.Woran kann s 
liegen?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.