Forum: Mikrocontroller und Digitale Elektronik Struct Problem, ändert zufällig Adressen anderer Variabeln


von Ralf K. (ralf82k)


Lesenswert?

Hallo,

habe ein struct Problem. ATMEGA 128, AVR Studio Optimierung 02

In meinem Programm werden Werte (Strings) auf ein Display geschrieben. 
Irgendwann fiel mir auf, dass ein Wert nicht mehr aktualisiert wird.
Schaltet man die Optimierung auf 01 war der Fehler weg. Oder je nachdem 
wenn man was im Programm änderte.

Nach langem suchen war erstmal klar, das die Adresse des Strings sich im 
Programm auf einmal veränderte, was ja eigentlich nicht möglich ist. 
Liegt ja fest auf dem RAM. Also sie sprang zwischen zwei Werten. Nach 
weiterem Suchen stand fest, dass es erst auftritt sobald der erste Wert 
auf der RTC gelesen wurde.
Dort ist ein struct enthalten, welches die Zeit als werte und das 
gesamte Datum als String enthält.

typedef struct Zeit
{
  unsigned char Sec;
  unsigned char Min;
  unsigned char Std;
  unsigned char WTag;
  unsigned char Tag;
  unsigned char Monat;
  unsigned int Jahr;
  char Time[20];
};

struct Zeit RX4045_array;

In der Funktion wo ich die RTC auslese schreibe ich dann die Zeiten in 
den struct.

RX4045_array.Sec = Sec;
RX4045_array.Min = Min;
RX4045_array.Std = Std;
RX4045_array.WTag = WTag;
RX4045_array.Tag = Tag;
RX4045_array.Monat = Monat;
RX4045_array.Jahr = Jahr;

und anschließend wandel ich das alles noch in einen String um und 
schreib es in die RX4045_array.Time variable. Achtung das ist nicht die 
variable wo sich die Adresse geändert hat sondern irgendeine im 
Programm.

Kommentiere ich die Zuweisung vom struct der einzelnen Ziffern aus, also 
alles außer dem String klappt das ganze Programm und die Adresse wird 
nicht mehr verändert.

Ich bin mir nicht sicher ob ich den struct richtig definiert habe. Ich 
mach das in der Header Datei der RTC, greife aber darauf auch global zu.
bei kompilieren kommt noch diese Warnmeldung:
../RX4045.h:14: warning: useless storage class specifier in empty 
declaration

Welches dieser Zeile vom struct ist  };

Wenn ich dort direkt dies }RX4045_array;  schreibe
kommt und die Neuzuweisung weg lasse kommt an jeder stelle wo ich ins 
struct schreibe diese Fehlermeldung

../RX4045.c:120: error: expected identifier or '(' before '.' token

Was mache ich falsch bzw. wie definiere ich das struct richtig?

Gruß Ralf

von Klaus W. (mfgkw)


Lesenswert?

Das riecht nach einem Problem mit Speicher in der Art:
- du verwendest malloc() und der Platz reicht nicht, evtl.
  in Kombination mit zuviel Stackverbrauch
- du verwendest malloc() und free() und benutzst den Speicher noch
  danach
- du gibst in einer Funktion einen Zeiger auf automatische
  Variablen zurück
- Zeiger auf nicht initialisierte Variablen
- vergessene Stringterminierung
- zu kleine Array-Grenzen
- ähnliche Schweinereien, die man reihenweise konstruieren kann

von Ralf K. (ralf82k)


Lesenswert?

malloc und free benutze ich nicht.
Zeiger benutze ich auch nicht, außer in der Uart Funktion, aber das ist 
die aus dem Uart Tutorial.
Stringterminierung sollte eigentlich überall vorhanden sein. Sonst würde 
der ja was anzeigen, aber weiter schreiben. Dies sollte auch nicht die 
Startadresse des Strings verändern.

Ralf

von Klaus W. (mfgkw)


Lesenswert?

Die Warnung wegen useless kommt jedenfalls davon, daß
du ein typedef hast, aber keinen Namen für den neuen Typ
angibst.

Also entweder so:
1
typedef struct Zeit
2
{
3
  unsigned char Sec;
4
  unsigned char Min;
5
  unsigned char Std;
6
  unsigned char WTag;
7
  unsigned char Tag;
8
  unsigned char Monat;
9
  unsigned int Jahr;
10
  char Time[20];
11
} neuer_name_fuer_struct_zeit_t;

Oder so:
1
struct Zeit
2
{
3
  unsigned char Sec;
4
  unsigned char Min;
5
  unsigned char Std;
6
  unsigned char WTag;
7
  unsigned char Tag;
8
  unsigned char Monat;
9
  unsigned int Jahr;
10
  char Time[20];
11
};

Ist aber nicht dramatisch.

von Klaus W. (mfgkw)


Lesenswert?

Sonst sehe ich nichts falsches, soweit es hier steht.
Das Problem ist irgendwo in den anderen 5 Zeilen deines Programms.

von Ralf K. (ralf82k)


Lesenswert?

Hey,

Natürlich war der Programmierer der dumme!
Ich hatte mir einen Hilfsstring in der Funktion deklariert der 4 Zeichen 
lang war. Blöderweise habe ich damit die Jahreszahl umgerechnet. Habe 
das nun auf 5 Zeichen erweitert und es läuft :-)

Konnte natürlich auch beim Printen aufs Display nicht auffallen weil es 
eine ganz andere Variable war.

DANKE!

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.