mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Atmega128 Variablen-Problem


Autor: Tobias B. (roxxity)
Datum:

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

Autor: Ulf Rolf (roolf)
Datum:

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

Autor: Tobias B. (roxxity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint8_t OUTP_READY;
uint8_t OUTP_LIMITER=0;   //  <--- So gehts, ohne =0 ändert sich es.
uint8_t OUTP_BUZZER;

....

void init_ports(void)
{
  OUTP_BUZZER = 0;
  OUTP_READY = 0;
  OUTP_LIMITER = 0;
  DDRA = 0b00000111;  // 3 Digitale Ausgänge an Port A
  DDRF = 0b00000000;  // ADCs nur lesen
  PORTF = 0b00000000;  // Keine Pullup-Widerstände am ADC
}

void write_pins(void)
{
  uint8_t out = 0;
  if(OUTP_READY)
    out |= (1<<PA0);
  if(OUTP_LIMITER)
    out |= (1<<PA1);
  if(OUTP_BUZZER)
    out |= (1<<PA2);
  PORTA = out;  
}

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

Autor: Randy (Gast)
Datum:

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

Autor: Tobias B. (roxxity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas dachte ich mir auch schon, nur zeigt der Compiler das nicht an 
(wie er es beim Atmega8 z.B tut.
AVR Memory Usage
----------------
Device: at90can128

Program:   18652 bytes (14.2% Full)
(.text + .data + .bootloader)

Data:       3190 bytes (77.9% Full)
(.data + .bss + .noinit)

EEPROM:     1610 bytes (39.3% Full)
(.eeprom)


Autor: Randy (Gast)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

uint8_t i = 5;
uint8_t Array[5];
uint8_t j = 8;

int main()
{
  Array[5] = 4;

  // an dieser Stelle im Programm hat entweder i oder j,
  // je nach Compiler und in welcher Reihenfolge er die
  // Variablen im Speicher ablegt, seinen Wert geändert
}

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

Autor: Tobias B. (roxxity)
Datum:

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

Autor: Stefan Ernst (sternst)
Datum:

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

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

Autor: Tobias B. (roxxity)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void lcd_str8(const char *s)  // Strings ausgeben, 8 Pixel Schrifthöhe
{
  uint8_t chr;
    while ((chr = *s++))
  { lcd_chr8(chr); }
}

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.

Autor: Tobias B. (roxxity)
Datum:

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

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.