Forum: Mikrocontroller und Digitale Elektronik Stringprobleme mit WinAVR (char x[])


von Thomas Decker (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich arbeite gerade an meinem ersten Projekt mit einem ATmega.
Gearbeitet habe ich schon mit einem 80C51 und einem Renesas R8C.
Folgendes Problem bringt mich gerade zum grübeln:
Manchmal funktioniert die Funktion und manchmal nicht, es hängt davon
ab, wo ich sie aufrufe.
Der ATmega springt jedes mal in die Funktion, aber manchmal trifft die
Bedingung der while()-Schleife schon von Anfang an nicht zu. So als
wäre der übergebene String 0 Zeichen lang.
Hat jemand eine Idee?

Grüße
Thomas

von Thomas Decker (Gast)


Lesenswert?

Ich sollte dazu erwähnen, wie die Funktion aufgerufen wird:
Normalerweise einfach so: sendString("test");
Dabei wird ja automatisch nach dem letzten Zeichen eine NULL angefügt,
um das Ende des Strings zu markieren.
Die While()-Schleife läuft ja solange, bis die NULL erreicht ist. Wie
kann die NULL schon vorher auftauchen?

von Karl H. (kbuchegg)


Lesenswert?

Die Funktion an sich ist in Ordnung.
Bedenke: Was du siehts, sind die Auswirkungen eines
Fehlers, der an ganz anderer Stelle sitzen kann.
Du siehts immer nur die Auswirkungen, niemals
die Ursache. Ein derartiges Verhalten kann
durch vielerlei Dinge verursacht werden.
Die häufigsten:
 * Array Überlauf
 * Du weist etwas an eine String Konstante zu
 * Da wir auf einem µC mit arge eingeschränkten
   Resourcen sind, ist auch ein Stacküberlauf
   nicht auszuschliessen.


Da

von Andreas B. (Gast)


Lesenswert?

Überprüfe mal bitte auf die binäre Null '\0'. Ich bin mir nicht
sicher ob der C-Standard vorsieht das '\0' == 0 ist.

Wenn du dir nicht sicher bist, untersuche mal wann die Schleife
abbricht:

unsigned char sendString(char string[])
{
unsigned char i;
i = 0;

while(string[i] != 0)
{
  sendByteAsClear2(string[i]);
  i++;
}
return i;
}

und danach vielleicht mal i abfragen, welchen Wert das hat. Noch besser
wäre es, du würdest den Nullterminierten String nicht einfach
voraussetzen, sondern die Länge des Strings der Funktion mitgeben.

Ansonsten ist (wie Karl Heinz schon sagte) der Code den wir hier sehen
in Ordnung

Gruß Andreas

von thkais (Gast)


Lesenswert?

Hast Du sehr viele Aufrufe mit viel Text? Die Eigenart des AVR-GCC
besteht darin, den "Text" zwar als Konstante im Flash abzuspeichern,
aber zu Beginn der Programmausführung in den Ram zu kopieren. Somit
wäre es durchaus möglich, dass bei vielen Texten irgendwann der Ram
voll ist.
Es gibt eine Möglichkeit dies zu verhindern, schau Dir hierzu die
Bibliothek "pgmspace.h" an. Im Tutorial könnte dies weiterhelfen:
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29

von Thomas Decker (Gast)


Lesenswert?

Vielen Dank für die Antworten, es scheint wirklich daran zu liegen, dass
ich zu viele "Strings" habe. Mal ein paar auskommentiert und das ganze
funktioniert perfekt. Werde mir den Link heute abend mal genau
anschauen.

Die Dezimalzahl 0 entspricht dem ersten Ascii-Zeichen "NULL",
deswegen klappt das auch ohne \.

Zum Thema RAM: Ich verwende einen ATmega168, eigentlich war ein ATmega8
geplant, aber ich habe sicherheitshalber doch auf doppelten Flash
gewählt. RAM hat der aber auch nur 1k. Über 512Bytes werden davon schon
von einer FAT16-Schreib/Leseroutine belegt.

Aufgabe des ganzen:
Der ATmega ist immer im Power-Down-Mode, wird per interrupt alle 15min
von einem Realtime-IC(
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2686 ) geweckt und liest
an einem Analogeingang den Druck eines Drucksensors ein und schreibt
diesen Wert mit der Aktuellen Uhrzeit/Datum auf eine MMC-Karte.
Das ganze hat den Zweck, den Wasserstand in einer Höhle zu
dokumentieren.

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
Noch kein Account? Hier anmelden.