Ich sende über die UART vom ATMEGA8535 Temperatur und Luftdruckwerte sowie Datum. Das alles geht ja schon mal. Nur ich bekomme nicht die Daten so an wie hier: 2006 12. 16. 1 1014 23 2006 12. 16. 2 1014 23 2006 12. 16. 3 1014 23 2006 12. 16. 4 1014 23 2006 12. 16. 5 1014 23 2006 12. 16. 6 1014 23 2006 12. 16. 7 1014 23 2006 12. 16. 8 1014 23 2006 12. 16. 9 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 2 1014 23 2006 12. 16. 2 1014 23 2006 12. 16. 2 1014 23 2006 12. 16. 2 1014 23 Mit dem Terminalprogramm empfange ich immer dies hier: Da sind immer Leerzeichen die da nicht hin sollen, sowie nach 16. sollte eigentlich die Zahl von 1 bis 23 dargestellt werden. Hier sieht man nur immer ein Zeichen. 2006 12. 16. 1 1014 23 2006 12. 16. 2 1014 23 2006 12. 16. 3 1014 23 2006 12. 16. 4 1014 23 2006 12. 16. 5 1014 23 2006 12. 16. 6 1014 23 2006 12. 16. 7 1014 23 2006 12. 16. 8 1014 23 2006 12. 16. 9 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 1 1014 23 2006 12. 16. 2 1014 23 2006 12. 16. 2 1014 23 2006 12. 16. 2 1014 23 2006 12. 16. 2 1014 23 Meine Funktion sieht so aus: void tagesprofil (void) { unsigned char n, m; for (n=0; n<24; ++n) { if (n == 0) { putchar('T'); } sprintf (printbuf,"%4i%2i.%2i.%2i ",2006,(int)12,(int)16,(int)n); sprintf (printbuf+15,"%4i%3i",1014,23); *(printbuf+24) = 0x0d; *(printbuf+25) = 0x0a; for (m=0; m<26; ++m) { putchar(*(printbuf + m)); } {unsigned int i; for (i=1000; i>0; --i);} } putchar('E'); }
Mist ich muss mich wieder korrigieren: Ich möchte diese Darstellung haben: 2006 12.16.01 1014 23 2006 12.16.02 1014 23 2006 12.16.03 1014 23 2006 12.16.04 1014 23 2006 12.16.05 1014 23 2006 12.16.06 1014 23 2006 12.16.07 1014 23 2006 12.16.08 1014 23 2006 12.16.09 1014 23 2006 12.16.10 1014 23 2006 12.16.11 1014 23 2006 12.16.12 1014 23 2006 12.16.13 1014 23 2006 12.16.14 1014 23 2006 12.16.15 1014 23 2006 12.16.16 1014 23 2006 12.16.17 1014 23 2006 12.16.18 1014 23 2006 12.16.19 1014 23 2006 12.16.20 1014 23 2006 12.16.21 1014 23 2006 12.16.22 1014 23 2006 12.16.23 1014 23 Also ganz oben das ist falsch.
Warum so umständlich? sprintf (printbuf,"%4i%2i.%2i.%2i ",2006,(int)12,(int)16,(int)n); sprintf (printbuf+15,"%4i%3i",1014,23); *(printbuf+24) = 0x0d; *(printbuf+25) = 0x0a; a) Die typecasts nach int kannst Du weglassen, die Konstanten sind sowieseo vom Typ int. Leerzeichen sollten auch im Formatstring angegeben sein. b) Ein Aufruf von sprintf genügt völlig: sprintf(printbuf, "%04d %02d.%02d.%02d %04d %02d\r\n", 2006, 12. 16, n, 1014, 23); (Anstelle von %i kann auch das üblichere %d verwendet werden) Natürlich könntest Du, wenn fast alle Parameter eh Konstanten sind, auch sprintf wie folgt verwenden: sprintf(printbuf, "2006 12.16.%02d 1014 23\r\n", n); aber das wäre vermutlich zu einfach. Desweiteren kannst Du auf Dein Abzählen von Zeichen bei der Ausgabe des Inhaltes von printbuf verzichten; printbuf enthält einen nullterminierten String, und das kann man ausnutzen: char* p; // Hilfspointer p = printbuf; while (*p) { putchar(*p++); } Du musst nur sicherstellen, daß printbuf ausreichend groß ist, um einen Deiner Strings aufnehmen zu können - und auch Platz für die abschließende \0 hat, die von sprintf als Kennzeichnung des Stringendes angehängt wird. Im übrigen hätten zur Demonstration des gewünschten Formates zwei bis drei Beispiele vollends genügt; 23 ist eindeutig übertrieben. Ansonsten solltest Du die "BACK"-Funktion Deines Browsers nicht verwenden, sonst passiert Dir diese Beitragsinkontinenz wie oben.
Hab meinen Code abgeändert. Jetzt erhalte ich vom Controller über die UART folgendes: T 2006 12. 16. 0 1024 23 <0> 2006 12. 16. 1 1024 23 <0> 2006 12. 16. 2 1024 23 <0> 2006 12. 16. 3 1024 23 <0> 2006 12. 16. 4 1024 23 <0> 2006 12. 16. 5 1024 23 <0> 2006 12. 16. 6 1024 23 <0> 2006 12. 16. 7 1024 23 <0> 2006 12. 16. 8 1024 23 <0> 2006 12. 16. 9 1024 23 <0> 2006 12. 16. 10 1024 23 2006 12. 16. 11 1024 23 2006 12. 16. 12 1024 23 2006 12. 16. 13 1024 23 2006 12. 16. 14 1024 23 2006 12. 16. 15 1024 23 2006 12. 16. 16 1024 23 2006 12. 16. 17 1024 23 2006 12. 16. 18 1024 23 2006 12. 16. 19 1024 23 2006 12. 16. 20 1024 23 2006 12. 16. 21 1024 23 2006 12. 16. 22 1024 23 2006 12. 16. 23 1024 23 E Woher kommt da das Zeichen <0>? Ich möchte dass das Zeichen <0> nicht erscheint bzw vorhanden ist.Desweiteren sollte nach 12. und nach 16. kein Leerzeichen vorhanden sein. Ich weiss nun nicht wo ich da meinen Code abändern muss. Der Code sieht so jetzt aus: void tagesprofil (void) { unsigned char n, m; for (n=0; n<24; ++n) { if (n == 0) { putchar('T'); } sprintf (printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,(int)12,(int)16,(int)n,1024,23 ); for (m=0; m<26; ++m) { putchar(*(printbuf + m)); } {unsigned int i; for (i=1000; i>0; --i);} } putchar('E'); }
Du solltest Dir mal die Bedeutung des Formatstrings von printf() und Konsorten näher ansehen. Der von Dir gepostete Formatstring kann jedenfalls die von Dir gepostete Ausgabe nicht erzeugen: "%4d%2d" mit den Argumenten 2006 und 12 (lass den Typecast weg!) ergibt "200612" Ohne dazwischengesetztes Leerzeichen und auch ohne Leerzeichen oder sonstwas vor 2006. Mir scheint, Code und Ausgabe"beispiel" passen nicht zusammen. Hast Du eigentlich wirklich gelesen, was ich vor drei Tagen schrieb?
vielleicht sendest Du zu schnell und das Terminal bringt etwas durcheinander: for (m=0; m<26; ++m) { putchar(*(printbuf + m)); } {unsigned int i; for (i=1000; i>0; --i);} teste mit Pause nach jedem Zeichen statt nur vor dem E: for (m=0; m<26; ++m) { putchar(*(printbuf + m)); {unsigned int i; for (i=1000; i>0; --i);} } und pass auf, ob der Compiler die Warteschleife nicht wegoptimiert. oder Dein Compiler hält sich nicht an die Konventionen und hält vor jeder integer-Zahl ein Zeichen für das Vorzeichen frei. caste mal mit (unsigned int) aber das kann ich mir gar nicht vorstellen. Versuche mal rauszufinden, ob der Fehler in der sprintf-Zeile passiert oder in der Ausgabeschleife.
Tja, ich hab alles mögliche versucht. Ohne Erfolg.Ich in verschiedenen stellen delays eingebaut. unsigned char printbuf [96]; void tagesprofil (void) { unsigned char n, m; for (n=0; n<24; ++n) { if (n == 0) { uart_transmit('T'); } sprintf (printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,(int)12,(int)16,(int)n,1024,(i nt)23); for (m=0; m<25; ++m) { uart_transmit(*(printbuf + m)); } delay_ms(20); } uart_transmit('E'); } Also beim Empfangen sieht es mal schon besser aus. Leider ist es aber noch immer so, dass zwischen den Punkten (Datum) immer noch ein Leerzeichen vorhanden ist. Ich hab soger mal nur ein paar Zeichen gesendet da sieht es auch nicht besser aus. ich finde das echt komisch!
Ich denke, dass Peter dich gefragt hat, ob du mit dem internen RC-Oszillator arbeitest. Eine Antwort wäre hilfreicher als eine Gegenfrage. ...
Naja, ein Baudratenquarz wäre vermutlich besser gewesen. Die Frage sollte wohl klären, ob die Möglichkeit besteht, dass Zeichen verloren gehen weil die Baudrate nicht genau eingehalten wird. ...
Ok das könnte vielleicht sein, aber diesen String "2006 12. 16. 11 1024 23" empfange ich 24 mal korrekt. Da sind wie gesagt nach den Punkten immer ein Leerzeichen. Die sollen da nicht vorkommen. sprintf (printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,12,)16,n,1024,23); Genau so verwende ich den Code bei mir.
sprintf (printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,12,16,n,1024,23); hab mich vertippt. So müsste es stimmen.
Hast Du mal in einem Debugger den Inhalt von printbuf näher angesehen? Hast Du mal ausprobiert, sprintf(printbuf, "200612.16.%2d1024 23\r\n", n); aufzurufen? Oder einfach nur sprintf(printbuf, "#%2d#\r\n", n); aufzurufen? Warum gibst Du den Wert 23 mit dem Formatspezifizierer %3d aus?
Das ist in der Tat seltsam. Das sollte nicht so sein. Sag. Welchen Compiler in welcher Version benutzt du? Vielleicht klingelts da bei irgendjemandem. Hmm. sprintf (printbuf,"%4d%2d.%2d.%2d%4d%3d\r\n",2006,(int)12,(int)16,(int)n,1024,(i nt)23); for (m=0; m<25; ++m) { uart_transmit(*(printbuf + m)); } Hmm. Beim sprintf sollte eigentlich gar kein String der Laenge 25 entstehen. Wenn ich den Format-String durchgehe, komme ich auf 21 Zeichen PS: Die int-casts im Aufruf kannst Du Dir sparen, die bewirken gar nichts. Kannst Du Dir die Laenge des entstandenen Strings in printbuf mal ausgeben lassen. Ziel ist es abzuklaeren ob die zusaetzlichen Zeichen im sprintf entstehen oder ob die irgendwie waehrend der Datenuebertragung hineingeschmuggelt werden.
> Da sind wie gesagt nach den Punkten immer ein Leerzeichen. Die > sollen da nicht vorkommen. Hmmm... Sind die Leerzeichen nun nach den Punkten oder vor den Zahlen? Denn in VB muss ich die Zahlen über TRIM(zahl) ausgeben, wenn ich die Leerzeichen davor vermeiden will. Von C habe ich aber keine Ahnung, AVRs programmiere ich in ASM. ...
@Hannes Das passt schon so. In C kann man die Ausgabe sehr genau und feinfuehlig ueber den Format-String steuern. Er hat fuer jede Ausgabe exakt angegeben, wieviele Stellen sie umfassen soll. Eigentlich sollte sich der sprintf daran halten.
Nicht nach einem Punkt, sondern vor einer 2-stelligen Zahl (beachte: vor dem 12 ist auch ein falsches Leerzeichen). Versuche mal, statt %2d nur %d und auch mal %2u und %u zu verwenden. Bitte teile uns auch die Ausgaben von %02d und %02u mit. Ich vermute, er reserviert vor einer 2-stelligen Zahl ein Zeichen für das (bei positiven Zahlen nicht vorhandene) Vorzeichen. Sind Zahlen länger als angegeben, werden sie auch länger ausgegeben. Bei der Angabe handelt es sich um eine Mindestbreite. Welchen Compiler / Version verwendest Du?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.