Forum: Mikrocontroller und Digitale Elektronik Probleme mit volatile


von Sebastian (Gast)


Lesenswert?

Hallo

Ich benutze einem ATMEGA32. Dort möchte ich folgendes implementieren:

Wärend der Initialisierung soll ein Array im S_RAM implementiert werden. 
Das Array soll 400 Elemente a unsigned int besitzen.

Im Hauptprogramm soll dann das Array auf einen DA-Wandler ausgegeben 
werden. Hierzu habe ich eine Funktion geschrieben, der in die 1. Adresse 
des Arrays übergebe.

Nun soll der Inhalt des Arrays per Interrupt geändert werden. In der 
Interruptserviceroutine soll eine Funktion aufgerufen werden, die auf 
das Array zugreift und die Werte verändert.

Im Hauptprogramm werden dann die veränderten Werte wieder ausgegeben.

Ich habe im Tutorial gelesen das man hierzu den Befehl "volatile" 
benutzt, jedoch habe ich es damit nicht hinbekommen

Hier mein Quellcode:

//Initialisierung des µC
volatile unsigned int spiegelpositionen[400];

void main(void)
{

// globale Interrupts deaktivieren
      #asm("cli")

      daten_auf_da_wandler_ausgeben(&spiegelpositionen[0]);

      //globale Interrupts aktivieren
      #asm("sei")
      delay_ms(100);

   };
}

/ External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
   // hier will der Compiler nicht "undefined symbol spiegelpositionen"
   neue_daten_ins_array_schreiben(&spiegelpositionen[0]);
}

Was mache ich falsch, oder wie kann ich der Unterruptserviceroutine die 
Adresse des Arrays übergeben

Grüsse

Sebastian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ein Array muss nicht wirklich als volatile deklariert werden, da selbst 
der geschickteste Optimizer eines C-Compilers es nicht schaffen wird, 
das Array zu Optimierungszwecken in Prozessorregistern zu halten ...

Das Problem wird daher an einer anderen Stelle zu suchen sein - Dein 
Quellcode sieht mir reichlich zusammenkopiert aus.

Könnte es sein, daß Dein Interrupthandler und die Deklaration der 
Variablen in unterschiedlichen Modulen zu finden sind?

Poste nicht irgendwelche zusammenhanglose Source-Fragmente, sondern 
Deinen tatächlichen Quelltext (ZIP-Attachment).

von Sebastian (Gast)


Lesenswert?

Ich kann den gesammten Quellcode nicht im Internet posten. Dies ist 
leider kein Privatprojekt.

Die ISR und das Mainprogramm sind alle in einer Datei, dadurch sollte es 
keine Probleme geben.

Wie schaffe ich es denn ein Array während der Initialisierung zu 
erzeugen das 400 Elemente enthält. Diese möchte ich im Mainprogramm 
ausgeben und in der Interruptroutine ändern.

von Sebastian (Gast)


Lesenswert?

Der Compiler gibt noch folgende Fehlermeldung raus "The estimated Data 
Stack usage(982 Bytes) exeeds the ammount allocated for the purpose in 
the C Compiler configuration It is recommanded to increase the Data 
Stack size in the Projekt | Configure|C-Compiler| Code Generation menu"

Ich will doch nicht die Daten im Stack speichern sondern im SRAM.

von Mark S. (struberg)


Lesenswert?

humm, &spiegelpositionen[0] ist ein wenig komisch geschrieben

spiegelposition[i] kann man auch als *spiegelposition+i schreiben, also 
bei 0 brauchst nix adden und auch das anschließende dereferenzieren ist 
unnötig weil du ja für den pointer die Adresse willst. Ein array ist in 
klassischem K&R C definiert als ein label an dem der speicherbereich für 
die einzelnen elemente beginnt (ist in Wirklichkeit das selbe wie ein 
assembler label). Eigentlich ist also der Adressoperator '&' nicht nötig 
(wird aber von den meisten Compiliern lenient ignoriert). Aber da gab es 
im Laufe von C schon etliche Änderungen in dem Bereich...

volatile verhindert auf jeden Fall nur, daß Variablen die für 
verschiedene parallele tasks benötigt werden nicht permanent in 
Registern gehalten werden, was aber bei einem array[400] sowieso nicht 
passieren kann.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Diese Fehlermeldung erscheint, wenn Du eine zu große automatische 
Variable anlegst. Die nämlich landen auf dem Stack.

Und das lässt vermuten, daß Dein Array "spiegelpositionen" innerhalb 
einer Funktion deklariert wird.
Und das wiederum wäre eine Erklärung dafür, daß das Array außerhalb 
dieser Funktion unbekannt ist.

Das sieht man zwar anhand Deines Quelltextfragmentes nicht, aber die 
Symptome deuten darauf hin.

Was genau magst Du aber mit

  "Wie schaffe ich es denn ein Array während der Initialisierung
  zu erzeugen das 400 Elemente enthält."

meinen? Während welcher Initialisierung?

Möchtest Du ein Array erzeugen und gleichzeitig mit konstanten Werten 
initialisieren?

Was bedeutet für Dich das Wort "Initialisierung"? In Deinem 
Quelltextfragment steht das als Kommentar oberhalb der 
Arraydeklaration/definition.

von Karl H. (kbuchegg)


Lesenswert?

Sebastian wrote:
> Ich kann den gesammten Quellcode nicht im Internet posten. Dies ist
> leider kein Privatprojekt.

Dann specke es soweit ab, dass es
* vollständig ist
* den Fehler noch immer zeigt

alles andere artet hier zu Rätselraten aus (um das Bild
von der Glaskugel nicht weiter zu strapazieren).

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Diese Woche verwenden wir Glaswürfel. Die rollen nicht so leicht weg.

von Mark S. (struberg)


Lesenswert?

Rufus t. Firefly wrote:
> Diese Woche verwenden wir Glaswürfel. Die rollen nicht so leicht weg.

und außerdem haben Würfel auch wesentlich mehr 'spiegelpositionen'

von Sebastian (Gast)


Lesenswert?

Ich habe jetzt ein globales Array erzeugt, damit sind die Probleme vom 
Tisch. Somit kann ich im Hauptprogramm und in der Interruptroutine 
darauf zugreifen.

Mit Initialisierung meinte ich folgendes. Power On beim µC anschließend 
werden die Ports initialisiert und anschließend werden die Variablen 
erzeugt. Danach kommt man in die While-Programmschleife.

Grüsse

Sebastian

von PM (Gast)


Lesenswert?

Das verstehe ich jetzt nicht...
In Deinem "code" oben war das Array doch schon global...

von Sebastian (Gast)


Lesenswert?

Nein das Array war voher nicht global sonder lokal.

von PM (Gast)


Lesenswert?

Aber es steht doch ausserhalb der main(), sprich in keiner Funktion. Das 
ist für mich global und ich bin mir recht sicher das der compiler das 
auch so sieht ;)

von Karl H. (kbuchegg)


Lesenswert?

Sebastian wrote:
> Nein das Array war voher nicht global sonder lokal.


In deinem Originalprogramm (das du nicht herzeigst) vielleicht.
Nicht jedoch in dem hier gezeigten Ausschnitt.

Womit wir wieder mal beim Thema wären:
Es funktioniert einfach nicht, wenn man ein Programm
postet das so ähnlich (aber doch ganz anders) als jenes
ist, welches durch den Compiler geht und von dem die
Fehlermeldungen präsentiert werden.
Kein Mensch kann dir da vernünftig helfen.

von Sebastian (Gast)


Lesenswert?

Ok ich habe jetzt das ganze global gemacht und damit funktioniert es 
auch. Trotzdem danke für Eure Hilfe

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.