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
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.
Mit volatile deklarieren, sonst wird die wegoptimiert. Siehe auch etliche Beiträge hier.
"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.
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
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.
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?
versuch's mal in der main{}... sprich: int main(void) { hour = 13; . . . }
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
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 :-|
> 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.
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.