Hi! Ich kämpfe immernoch mit dem UART Problem und bin jetzt auf etwas "unerklärliches" gestoßen. Zur Abfrage der UART deklariere ich char data,text[3],buffer[16]="",buffer2[16]=""; Um zu schauen, ob ich selbst der Verursacher des Datensalats bin sammle ich die Daten data = UDR1; buffer[countit] =data; // data &= ~(0x80); buffer2[countit] =data; Nun der Hammer! Wenn ich die Sammlung ausgebe display_cursor(1,1); itoa(buffer[countit],text,2); display_string(text); display_cursor(1,12); itoa(countit,text,10); display_string(text); display_cursor(2,1); itoa(buffer2[countit],text,2); display_string(text); Inhalt Buffer 1 Inhalt Buffer 2 0011 0001 0010 0110 0011 0000 0010 0110 0011 0001 1010 0110 0011 0000 1100 1100 0 1000 1001 0001 0011 0001 0011 0011 0010 0011 0010 ab der Null sind die Daten dann identisch! Das ist doch nicht normal?! Was passiert da? Läuft mir der Speicher über?
Korrekt selbst festgestellt. In text[3] passen max 3 Zeichen inklusive der abschliessenden Null. Einen 8 Bit Wert binär auszugeben braucht 9 Zeichen. Das erste itoa() überschreibt somit den Anfang vom buffer[].
Hab ich noch nicht ganz verstanden. Warum überschreibt text buffer ? Ok Text ist zu klein und sollte 9 sein! aber wenn ich in text einen String reinquetsche, der in text nicht reinpasst, warum überschreibt er dann buffer?
wenn du am anfng deiner routine char data,text[3],buffer[16] definierst, dann wird text am irgend einer stelle im ram stehen und buffer 3 zeichen später im ram beginnen. wenn du jetzt zb auf text[3] zugreifst, ist da das gleiche wie buffer[0] oder text[4]== buffer[1], da ja dein array nur eine 16bit speicheradresse ist wo anschließend x byte freier speicherplatz reserviert ist. vielleicht hilft das ein wenig weiter die problematik zu verstehen MfG Sebastian
> char data,text[3],buffer[16]="",buffer2[16]="";
Darf ich aus der Reihenfolge schließen, wie die Variablen im RAM
abgelegt werden? Der C-Standard sagt dazu ja nix, also kann man sich
darauf nicht verlassen. Wie macht der GCC das?
ciao, Stefan.
> Wie macht der GCC das?
Du hast es ganz richtig erkannt, du darfst dich keinesfalls auf die
genaue Anordnung der Variablen im RAM verlassen.
Selbst wenn der gcc das in der aktuellen Version wie gewünscht macht,
sieht es in der nächsten Version vielleicht schon wieder ganz anders
aus.
>Darf ich aus der Reihenfolge schließen, wie die Variablen im RAM >abgelegt werden? Der C-Standard sagt dazu ja nix, also kann man sich >darauf nicht verlassen. Wie macht der GCC das? gcc wie auch viele andere compiler legen variablen in der reihenfolge im RAM ab, wie die variablen definiert werden. wie du selber festgestellt hast, ist das aber nicht festgelegt, und man darf sich darauf nicht verlassen. wenn du darauf angewiesen bist, dass variablen in einer ganz bestimmten reihenfolge im RAM liegen, kannst du sie in eine struktur packen. aber auch dort kann der compiler einzelne felder ausrichten, falls das für die target CPU notwendig ist.
OK Ok ich habs verstanden. Bleibt eine frage ... Ich lege die Zahl sagen wir mal 21 in einer Int ab. Die ist ja von Hause aus in ihrer Länge begrenzt. Wenn ich die jetzt per Itoa umwandle, wieviel Zeichen brauche ich dann?? Ich ab zwar inzwischen das Machwerk von Karninghan aber Itoa steht ziemlich weit hinten mit zig Zeichen, die mir (noch) nix sagen. Ich versteh sowieso nicht warum C so einen Zauber aus den Variablen macht. Bei TP war das alles viel einfacher ...
http://www.nongnu.org/avr-libc/user-manual/group__avr__stdlib.html#ga25 Moeglichen Wertebereich der uebergabenen Zahl anschauen, abhaengig von der Basis (radix) Anzahl der moeglichen Stellen ausrechnen und noch eins fuer die terminierende \0 dazuzaehlen. Bei Basis 10 und moeglichen negativen Werten noch eine Stelle fuer das Vorzeichen hinzu. Das ist alles andere als "Zauber" und etwas naeher 'an der Machine' als in Pascal mit der versteckten Laengenangabe bei Zeichenketten. Das K&R "Machwerk" ist stellenweise etwas anspruchsvoll, moeglicherweise zu. Wenn das Verstaendnis gar so schwer faellt: es gibt Pascal-Compiler fuer AVR. (Wenn man in einem C-Forum Antworten auf solche Anfaengerfragen erwartet, scheint es geschickt, Formulierungen wie "so einen Zauber" oder "Machwerk" zu vermeiden. Hoffentlich die itoa-Ausfuehrungen sorgfaeltiger gelesen als die Titelseite)
Ich trage noch eins zum Verständnis bei, weil ich Pascal hörte. Die Strings werden im Gegensatz zu Pascal als Null-Terminierte String gespeichert. Pascal speichert Strings AFAIK mit einem Längenbyte am Anfang. Das gibt es in C nicht, dort wird das Ende eines String immer mit \0 gekennzeichnet. Dazu steht im K&R eine ganze Menge. Ich finde eigentlich nicht, daß der K&R so schwer zu verstehen ist. mfg, Stefan.
@MThomas Ich fürchte, ich werde mit pascal nicht weit kommen. Es wird schon einen Grund haben, warum die Mehrheit C-Compiler oder ASM benutzt. Zum "Machwerk". Eines der ersten Beispiele in dem Buch enthält nur eine Programmzeile und die beginnt mit fprint. Was wissen wir von fprint? " ... gibt Zeichenkette an Standartausgabeport aus" ?? Ach was!! Ich habe eine UART auf Pin 2 und 3, ein LCD an PC1 und noch eine UART an ??? und einen CAN Bus irgendwo. Und woher weiss fprint, welches mein Standartausgabeport ist?? Kein Hinweis! Kein Querverweis. Nix! Kann sein dass ich da von meinen Funktionsverzeichnissen und Büchern für Pascal, MFX, Excel - Makro, Siemens, ... verwöhnt bin.
Und wieder ein RTFM: Die Dokumentation von der AVR Libc. http://www.nongnu.org/avr-libc/user-manual/index.html Da ist z.B. auch die Frage nach der Länge, die Du für itoa benötigst, beantwortet. Der K&R ist halt nicht auf Microcontroller spezialisiert, sondern auf Unix-Systemen. Da gibt es Printf halt. Wie sollte denn ein Hallo-Welt auf einem Mikrocontroller aussehen? Blinken? Dann schau mal in das Tutorial. Hmm, mein Pascal-Buch beginnt mit einem WriteLn("Hallo Welt"); und wo ist der Querverweis? ciao, Stefan.
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.