mikrocontroller.net

Forum: Compiler & IDEs mit Interrupt globale Variablen verändern


Autor: Bartman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich verwende gcc-avr unter Linux und möchte nun ein Programm schreiben,
bei dem durch ein Interruptaufruf eine Variable verändert wird. Diese
veränderte Variable soll dann in anderen Funktionen (*hier die main
Funktion) ausgewertet werden. Leider funktioniert das Programm so
nicht! An was liegt das? Wenn ich die Variable hour erst in der main
deklariere funktioniert zwar die Abfrage, dann erkennt aber die
Interrupt routine die Variable nicht mehr.

hier mein Programm:

/*dcf77 Funkuhr*/

#include <avr/io.h>
#include <avr/signal.h>


char hour=13; // globale Variable


void initialisation(void)
{
DDRC=0xFF; //PORTC als Ausgang
PORTC=0xFF; //alle LEDs aus
}


INTERRUPT(SIG_OVERFLOW0)//Interrupt Timer0 Overflow
{
 //... soll hier später die Variable hour verändern
}


int main (void)
{
initialisation();


if(hour==13) // hier die Abfrage der globalen Variable
{
PORTC=0x00;
}

return 0;
}

Eigentlich sollten ja nun die LEDs angehen, da die globale Variable 13
ist, tuts abba nicht.  Hat jemand ne Ahnung?

Danke
Gruss Bartman

Autor: Malte Marwedel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuche es mal mit
char volatile hour= 13;

Das volatile sorgt dafür, dass die Register immer sofort zurück in den
SRAM geschrieben werden.
Ansonsten: nachdem portc eingeschaltet wurde, wo springt das Prog dann
hin? wieder zum Anfang? das würde die LEDs ja erstmal wieder
ausschalten.

Ansonsten würde mich mal interresieren, wie ein makefile zum
compilieren unter Linux aussehen muss. Habe bisher nur unter Windows
compilieren können.

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit volatile deklarieren, sonst wird die wegoptimiert.

Siehe auch etliche Beiträge hier.

Autor: Dieter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Das volatile sorgt dafür, dass die Register immer sofort zurück in den
SRAM geschrieben werden."

Das ist falsch. Volatile verhindert, dass der Compiler beim Optimieren
die Variable anfasst.
In obigem Beispiel wird sie also gar nicht erst angelegt.

Was das Makefile angeht, so habe ich ein einziges für Windows und
Linux. Das sollte gleich sein, es sei denn, Du rufts irgendwelche
Windowsprogramme auf, aber auch das kannst Du mit verschiedenen
Make-Targets umgehen.

Autor: Bartman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich habe das Programm laut euren Hinweisen modifiziert, aber leider
ohne erfolg... hmmm an was könnte das denn noch liegen?

/*dcf77 Funkuhr*/

#include <avr/io.h>
#include <avr/signal.h>


char volatile hour= 13;


void initialisation(void)
{
DDRC=0xFF; //PORTC als Ausgang
PORTC=0xFF; //alle LEDs aus
}




int main (void)
{
initialisation();

while(1)
{

  if(hour==13)
  {
  PORTC=0x00;
  }

}

return 0;
}



PS.:
So sieht mein Makefile aus:

#Makefile für dcf77

dcf77.hex: dcf77.out
  avr-objcopy -j .text -O ihex dcf77.out dcf77.hex
dcf77.out: dcf77.o
  avr-gcc -g -mmcu=at90s8515 -o dcf77.out dcf77.o
dcf77.o: dcf77.c
  avr-gcc -g -Os -mmcu=at90s8515 -c dcf77.c

clean:
  rm -rf *.o *.out

erase:
  uisp -dprog=stk200 -dlpt=/dev/parport0 -dpart=AT90S8515 --erase

upload:
  uisp -dprog=stk200 -dlpt=/dev/parport0 -dpart=AT90S8515 --upload
if=dcf77.hex

Autor: Bartman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bzw.wenn die gar nicht erst angelegt wird, wie kann ich das ganze am
Besten angehen um wie gesagt durch nen Interrupt ein Variable zu
verändern, die ich dann in anderen Funktionen weiter auswerte.
Vielleicht hat ja jemand ein Programm Beispiel.
Immerhin kann das Problem ja nicht unbekannt sein...
Also Jungs, lasst mich bitte nicht hängen.

Autor: Bartman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab etwas rausgefunden. Die Variable lässt sich offenbar nicht mit
dem Aufruf volatile char hour=13; definieren. Erst bei einer Definition
durch den Interrupt mit einem Wert war dieser auch in der main Funktion
verfügbar.

Der Eintrag volatile char hour;
      hour=13;

global eingetragen brachte sogar beim kompilieren eine Fehlermeldung:
  avr-gcc -g -Os -mmcu=at90s8515 -c dcf77.c
dcf77.c:8: error: conflicting types for `hour'
dcf77.c:7: error: previous declaration of `hour'
dcf77.c:8: warning: data definition has no type or storage class
make: *** [dcf77.o] Fehler 1

Warum lässt sich die Variable nur global deklarieren, aber nicht
definieren, also mit einem Wert belegen?

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
versuch's mal in der main{}...
sprich:
int main(void)
{
   hour = 13;
.
.
.

}

Autor: Bartman (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
In der main ist die Variable halt nicht für die Interruptfunktion
verfügbar. Hmmm ich mache es jetzt über eine Initialisierungsfunktion,
in der ich dann (beim Aufruf dieser in der main ) der Variable einen
Wert zuweise. Warum das aber nicht in einem Aufwasch direkt bei der
Deklaration ( sprich: volatile char hour=13) geht weiss ich bis jetzt
noch nicht. Also falls jemand eine logische Erklärung hat. Immer her
damit. Ansonsten vielen Dank für eure Antworten.

Mfg  Bartman

Autor: Malte Marwedel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
typedef unsigned char  u08;
u08 volatile empfangir = 0xff;
geht bei einem Projekt von mir wunderbar (erst char, dann volatile).

Habs jetzt auch geschafft, mal under linux zu comilieren. Ich bekomm
aber  nur alte rpm Pakete installiert, so dass ein Prog 32Byte größer
als mit Winavr wurde -> hätte nicht mehr in den AVR gepasst :-|

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Das ist falsch. Volatile verhindert, dass der Compiler beim
> Optimieren die Variable anfasst.  In obigem Beispiel wird sie also
> gar nicht erst angelegt.

So wie ich diese Aussage lese, ist es schlicht Unsinn.

`volatile' verhindert jegliche Zugriffsoptimierungen auf eine derart
deklarierte Variable.  Jegliche Leseoperation von dieser Variablen
liest also vom entsprechenden RAM, jegliche Schreiboperation schreibt
dorthin.

Das ist die FAQ #1, bitte die FAQ auch lesen...

,,Angelegt'' (im Sinne von: Speicher reserviert) wird die Variable
sowohl mit als auch ohne volatile.

Autor: tubbu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
puhh
ich such schon den ganzen tag nach einem fehler
...
wollte auch ne globale variable im interrupt ändern und dann woanders
auslesen..

jetzt mit dem volatile klappts endlich

und ich such mich hier kaputt

thx!!

lob ans forum

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht solltest Du ja zuerst mal die avr-libc FAQ durchlesen?

`volatile' ist nicht umsonst FAQ #1.

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.