mikrocontroller.net

Forum: Compiler & IDEs Variablen Wahn?


Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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[].

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Er überschreibt dann irgendwas, zum Beispiel buffer.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan May (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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.

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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 ...

Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.nongnu.org/avr-libc/user-manual/group__...
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)

Autor: Stefan May (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: tex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@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.

Autor: Stefan May (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.