Hallo, ich stehe etwas auf dem Schlauch: uint16_t sollte doch einen Wertebereich vom 0 bis 65535 haben. Bei mir reicht es aber nur bis 2^15, d.h., wenn ich eine größere Zahl per UART übertrage, dann ist bei 32767 Schluß, danach kommt ein Minuszeichen und es zählt wieder rückwärts - wie es bei einem signed geschieht. Kann denn der gcc-Compiler mein uuuu-int16_t nicht lesen? Gruß Alexander
Alexander Schmeil schrieb: > wenn ich eine größere Zahl > per UART übertrage, Das deutet darauf hin, das Du bei der Vorbereitung für die Übertragung oder beim speichern auf der Empfängerseite was anderes machst als es Deine Absicht ist. Gib uns diesbezüglich Details und Code.
Glaube ich auch, ich habe probeweise die Definition des Array auf uint32_t geändert und trotzdem bleibt die Begrenzung bei 2^15. Also, es ist in einem Programm-Module ein Array definiert mit int16_t cts[16];. In einem anderen Modul steht dann extern uint16_t cts[16]; In dieses Array legt das Programm die ermittelten Werte ab, im vorliegenden Testfall habe ich die Werte um 32367 manuell eingetragen. Dann kommt die Ausgabe über UART char mw_ascii[5]; // Ascii-Wert von cts[i] itoa(cts[i], mw_ascii, 10); uart_puts(mw_ascii); Beim Schreiben dieser Antwort ist mir aufgefallen, was ich falsch gemacht habe: das Nadelöhr ist wohl die Definition der Variablen mw_ascii[], wo es an der nötigen Bandbreite fehlt. Ich glaube, wenn ich das ändere, wird es funktionieren. Gruß Alexander
Alexander Schmeil schrieb: > char mw_ascii[5]; // Ascii-Wert von cts[i] > itoa(cts[i], mw_ascii, 10); > uart_puts(mw_ascii); Der Compiler macht nur einfach genau das, was Du ihm sagst. Wenn Du ihm "utoa() sagen würdest, macht er es auch. Peter
Nein, das Problem liegt daran, daß Du itoa verwendest. Was auch immer Du itoa übergibst, es interpretiert es als int - was auf Deinem System einem int16_t ist.
Die Funktion itoa erwartet eine int-Zahl, und int ist immer signed. Benutze stattdesssen utoa. MfG Mark
Alexander Schmeil schrieb: > int16_t cts[16];. Häh. Ich dachte uint16? Alexander Schmeil schrieb: > In einem anderen Modul steht dann > extern uint16_t cts[16]; Hmm. An sich würde ich vom Linker erwarten, das er meckert weil die Typen nicht übereinstimmen. Denn uint16_t ist ungleich int16_t. Ändere das, das ist sauberer. Der eigentliche Knackpunkt aber wird die Verwendung von itoa sein. Lies Dir mal die Beschreibung durch. Es erwartet ein int und kein unsigned int. Entsprechend verhält es sich auch. Verwende doch einfach utoa.
> An sich würde ich vom Linker erwarten, das er meckert weil die > Typen nicht übereinstimmen. Der Linker macht keine Typüberprüfungen, der sieht nur nach Symbolnamen. Und da das hier C und nicht C++ ist, haben die Symbolnamen keine Typinformation.
Meine Vermutung, es könne an der Variablen mw_ascii liegen, waren natürlich unsinnig, für ascii reicht char völlig aus. Mit utoa statt mit itoa funktioniert es aber bestens! Vielen Dank für Eure schnelle Hilfe. Alexander PS Gibt es irgendwo eine Dokumentation, in der solche Funkltionen und ihre Parameter aufgelistet sind? Das itoa() hatte ich seinerzeit nur gefunden, weil ich den Namen anderswo schon mal gelesen hatte.
Rufus t. Firefly schrieb: > Und da das hier C und nicht C++ ist, haben die Symbolnamen keine > Typinformation. Auch in C++ wäre das (zumindest bei GCC) so. Die Symbolnamen werden nicht generell um Typinformationen erweitert, sondern nur dort, wo das nötig ist, z.B. bei Funktionen, wo man Parameter-Typen für die Überladung unterscheiden können muß. Alexander Schmeil schrieb: > PS Gibt es irgendwo eine Dokumentation, in der solche Funkltionen und > ihre Parameter aufgelistet sind? Das itoa() hatte ich seinerzeit nur > gefunden, weil ich den Namen anderswo schon mal gelesen hatte. Vermutlich in der Dokumentation der Bibliothek, die diese Funktion bereitstellt, welche auch immer das sein mag.
> Auch in C++ wäre das (zumindest bei GCC) so.
Du hast natürlich recht, warum auch sollte eine Namensdekoration von
nicht überladbaren Symbolen erfolgen?
Wobei sie bei solchen Fehlern wie dem hier praktisch wäre.
Der übrigens hätte vermieden werden können, wenn die Headerdatei, in der
das Array als extern deklariert wurde, in das Modul mit eingebunden
worden wäre, in dem das Array definiert wird.
Dann hätte der Compiler meckern können.
@Alexander Die Doku für die avr-libc findet sich unter http://www.nongnu.org/avr-libc/user-manual/modules.html MfG Mark
Rufus t. Firefly schrieb: > Du hast natürlich recht, warum auch sollte eine Namensdekoration von > nicht überladbaren Symbolen erfolgen? > > Wobei sie bei solchen Fehlern wie dem hier praktisch wäre. Wird dadurch nicht besser, im Gegenteil. Dann kriegt man u.U. mehrere separate Variablen gleichen Namens und wundert sich, warum die gleiche Variable in zwei Programmmodulen unterschiedliche Werte hat. Das ist mit Absicht so implementiert.
Hmpf, da hast Du natürlich recht. Hier hätte es allerdings geholfen, weil der Linker ein nicht aufgelöstes Symbol gemeldet hätte, nämlich das, was mit extern nur deklariert wurde. Naja, man muss halt in C schon eine gewisse Disziplin entwickeln.
bin über die Suche über diesen Thread gestolpert und möchte folgende Beobachtung anmerken, die ich mit avr-gcc 4.3.3 mit Target atmega8 gemacht habe: itoa auf uint8_t -> liefert 0 - 255, überlauf etc alles scheint ok itoa auf uint16_t -> liefert -32k - +32k ... Wertebereich wird also anders - für *i*toa korrekt - wiedergegeben also ein bisschen Inkonsistent. Daher ist mir erst bei der verwendung von uint16_t Variablen aufgefallen, das ich itoa auf unsigned Variablen loslasse. böse! pfui! utoa auf uint16_t liefert wie erwartet korrekte Ergebnisse.
Robert F. schrieb: > bin über die Suche über diesen Thread gestolpert und möchte folgende > Beobachtung anmerken, die ich mit avr-gcc 4.3.3 mit Target atmega8 > gemacht habe: > > itoa auf uint8_t -> liefert 0 - 255, überlauf etc alles scheint ok > itoa auf uint16_t -> liefert -32k - +32k ... Wertebereich wird also > anders - für *i*toa korrekt - wiedergegeben > > also ein bisschen Inkonsistent. Nö, überhaupt nicht. Da ein uint8_t in einen int hineinpasst, und zwar mit allen Werten, ist es genau das was zu Erwarten ist. itoa will einen int! wenn du einen uint8_t hast, dann wird der zunächst auf einen int hochgehoben. Und da das ohne Probleme geht, bleiben alle Werte von 0 bis 255 erhalten. Ein uint16_t passt aber nicht mit allen Werten in einen int. Du gehst davon aus, dass sich itoa irgendwie magisch an den übergebenen Parameter anpasst. Das passiert aber nicht. Es wird versucht, das was du angibst in einen int zu verwandeln und erst dieser int geht dann an itoa. Was du siehst, ist eine direkte Konsequenz dieses impliziten Casts.
Robert F. schrieb: > itoa auf uint8_t -> liefert 0 - 255, überlauf etc alles scheint ok > itoa auf uint16_t -> liefert -32k - +32k ... Wertebereich wird also > anders - für *i*toa korrekt - wiedergegeben > > also ein bisschen Inkonsistent. Genaugenommen ist das nicht inkonsistent. Da der Prototyp von itoa bekannt ist, hast Du in beiden Fällen einen impliziten Cast nach int. Und ein Cast (uint8_t) -> (int) geht nunmal unfallfrei, da alle für uint8_t möglichen Werte in einen int passen, bei einem (uint16_t) -> (int) muss es den beobachteten Überlauf geben.
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.