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


von Bartman (Gast)


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

von Malte Marwedel (Gast)


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.

von Dieter (Gast)


Lesenswert?

Mit volatile deklarieren, sonst wird die wegoptimiert.

Siehe auch etliche Beiträge hier.

von Dieter (Gast)


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.

von Bartman (Gast)


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

von Bartman (Gast)


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.

von Bartman (Gast)


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?

von Rahul (Gast)


Lesenswert?

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

}

von Bartman (Gast)


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

von Malte Marwedel (Gast)


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 :-|

von Jörg Wunsch (Gast)


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.

von tubbu (Gast)


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

von Jörg Wunsch (Gast)


Lesenswert?

Vielleicht solltest Du ja zuerst mal die avr-libc FAQ durchlesen?

`volatile' ist nicht umsonst FAQ #1.

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.