www.mikrocontroller.net

Forum: Compiler & IDEs Interrupt ansprechen wie???


Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

heute frage ich euch Löcher in den Bauch... ;o)

also ich habe die Problematik, das ich weiß wie ich einstellen kann,
dass bestimmte Dinge einen Interrupt auslösen können. Aber ich weiß
nicht wie ich in WinAVR die Interruptfunktion bekannt gebe!!! Das
findet man auch nirgends in der Hilfe.

Von Keil kenne ich das noch so:

void xxxx_xx (void) interrupt 6
{
  ....
}

jetzt erklär mir doch mal bitte einer wie ich das bei WinAVR mache!?

Ich bedanke mich schon mal für die super Informationen die man hier
erhält und wünsche euch noch einen sonnigen Tag.

Gruß
Benjamin

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sollte eigentlich im avr-libc-user-manual-1.4.4.pdf stehen.

Ansonsten schau mal in der interrupt.h nach (ISR)


Peter

Autor: Peter S. (peter) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

also ich habe mir mal die HEADER bzgl. der interrupts angesehen, dabei
sind unterschiede zu der beschreibung im GCC-Turtorial zu sehen
gewesen. denn in der header (trotz neuer version von WinAVR) sind die
alten macros für die vectoren enthalten (z.b. SIG_XXXX_XXXX) und als
ich dann mit:

ISR (SIG_XXXX_XXXX)
{
    ......
}

die routine ausprobieren wollte hat sich auch nichts getan!! Was soll
ich jetzt tun????

Danke!!

Gruß

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welchen Teil des Abschnitts
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...
aus dem AVR-GCC Tutorial versteht du nicht?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Was soll ich jetzt tun????"


Nicht so tun, als könnten andere in Deinen Kopf schauen.


Also was hast Du getan, und was hast Du erwartet und was ist
stattdessen passiert ?


Peter

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du die ISRs mit 'ISR' einleitest, dann musst Du auch die
'XXXX_XXXX_vect'-Makros benutzen und nicht die veralteten
'SIG_irgendwas'-Dinger...

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mir geht se darum, ab welcher version von WinAVR setze ich die Kommandos


ISR(xxxxxx)
{
  ....
}

ein!? bzw. bis zu welchen version wird noch mit:

SIGNAL (xxxxxx)
{
  ....
}

eigesetzt!?

ich habe beides ausprobiert und keiner der befehle hatte keine
wirkung!! ich habe den globalen interrupt freigegeben, und auch die
nötigen flags in den SFR gesetzt gehabt!!

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn Du die ISRs mit 'ISR' einleitest, dann musst Du auch die
> 'XXXX_XXXX_vect'-Makros benutzen und nicht die veralteten
> 'SIG_irgendwas'-Dinger...

schön und gut!! aber wenn die neuen vectoren nicht in der header stehen
dann kann ich sie nicht verwenden!! wenn der compiler bei dem befehl
SIGNAL auch nichts macht.... , was dann??????????

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich stelle nachher mal mein programm hier hinein!! dann kann sich das ja
vielleicht mal jemand ansehen!!

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

Bewertung
0 lesenswert
nicht lesenswert
so jetzt habe ich mal mein komplettes projekt gezipt!! wenn mir jemand
mal einen Tip geben könnte!!

Das Programm ist einfach erst einmal nur spielerei! darum nicht auf die
portbelegungen achten!!

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Woher weist du, dass der Timer Overflow Interrupt
nicht aufgerufen wird?

So wie ich das sehe, machst du im Interrupt:

  (*czTimer++);

wobei
uint8_t *czTimer;

und dieser Pointer niemals einen Wert zugewiesen kriegt. Das heist,
dein Programm ändert ständig die SRAM Speicherzelle 0 (da czTimer ja
eine globale Variable ist, und als solche den Wert 0 enthält.)
Was da aber an dieser Speicherzelle steht, entzieht sich
unserer Kenntnis und Kontrolle. Das entscheidet einzig und alleine
der Compiler. Wenn du Glück hast, bügelst du nur eine unwichtige
Variable nieder, wenn du Pech hast, hast du das Runtime System
zerschossen.

Auf jeden Fall: Wenn ich mit einem Feature nicht zurecht komme,
dann schreibe ich mir ein eigenes Testprogramm, dass sich nur
mit diesem Feature beschäftigt. Zum einen kann ich mich dadurch
nur auf mein momentanes Problem konzentrieren (in deinem Fall:
warum löst der Interrupt nicht aus), kann mir saubere Testumgebungen
überlegen (zb. wenn der Interrupt kommt, soll eine LED leuchten)
und ganz wichtig: Ich werde nicht durch mögliche Fehler in meinem
eigentlichen Programm behindert und abgelenkt.

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Fehler:

(*czTimer++);

bügelt überhaupt nichts nieder. Es wird einfach nur
der Pointer erhöht. Die Dereferenzierung ist an dieser
Stelle völlig für die Katz.

Damit: Woran erkennst du das der Overflow nie aufgerufen wird?

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich habe einfach nur die zeile hinein geschrieben gehabt, um zu sehen ob
der compiler im debugmodus überhaupt in die ISR hineinspringt!! das habe
ich nie gesehen, darum gehe ich davon aus das er diese routine nie
angesprungen hat! mmmmhhhh.... also wieder mal einen gedanklichen
fehler gemacht!! oder??

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
also ich habe das noch einmal geändert!!

//Globale Variable
uint8_t Timer;

//Initialisierung
czTimer = &Timer

//ISR
SIGNAL (SIG_OVERFLOW0)
{
  uint8_t i;

  i++;
  *czTimer = i;
}

das habe ich simuliert.... die ISR wird nicht angesprungen obwohl im
TIFR das flag TOV0 gesetzt wird und im TIMSK das flag TOIE0 gesetzt
wurde!! ich komme nicht mehr klar.... entweder ich bin zu blöd oder ich
kann keine logischen zusammenhänge mehr erkennen!?

Autor: Thomas Knecht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Definiere Deinen Pointer in der ISR als volatile, sonst wird die ganze
ISR vom Optimizer weg rationalisiert, weil sie nichts macht...

volatile uint8_t *czTimer;   //Timer-Laufvariable

Dann würde ich noch sicher stellen, das die Interrups wirklich aktiv
sind, bzw. sie mit sei() schon vor der Endlosschlaufe freigeben...

//Endlosschleife, wenn kein Interrupt
sei();        // Globale Interruptfreigabe
while(1)
{
  ...
}

So funktioniert Dein gepostetes Program zumindest bei mir...

Autor: Thomas Knecht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit dem neuen Interrupt-Macros gehts übrigens bei mir ebenfalls:

==========================================
// SIGNAL(SIG_OVERFLOW0) // deprecated interrupt macro
ISR(TIMER0_OVF_vect)     // new interrupt macro
{
  (*czTimer++);
}

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hey... wahnsinn... ich sehe das der compiler einen interrupt
registriert, aber er springt immer noch nicht die ISR an!!! sondern
beginnt der compiler mit meiner initialisierung... das heißt für mich
er findet nicht den vector den er anspringen soll!? oder? wenn das so
wäre hätte ich auch noch immer ein problem mit der declaration der
ISR...

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich sehe das der compiler einen interrupt
> registriert, aber er springt immer noch nicht die ISR an!!! sondern
> beginnt der compiler mit meiner initialisierung...

Kannst du das mal naeher erläutern?
Irgendwie macht der Satz da oben überhaupt keinen Sinn.

Wenn du im Simulator mit Single-Step durch dein Programm
gehst, wird irgendwann der sei() ausgeführt (hoffentlich).
Ab diesem Zeitpunkt müsstest du im Simulator links bei den
I/O Devices sehen können, wie bei jedem Single-Step Schritt
der Zähler hochzählt. Sobald der über 255 drüber kommt, wird
die ISR angesprungen  (Breakpoint dorthin setzen, der müsste
ansprechen).

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok... gebe zu das ich ein bißchen schnell mit meinen gedanken war...
also der globale interrupt ist freigegeben!! der timer interrupt ist
enable gesetzt, der timer läuft voll und ein overflow wird registriert.
aber die interruptroutine wird nicht angesprungen, sondern mein programm
startet direkt wieder hinter meiner "main" declaration!!!

komisch.... oder??? und ich habe beide befehle ausprobiert!!!!!!

Autor: Karl heinz Buchegger (kbucheg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ein ähnliches Phänomen hatt eich auch mal.

Verwendest du noch SIGNAL oder bist du bei ISR?

Wenn du noch SIGNAL benutzt, dann musst du unbedingt
#include <avr/signal.h>
einbinden. Ansonsten kommts zu solchen Effekten
(zumindest wars bei mir so).

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du mit AVRStudio simulierst, dann schau doch mal im
Disassembler-Fenster, was in der Vektortabelle an der entsprechenden
Stelle steht. Das hört sich mir fast so an, als ob tatsächlich der
Vektor nicht korrekt initialisiert wurde und der µC bei jedem Interrupt
nen Reset macht... Das Interrupt-Flag wird doch jedes mal gelöscht,
oder?

Autor: Thomas Knecht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast Du die Timer-Laufvariable als volatile deklariert...???

volatile uint8_t *czTimer;   //Timer-Laufvariable

Ich hab den Eindruck die ISR-Funktion wird sonst komplett wegoptimiert,
und dann die Jump Adresse des ISR-Vectors auf 0 gesetzt => Restart....

IMHO eine gefährliche Eigenschaft des AVR-GCC.

Interupt-Vektoren mit volatile uint8_t *czTimer;
____________________________________________________________

+00000000: 940C002A  JMP  0x0000002A  Jump  //Reset
+00000002: 940C0045  JMP  0x00000045  Jump
+00000004: 940C0045  JMP  0x00000045  Jump
+00000006: 940C0045  JMP  0x00000045  Jump
+00000008: 940C0045  JMP  0x00000045  Jump
+0000000A: 940C0045  JMP  0x00000045  Jump
+0000000C: 940C0045  JMP  0x00000045  Jump
+0000000E: 940C0045  JMP  0x00000045  Jump
+00000010: 940C0045  JMP  0x00000045  Jump
+00000012: 940C0045  JMP  0x00000045  Jump
+00000014: 940C0045  JMP  0x00000045  Jump
+00000016: 940C0047  JMP  0x00000047  Jump //Timer0_OVF => ISR
+00000018: 940C0045  JMP  0x00000045  Jump
+0000001A: 940C0045  JMP  0x00000045  Jump
+0000001C: 940C0045  JMP  0x00000045  Jump
+0000001E: 940C0045  JMP  0x00000045  Jump
+00000020: 940C0045  JMP  0x00000045  Jump
+00000022: 940C0045  JMP  0x00000045  Jump
+00000024: 940C0045  JMP  0x00000045  Jump
+00000026: 940C0045  JMP  0x00000045  Jump
+00000028: 940C0045  JMP  0x00000045  Jump
_______________________________________________________

+00000000: 940C002A  JMP  0x0000002A  Jump
+00000002: 940C0045  JMP  0x00000045  Jump
+00000004: 940C0045  JMP  0x00000045  Jump
+00000006: 940C0045  JMP  0x00000045  Jump
+00000008: 940C0045  JMP  0x00000045  Jump
+0000000A: 940C0045  JMP  0x00000045  Jump
+0000000C: 940C0045  JMP  0x00000045  Jump
+0000000E: 940C0045  JMP  0x00000045  Jump
+00000010: 940C0045  JMP  0x00000045  Jump
+00000012: 940C0045  JMP  0x00000045  Jump
+00000014: 940C0045  JMP  0x00000045  Jump
+00000016: 940C0000  JMP  0x00000000  Jump //Timer0_OVF => RESET
+00000018: 940C0045  JMP  0x00000045  Jump
+0000001A: 940C0045  JMP  0x00000045  Jump
+0000001C: 940C0045  JMP  0x00000045  Jump
+0000001E: 940C0045  JMP  0x00000045  Jump
+00000020: 940C0045  JMP  0x00000045  Jump
+00000022: 940C0045  JMP  0x00000045  Jump
+00000024: 940C0045  JMP  0x00000045  Jump
+00000026: 940C0045  JMP  0x00000045  Jump
+00000028: 940C0045  JMP  0x00000045  Jump

Autor: Benjamin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
danke!!!!! die einbindung der signal.h hat den entscheidenden effekt
gebracht!! ich werde diese jetzt gleich durch die interrupt.h einbinden
lassen, damit kann man diese nicht vergessen!!

noch einmal danke an alle!!!!!!

Autor: Thomas Knecht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab was vergessen....

Die 2. Tabelle is ohne volatile

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich werde diese jetzt gleich durch die interrupt.h einbinden
> lassen, damit kann man diese nicht vergessen!

Spar's dir und nimm die aktuelle Version: die hat gar keine
<avr/signal.h> mehr.  Da kannst du sie auch nicht mehr vergessen.

Autor: Thomas Knecht (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An die AVR-GCC Macher:

+00000014: 940C0045  JMP  0x00000045  Jump
+00000016: 940C0000  JMP  0x00000000  Jump //Timer0_OVF => RESET
+00000018: 940C0045  JMP  0x00000045  Jump

Im obigen Beispiel sieht man, dass unter Umständen ein Jump auf die
Adresse 0 in die Interrupt-Tabelle eingetragen wird, wenn etwas schief
läuft (z.B. bei weg optimierter ISR-Funktion?)

Ist es nicht möglich, beim comilieren oder linken ein #warning
auszugeben, wenn dies passiert und eventuell auch noch ein "reti"
Statement oder ein Jump auf ein "reti" Statement?

MfG  Peter

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.