Forum: Mikrocontroller und Digitale Elektronik Atmega128 Variablen-Problem


von Tobias B. (roxxity)


Lesenswert?

Hi, ist sicher ne Kinderfrage, aber ich find dazu leider nix...

Und zwar programmiere ich grad einen AT90CAN128 (=Atmega128+CAN?) in C 
bzw. dem AVR-Studio, der Code ist schon ziemlich groß, Variablen gibts 
sehr viele, allerdings nur Bytes und Words bzw. diese als Array.

Jetzt stell ich gerade fest, dass eine Variable, die am Anfang mit einem 
Wert (0) initialisiert wird und ansonsten nicht verändert (soweit bin 
ich noch nicht),
einfach ihren Wert ändert. Das stelle ich über ein Pin fest, an das die 
Variable ausgegeben wird.

Ursprünglich hab ich die Variable während dem Programmablauf 
initialisiert (=0)

Wenn ich die Variable über ein Display ausgebe, ändert sich allerdings 
nichts mehr.

Wenn ich die Variable bei der Variablendeklaration schon initialisiere, 
ändert sich auch nichts mehr.

Jedoch "volatile" vor der Variablendeklaration zu setzen bringt keine 
Abhilfe.


Wodurch kommt das bzw. wie kann ich es sicher unterbinden?


Grüße,
Tobias

von Ulf R. (roolf)


Lesenswert?

Tobias B. schrieb:

> Jetzt stell ich gerade fest, dass eine Variable, die am Anfang mit einem
> Wert (0) initialisiert wird und ansonsten nicht verändert (soweit bin
> ich noch nicht),
> einfach ihren Wert ändert. Das stelle ich über ein Pin fest, an das die
> Variable ausgegeben wird.

Das ist Deine Idee. Der Sourcecode (den wir bisher nicht sehen konnten) 
zeigt aber etwas anderes.

von Tobias B. (roxxity)


Lesenswert?

1
uint8_t OUTP_READY;
2
uint8_t OUTP_LIMITER=0;   //  <--- So gehts, ohne =0 ändert sich es.
3
uint8_t OUTP_BUZZER;
4
5
....
6
7
void init_ports(void)
8
{
9
  OUTP_BUZZER = 0;
10
  OUTP_READY = 0;
11
  OUTP_LIMITER = 0;
12
  DDRA = 0b00000111;  // 3 Digitale Ausgänge an Port A
13
  DDRF = 0b00000000;  // ADCs nur lesen
14
  PORTF = 0b00000000;  // Keine Pullup-Widerstände am ADC
15
}
16
17
void write_pins(void)
18
{
19
  uint8_t out = 0;
20
  if(OUTP_READY)
21
    out |= (1<<PA0);
22
  if(OUTP_LIMITER)
23
    out |= (1<<PA1);
24
  if(OUTP_BUZZER)
25
    out |= (1<<PA2);
26
  PORTA = out;  
27
}

es geht um OUTP_LIMITER und die Variable wird sonst nirgends im Code 
verwendet...

Letzte Funktion wird über eine Endlosschleife in der main() dauernd 
wiederholt

von Randy (Gast)


Lesenswert?

Vielleicht reicht das SRAM nicht für alle globalen Variablen + Stack. 
Dann überschreibt der Stack die Variablen. AFAIK wird das nicht durch 
eine Fehlermeldung abgefangen. Pro ineinandergeschachtelten 
Funktionsaufruf wird auf dem Stack Platz für die Rücksprungadresse plus 
alle lokalen Variablen der Funktion benötigt.

HTH
Randy

von Tobias B. (roxxity)


Lesenswert?

Sowas dachte ich mir auch schon, nur zeigt der Compiler das nicht an 
(wie er es beim Atmega8 z.B tut.
1
AVR Memory Usage
2
----------------
3
Device: at90can128
4
5
Program:   18652 bytes (14.2% Full)
6
(.text + .data + .bootloader)
7
8
Data:       3190 bytes (77.9% Full)
9
(.data + .bss + .noinit)
10
11
EEPROM:     1610 bytes (39.3% Full)
12
(.eeprom)

von Randy (Gast)


Lesenswert?

> Sowas dachte ich mir auch schon, nur zeigt der Compiler das nicht an
> (wie er es beim Atmega8 z.B tut.
...
> Data:       3190 bytes (77.9% Full)
> (.data + .bss + .noinit)

Tut er hier auch nicht. Die 3190 Bytes sind die Variablen die immer 
Speicher belegen (d.h. globale und static). Wie groß der Stack wird weiß 
der Complier nicht, das hängt ja davon ab wie tief verschachtelt die 
Funktionaufrufe stattfinden. Das stellt sich erst zur Laufzeit raus. 
AFAIK haben die AVRs keine (Hardware-)Logik eingebaut die überprüfen 
kann ob der Stack so groß geworden ist dass er in den Speicherbereich 
der globalen Variablen hineingewachen ist.

Randy

von Karl H. (kbuchegg)


Lesenswert?

Variablen, die aus unerfindlichen Gründen ihren Wert ändern, können auch 
ein Hinweis darauf sein, dass irgendwo ein Arrayzugriff in die Hose geht 
und du ausserhalb der definierten Arrayindizierung in das Array 
schreibst
1
uint8_t i = 5;
2
uint8_t Array[5];
3
uint8_t j = 8;
4
5
int main()
6
{
7
  Array[5] = 4;
8
9
  // an dieser Stelle im Programm hat entweder i oder j,
10
  // je nach Compiler und in welcher Reihenfolge er die
11
  // Variablen im Speicher ablegt, seinen Wert geändert
12
}

Dies ist eigentlich der häufigste Fall, dicht gefolgt vom Stacküberlauf, 
bei dem der Stack in den Variablenbereich hineinwächst.

von Tobias B. (roxxity)


Lesenswert?

Lag wohl an beidem...

Hab nen String übergeben a eine Displayfunktion. String abgekürzt und 
jetzt funktioniert es.

So muss ich wohl ein paar Arrays ins EEPROM auslagern bzw. drin lassen.
Hatte bis jetzt das alle Daten beim Start aus dem EEPROM ins SRAM 
geladen, um bisschen Rechenzeit zu sparen.

Danke für eure Hilfe!

von Stefan E. (sternst)


Lesenswert?

Schau mal lieber erst mal nach, was du so an konstanten Strings im 
Programm hast, und stecke die ins Flash.

von Karl H. (kbuchegg)


Lesenswert?

Tobias B. schrieb:
> Lag wohl an beidem...
>
> Hab nen String übergeben a eine Displayfunktion. String abgekürzt und
> jetzt funktioniert es.

String, der in einem Array zwischengespeichert wird?
Array zu klein dimensioniert?
Das abschliessende \0 Zeichen nicht eingerechnet?

von Tobias B. (roxxity)


Lesenswert?

1
void lcd_str8(const char *s)  // Strings ausgeben, 8 Pixel Schrifthöhe
2
{
3
  uint8_t chr;
4
    while ((chr = *s++))
5
  { lcd_chr8(chr); }
6
}

Ich bin mir nicht sicher was der Compiler hier macht, aber ich vermute, 
dass der String hier als Array an die Funktion übergeben wird.

Glaube nicht dass der Compiler so clever ist, und die Zeichen einzeln 
aus dem Flash ausliest.

Abgesehen davon ist der Platz im SRAM tatsächlich sehr begrenzt, daher 
werd ich ihn ausmisten müssen.

von Tobias B. (roxxity)


Lesenswert?

Problem erkannt und wie immer ists ganz einfach.
Der Text geht aus dem Display hinaus... das stinkt verdächtig nach dem 
Array-Überlauf.

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.