Hallo Zusammen. Habe ein weiteres Problem mit meinen Interrupts. Ich schrieb ein programm bei welchem ich bei jeder steigenden-Flanke eine LED aufleuchten lies. Es funnktionierte alles TipTop bis dort hin. ""Auf den Angehängten C code bezogen""""" Nun wollte ich bei jeder steigenden-Flanke eine Variabel namens Takt_Counter jeweils um 1 erhöhen. sobald die Variabel grösser ist als 10sollen die LEDs An PORTB leuchten, "else" sollen sie nicht leuchten. und wenn die Variabel den Wert 20 erreicht, soll die Variabel auf 0 gesetzt werden. leider aber leuchtet kein LED :-( sieht da irgendjemand einen Fehler in meinem Programm Danke
Takt_Counter ist nicht volatile deklariert, wodurch das Hauptprogramm möglicherweise Änderungen der Variable nicht mitbekommt. Die delay-Funktion ist ziemlicher Mumpitz. Dazu gibt es in der util/delay.h fertige Funktionen, die sich auch jeglicher Schleifen-Wegoptimierung entziehen (falls Du den AVR-GCC benutzt, was ich aus der Verwendung von "avr/interrupt.h" schließe). >SREG = 0x80; Das ist ebenfalls nicht gut. Dafür gibts extra die (atomaren) Anweisungen sei() zum setzen des I-Bit und cli() zum Löschen desselben. Außerdem fehlt etwas ganz wichtiges, nämlich ein "#include<avr/io.h>"... Das AVR-GCC-Tutorial solltest Du Dir unbedingt mal anschauen...
Da "#include<avr/io.h>" in "avr/interrupt.h" schon enthalten ist, kann ich doch auf diese textzeile verzichten? oder etwa nicht? Und ""Takt_Counter"" initialisier ich ja als Globale Variabel, so sollte diese auch im Main erkannt werden. versuche es trotzdem mal. Danke
Gimpel wrote: > Da "#include<avr/io.h>" in "avr/interrupt.h" schon enthalten ist, kann > ich doch auf diese textzeile verzichten? oder etwa nicht? Keine gute Idee. Du verwendest Dinge aus io.h, also solltest du das auch includieren. Wenn interrupt.h seinerseits io.h inkludiert, dann ist das seine Sache, die dich nicht interessieren muss. > > Und ""Takt_Counter"" initialisier ich ja als Globale Variabel, so sollte > diese auch im Main erkannt werden. Es geht nicht um die Initialisierung. Es geht um die Erhöhung, bzw. darum, was der Optimizer sich dabei denkt, wenn er deine Hauptschleife in main() sieht. Der denkt sich nämlich: Oh, super: Da wird ständig eine Variable Takt_Counter abgefragt. Aber innerhalb der Schleife gibt es für Takt_Counter keine Möglichkeit, wo es sich ändern könnte. Also brauch ich die diese Variable gar nicht aus dem Speicher auslesen, sondern halte sie ganz einfach in einem Register vor. So kann ich dann die Zeit für einen Speicherzugriff sparen. Super: Deine Interrupt Routine ändert laufend den Wert im Speicher, aber deine Hauptschleife holt ihn sich nie aus dem Speicher, weil der Optimizer diesen Speicherzugriff wegoptimiert hat. Und da kommt volatile ins Spiel: volatile teilt dem Compiler mit, dass er diese Variable auf jeden Fall immer aus dem Speicher holen muss, da sie auf Wegen verändert wird, die der Compiler nicht erkennen kann.
Sie hatten wirklich recht :-) Wenn ich den Ganzen CODE von der Endlosschlaufe in das Interrupt unterprogramm nehme, dan funktioniert das ganze. Gibt es irgendeine Möglichkeit wie ich die Variabel ""Takt_Counter"" deklarieren kann, dass ich damit in der Endlosschlaufe im Main, wie auch in der Interruptfunktion mit ein und der selben Variabel arbeiten kann? Danke
Gimpel wrote: > Sie hatten wirklich recht :-) In einem Forum ist man automatisch 'per Du' > > Wenn ich den Ganzen CODE von der Endlosschlaufe in das Interrupt > unterprogramm nehme, dan funktioniert das ganze. Das ist aber nicht die vorgeschlagene Änderung :-) > > Gibt es irgendeine Möglichkeit wie ich die Variabel ""Takt_Counter"" > deklarieren kann, dass ich damit in der Endlosschlaufe im Main, wie auch > in der Interruptfunktion mit ein und der selben Variabel arbeiten kann? > Wurde doch schon gesagt: Die Variable volatile machen (siehe auch die Erklärung im vorhergehenden Post)
1 | volatile int Takt_Counter; |
Gimpel wrote: > Gibt es irgendeine Möglichkeit wie ich die Variabel ""Takt_Counter"" > deklarieren kann, dass ich damit in der Endlosschlaufe im Main, wie auch > in der Interruptfunktion mit ein und der selben Variabel arbeiten kann? Hab ich doch schon im ersten Posting geschrieben und Karl Heinz hat es in seinem (wie immer sehr ausführlichen) Posting ebenfalls erwähnt: Die Variable muss volatile deklariert sein.
Danke vielmals..... Habe es doch noch gecheckt wie das gemeint war :-) Jetzt funktioniert es tiptop. Man hört sich beim nächsten Problem ;-)
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.