mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt ATtiny 45


Autor: Gimpel (Gast)
Datum:
Angehängte Dateien:

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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Gimpel (Gast)
Datum:

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

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

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

Autor: Gimpel (Gast)
Datum:

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

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

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

Autor: Johannes M. (johnny-m)
Datum:

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

Autor: Gimpel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke vielmals.....

Habe es doch noch gecheckt wie das gemeint war :-)
Jetzt funktioniert es tiptop.

Man hört sich beim nächsten Problem ;-)

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.