mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Probleme mit volatile


Autor: Sebastian (Gast)
Datum:

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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

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

Autor: Sebastian (Gast)
Datum:

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

Autor: Sebastian (Gast)
Datum:

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

Autor: Mark Struberg (struberg)
Datum:

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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

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

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

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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

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

Autor: Mark Struberg (struberg)
Datum:

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

Autor: Sebastian (Gast)
Datum:

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

Autor: PM (Gast)
Datum:

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

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein das Array war voher nicht global sonder lokal.

Autor: PM (Gast)
Datum:

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

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

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

Autor: Sebastian (Gast)
Datum:

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

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.