Forum: Compiler & IDEs Interrupt ansprechen wie???


von Benjamin (Gast)


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

von Peter D. (peda)


Lesenswert?

Das sollte eigentlich im avr-libc-user-manual-1.4.4.pdf stehen.

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


Peter

von Peter S. (peter) Benutzerseite


Lesenswert?


von Benjamin (Gast)


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ß

von Karl heinz B. (kbucheg)


Lesenswert?


von Peter D. (peda)


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

von johnny.m (Gast)


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

von Benjamin (Gast)


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

von Benjamin (Gast)


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

von Benjamin (Gast)


Lesenswert?

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

von Benjamin (Gast)


Angehängte Dateien:

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

von Karl heinz B. (kbucheg)


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.

von Karl heinz B. (kbucheg)


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?

von Benjamin (Gast)


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

von Benjamin (Gast)


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!?

von Thomas Knecht (Gast)


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

von Thomas Knecht (Gast)


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++);
}

von Benjamin (Gast)


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

von Karl heinz B. (kbucheg)


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).

von Benjamin (Gast)


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

von Karl heinz B. (kbucheg)


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).

von johnny.m (Gast)


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?

von Thomas Knecht (Gast)


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

von Benjamin (Gast)


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

von Thomas Knecht (Gast)


Lesenswert?

Hab was vergessen....

Die 2. Tabelle is ohne volatile

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Thomas Knecht (Gast)


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

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.