Ich habe mir meine eigene Library zusammengestellt. U.a. befinden sich in dieser Lib auch Funktionen für ein VT100-Terminal. Bei einem Testprogramm ist mir aufgefallen, dass die Funktion sprintf() aus der stdio nicht funktioniert. Beim compilieren erhalte ich keine Fehlermeldung oder Warnung. Bei der zweiten Ausgabe auf dem Terminal (Term_Send_String(buf);) erscheint nur Müll auf dem Monitor. Bitte testet doch selber mal! Mein C-Quelltext: #include <avr/io.h> #include <stdio.h> #include "M8_Lib.h" unsigned char buf[100]; unsigned char *s="string"; unsigned char c = '1'; double d = 134.431; unsigned char i=0; int main( void ) { Term_Initialise(); for(;;) { Term_Send_String("char i = "); Term_Send_Value_as_Digits(i++); Term_Send(0x0d); sprintf(buf,"sprintf = %f %c %s \r",d,c,s); Term_Send_String(buf); wait_500(); wait_500(); } } Das ist ein Auszug aus der .lss: ... sprintf(buf,"sprintf = %f %c %s \r",d,c,s); 80: 80 91 6c 00 lds r24, 0x006C 84: 90 91 6d 00 lds r25, 0x006D 88: 9f 93 push r25 8a: 8f 93 push r24 8c: 80 91 64 00 lds r24, 0x0064 90: 99 27 eor r25, r25 92: 9f 93 push r25 94: 8f 93 push r24 96: 80 91 60 00 lds r24, 0x0060 9a: 90 91 61 00 lds r25, 0x0061 9e: a0 91 62 00 lds r26, 0x0062 a2: b0 91 63 00 lds r27, 0x0063 a6: bf 93 push r27 a8: af 93 push r26 aa: 9f 93 push r25 ac: 8f 93 push r24 ae: 85 e7 ldi r24, 0x75 ; 117 b0: 90 e0 ldi r25, 0x00 ; 0 b2: 9f 93 push r25 b4: 8f 93 push r24 b6: 07 e9 ldi r16, 0x97 ; 151 b8: 10 e0 ldi r17, 0x00 ; 0 ba: 1f 93 push r17 bc: 0f 93 push r16 be: f4 d0 rcall .+488 ; 0x2a8 <sprintf> ... ?????????? Peter (DF8XA)
:
Gesperrt durch Moderator
Was bitte sollen wir denn wie testen? Sorry, mit einem nicht compilierbaren Schnipsel kann ich leider nix anfangen. Ansonsten das Übliche: in 99 % der Fälle sitzt der Bug vor dem Rechner...
Hallo Jörg, du wirst doch wohl die Möglichkeit haben, einen String den du mit sprintf produziert hast, auf irgendein Medium (LCD o.ä.)auszugeben! 73 Peter,DF8XA
Hi linkst du auch das richtige sprintf dazu? Du benötigst die Version mit Gleitkommaunterstützung. Matthias
Selbst wenn er kein Gleitkomma-printf hat, sollte nicht nur Schrott herauskommen. Lediglich das %f wird dann in ein (einzelnes) Fragezeichen gewandelt.
Komisch, bei "UART" und "Müll" denke ich immer an "RC-Oszillator". Und fast immer stimmts auch. Peter
> Komisch, bei "UART" und "Müll" denke ich immer an > "RC-Oszillator". Wenn man ihn nicht richtig benutzt, kann das gut sein.
Danke Matthias. Ja, es lag an der nicht eingebundenen float-Library. Blöd ist, dass keine Fehlermeldung oder wenigstens eine Warnung beim compilieren generiert wird. Das sich dabei das Programm von 588 Byte auf 4632 Byte aufbläht liegt wahrscheinlich daran, dass der Linker die komplette stdio-Library mit einbindet und nicht nur die für die sprintf benötigten Funktionen. @Jörg: Das '?' sieht man aber nur, wenn man ein einzelnes %f in der Formatanweisung hat. Wenn zusätzlich ein string (%s) und ein char (%c) in der Formatanweisung stehen, sieht man einfach nur "Müll" auf dem Monitor und da kannst du dann lange nach deinem einzelnen Fragezeichen suchen. Andererseits, wenn dich solche Fragen nerven, dann Antworte doch einfach nicht. Deine Bemerkung, dass bei dir alles funktioniert bringt niemanden weiter. Das du ja ein "ganz Toller" bist, ist mir durch deine zahlreichen Beispiele im Umgang mit "Unwissenden" in diesem Forum längst bekannt. Du solltest besser dein Rufzeichen weglassen sonst denken die Leute noch alle Funkamateure sind so "aufgeblasene Besserwisser". Nochmals danke Matthias Peter, DF8XA
> Blöd ist, dass keine Fehlermeldung oder wenigstens eine Warnung beim > compilieren generiert wird. Geht leider nicht, da der Compiler nicht weiß, gegen welche Library du linkst, der Linker aber keine Chance mehr hat, alle Formatstrings zu überprüfen, ob da nun irgendwo ein Gleitkomma-Format verlangt worden ist. > Das sich dabei das Programm von 588 Byte auf 4632 Byte aufbläht > liegt wahrscheinlich daran, dass der Linker die komplette > stdio-Library mit einbindet und nicht nur die für die sprintf > benötigten Funktionen. Der Linker linkt nur dazu, was gebraucht wird. Gleitkommarechnung auf einem 8-Bit-Micro kostet halt richtig. Da noch dazu printf() immer den Code für alle möglichen Formate vorhalten muss, bezahlst du ja auch für andere Dinge wie 32-Bit-Integerzahlen, selbst wenn du sie nicht benutzt. > Das '?' sieht man aber nur, wenn man ein einzelnes %f in der > Formatanweisung hat. Wenn zusätzlich ein string (%s) und ein char > (%c) in der Formatanweisung stehen, sieht man einfach nur "Müll" auf > dem Monitor ... Dann ist da noch was anderes foul. Wenn alles Andere bei dir korrekt eingestellt ist (Taktfrequenz, Baudrate etc.), dann hätte mit Gleitkommavariante geschrieben werden sollen (z. B., Rundungsfehler erfinde ich mal schnell frei): sprintf = 134.430951 1 string <CR> und mit der Standardversion sprintf = ? 1 string <CR> Wenn das bei dir anders war, hast du noch ein weiteres Problem. > Deine Bemerkung, dass bei dir alles funktioniert bringt niemanden > weiter. Deine ungenügende Fehlerbeschreibung allerdings auch nicht.
@Jörg > und mit der Standardversion > sprintf = ? 1 string <CR> > Wenn das bei dir anders war, hast du noch ein weiteres Problem. Wenn ich mich recht erinnere, war es bei mir auch so, daß nach einem "%f" ohne float-printf nur noch Unsinn ausgegeben wurde. (Nicht die letzte avr-lib,) In diesem(!) Punkt stimme ich Peter zu. Ich werde das morgen nochmal testen und berichten. 73, Falk
Hab's eben selbst nochmal ausprobiert. Ja, mir fällt's jetzt wie Schuppen aus den Haaren... :-) Das %f wird ja komplett ignoriert, d. h. der Gleitkommawert wird nicht vom Stack geholt und damit anschließend als char (durch %c) interpretiert. Vermutlich habe ich bei derartigen Tests nur ein %i oder sowas danach gehabt, da wird dann einfach irgendeine Zahl ausgegeben. Ich halte das für einen Bug. Bitte schreibt mal einen Bugreport: https://savannah.nongnu.org/bugs/?group=avr-libc Sorry nochmal.
Hallochen Gibt es eine konstruktive Lösung ? Habe das gleiche Problem. Mit #include <stdio.h> #include <stdlib.h> #include <math.h> void main (void) { char[10] buffer = "leer"; float MyFloat = 123.45; if (MyFloat == 123.45) sprintf(buffer, "% #3.2f", MyFloat); } erhalte ich nur ein Fragezeichen im buffer. Was muss ich also tun, damit im buffer "123.45" steht ? Viele Grüsse Daniel
Daniel schrieb: > Habe das gleiche Problem. Das glaube ich nicht. > erhalte ich nur ein Fragezeichen im buffer. http://www.mikrocontroller.net/articles/FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio
Tja, das nützt alles nichts. Habe alle Options ausprobiert, die da beschrieben sind. Immer nur Fragezeichen. Die Lösung habe ich anderswo gefunden: // sprintf(buffer,"% #3.2f",MyFloat); // DOESN'T WORK --> "?" dtostrf(MyFloat,7,2,buffer); Das arbeitet perfekt. Aber besten Dank ... Daniel
Daniel schrieb: > Gibt es eine konstruktive Lösung ? Ja: einen eigenen Thread aufmachen für ein neues Thema, statt einen 5 Jahre alten zu kapern.