www.mikrocontroller.net

Forum: Compiler & IDEs Kurze Frage zum Interrupt


Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen :)
ich hab ne kurze Fage was Interrupts betrifft. Ich hab mal im Tutorial 
gelesen, das während der Controller auf einen vollen Empfangspuffer 
wartet der komplette Programmablauf blockiert ist. Gilt das auch für 
Interrupts?

Das Problem hab ich nämlich momentan. Der Controller wartet auf Zeichen 
von der Seriellen (was mir durch eine LED angezeigt wird, um sicher 
zugehen das ich wirklich in meiner "Empfangspuffer-Warten-Schleife" bin) 
dann löse ich einen Interrupt aus und es tut sich nix. Wenn er nicht auf 
Zeichen wartet dann funktioniert der Interrupt.

Controller ist AT Mega 32. AVR Studio mit Win AVR. Programmierspare C.

Kann mir jemand helfen?

Autor: Sauger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Klaus Dietz schrieb:
> Gilt das auch für Interrupts?

nein, wenn er (der Interrupt) freigegeben ist schlägt er zu.

Ohne deine Quelltexte ist eine Hilfe nur schwer möglich.

MfG

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sauger schrieb:
> nein, wenn er (der Interrupt) freigegeben ist schlägt er zu.

theoretisch könnte aber die

> "Empfangspuffer-Warten-Schleife"

ja auch in einem Interrupt sein...

Autor: Sauger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Justus Skorps schrieb:
> ja auch in einem Interrupt sein...

deswegen

> Ohne deine Quelltexte ist eine Hilfe nur schwer möglich.

MfG

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich versuch nen code auf die Beine zu stellen. Denn der Echte Quellcode 
ist etwas zu lang fürs Forum.

Autor: Sauger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

gepackte Archive wurden schon vor längerer Zeit erfunden!

MfG

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
meine Frage war ja nur ob die Interrupts dann deaktiviert sind wenn er 
auf Zeichen wartet. Ich versuch das Problem erst mal alleine zu lösen. 
Ihr sollt schließlich nicht meine Arbeit vollrichten.

MFG

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> meine Frage war ja nur ob die Interrupts dann deaktiviert sind wenn er
> auf Zeichen wartet.

dann musst du uns aber erstmal sagen was du darunter verstehst, wie 
wartest du denn auf die Daten? Ist das eventuell innerhalb eines 
Interupts?

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich Frage das Bit ab das gesetzt wird wenn der Puffer voll ist. Sprich 
alle zeichen Empfangen hat. Zusätzlich will ich aber das mein Interrupt 
zuschlagen kann. Was er im moment nicht macht.

Autor: Floh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ISR vorhanden ?
Interrut eingestellt ?
sei ?

Autor: Sauger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Klaus Dietz schrieb:
> meine Frage war ja nur ob die Interrupts dann deaktiviert sind wenn er
> auf Zeichen wartet. Ich versuch das Problem erst mal alleine zu lösen.
> Ihr sollt schließlich nicht meine Arbeit vollrichten.

lobenswert,

Sauger schrieb:
> nein, wenn er (der Interrupt) freigegeben ist schlägt er zu.

also drauf achten der Interrupt nicht gesperrt ist (wird)

MfG

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ist alles eingestellt. Im Hauptprogramm ist sei(); drin, und ein 
Unterprogramm wird aufgerufen das dann die entsprechenden Bits 
einstellt.

ISR steht auserhalb vom hauptprogramm. Das funktioniert alles wunderbar. 
Problem ist nur wenn er auf dieses Bit wartet (Puffer voll) dann 
intressiert ihn der Interrupt nicht.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> ich Frage das Bit ab das gesetzt wird wenn der Puffer voll ist. Sprich
> alle zeichen Empfangen hat. Zusätzlich will ich aber das mein Interrupt
> zuschlagen kann.

es sollte zwar gehen, aber der sinn ist mir nicht ganz klar. Denn warum 
willst du an der stelle überhaupt auf das Zeichen warten, wenn du es eh 
im Interupt auswertest?

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil ich eine Aktion machen will, die von der Seriellen aus gesteuert 
werden kann und wenn ich über die serielle nichts machen will dann 
drücke ich einfach eine andere Taste.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ob Dein Interrupt zubeißt oder nicht, ist nicht davon abhängig, wo im 
Programm sich die CPU gerade rumtreibt.  Ausschlaggebend dafür ist 
ausschließlich das I-Flag im Statusregister.

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wird das I-Flag nicht über den Befehl sei(); gesetzt?

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wird das I-Flag nicht über den Befehl sei() gesetzt?

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh sry da bin ich wohl einmal zu oft auf den button gekommen :)

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> weil ich eine Aktion machen will, die von der Seriellen aus gesteuert
> werden kann und wenn ich über die serielle nichts machen will dann
> drücke ich einfach eine andere Taste.

versteht ich nicht? Du kannst doch auch die Aktion im Interupt machen.

Autor: Sauger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Vermutung:

du liest UDR in einer Schleife aus. Warum sollte noch ein Interrupt 
ausgelöst werden wenn das Register gelesen ist?

MfG

Autor: Wayne (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es sei denn, die Bitabfrage ist so geschrieben, dass die 
Interruptsgespert sind.
cli(); // ATOMIC_BLOCK(ATOMIC_FORCEON) wäre auch eine Möglichkeit...
while(1)
{
  if(Bitabfrage())
  {
    do();
  }
} 
sei();

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sauger schrieb:
> du liest UDR in einer Schleife aus. Warum sollte noch ein Interrupt
> ausgelöst werden wenn das Register gelesen ist?

ich denke aber das das Interupts flag gesetzt bleibt, auch wenn die 
daten schon gelesen sind. Problematisch wird es dann wenn im Interupt 
noch einmal gefragt wird ob zeichen zum lesen vorhanden sind, dann 
blockert in der ISR.

Autor: Sauger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Mit dem lesen des Registers hat sich die Sache erledigt.

MfGS

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> wird das I-Flag nicht über den Befehl sei() gesetzt?

Ja.  Ab dann sind Interrupts erlaubt.  Und das bleiben sie, solange kein 
cli() kommt und solange nichts sonst am Statusregister manipuliert (beim 
Interrupt wird das Flag übrigens gelöscht, aber beim Beenden des 
Interrupts wieder auf den alten Wert gesetzt).

Wenn diese Bedingungen erfüllt sind und wenn Dein Programm also auf ein 
Flag vom Interrupt ewig wartet, aber keines kommt, würde ich davon 
ausgehen, dass es vom Interrupt nicht gesetzt wird (und nicht, dass kein 
Interrupt ausgeführt wird).

Autor: Klaus Dietz (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich hab den Prägnanten teil des Programms mal zusammengefasst.

so sieht das dann ungefähr aus.

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

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> ich hab den Prägnanten teil des Programms mal zusammengefasst.
>
> so sieht das dann ungefähr aus.

Du hast deine Lektion von gestern immer noch nicht gelernt.
Poste ein komplettes, getestetes Program.

Das Programm muss sich hier bei uns kompilieren lassen und wenn du uns 
sagst, das und das muss auf den Eingängen gemacht werden, damit man das 
Problem sieht (vorher bei dir ausprobieren ob das zurechtgestutzte 
Programm bei dir auch wirklich dieses Verhalten zeigt), dann kann man 
auf dieser Seite des Montiors auf Fehlersuche gehen.

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lektion von gestern?
ich glaub du verwechselst mich mit jemandem...

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

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> Lektion von gestern?
> ich glaub du verwechselst mich mit jemandem...

Mag sein. In dem Fall entschuldige ich mich.
Mir ist nur der Anfang von main sehr bekannt vorgekommen, und da ging es 
auch um einen INT0

Die Variable 'Interrupt' (übrigens ein selten dämlicher Name für eine 
Variable), ... ist die volatile?

(Und im Grunde gilt es trotzdem: mach ein komplettes Beispiel fertig)

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> ich hab den Prägnanten teil des Programms mal zusammengefasst.

leider ist das testprogramm nichts wert!!!
ISR(INT1_vect)              // Wenn Interrupt eintritt dann Starte Prüfung
  {
   Interrupt = 1;           // 
   Start = 1;
  }

wir wissen nicht wie "Interrupt" definiert ist. (Stichwort: volatil)
int main (void)
{ 
  sei();                   // Interrupts einschalten
  interrupt();             // Interrupt Unterprogramm aufrufen
  init(); 
  initusart();

  if (bit_is_set (PINA,PINA0))
   {Serielle Daten();}

wo ist die entlosschleife? das if (bit_is_set (PINA,PINA0)) wird also 
nur beim programmstart einmal ausgewertet.
#ifdef UCSRA
woher sollen wir wissen ob das true oder false ist?

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich werde ein fertiges Programm schreiben. Drüfte aber ein wenig dauern

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

Bewertung
0 lesenswert
nicht lesenswert
Sag vorher noch ganz schnell ob 'Interrupt' volatile ist oder nicht. 
Wenn nicht, dann hast du dein Problem identifiziert.

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was meinst du mit volatile?

das unterprogramm heisst

void interrupt (void)
.
.
.Bit einstellungen für interrupt.
.

und die variable interrupt ist mit uint8_t definiert.

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> und die variable interrupt ist mit uint8_t definiert.

und hast du dir mal angeschaut, was für ein Assembler-Code aus deinem 
C-Code ensteht?

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein wie soll den das gehen?

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> was meinst du mit volatile?

und die variable interrupt ist mit uint8_t definiert.

dann lies mal hier 
http://www.mikrocontroller.net/articles/Interrupt#...

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> nein wie soll den das gehen?

indem man die lss-Datei öffnet...

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

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Klaus Dietz schrieb:
>> was meinst du mit volatile?
>>
>> und die variable interrupt ist mit uint8_t definiert.
>
> dann lies mal hier
> 
http://www.mikrocontroller.net/articles/Interrupt#...

Oder hier
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

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

Bewertung
0 lesenswert
nicht lesenswert
Justus Skorps schrieb:
> Klaus Dietz schrieb:
>> und die variable interrupt ist mit uint8_t definiert.
>
> und hast du dir mal angeschaut, was für ein Assembler-Code aus deinem
> C-Code ensteht?

Im Prinzip keine schlechte Idee, aber wenn die Variable nicht volatile 
ist, brauchen wir erst mal gar nicht weiter suchen :-)

(Zumal ja auch gar nicht gesagt ist, dass er mit dem Assembler-Output 
was anfangen kann)

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so jetzt gehts... die variable auf volatile umbenannt und schon 
funktionierts.

Danke :)

Autor: Justus Skorps (jussa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Im Prinzip keine schlechte Idee, aber wenn die Variable nicht volatile
> ist, brauchen wir erst mal gar nicht weiter suchen :-)

jo, das hätte man vorher mal machen sollen

> (Zumal ja auch gar nicht gesagt ist, dass er mit dem Assembler-Output
> was anfangen kann)

na ja, aber wenn da ein kompletter Abschnitt fehlt, dann sollte das 
einem schon irgendwie auffallen denke ich mir

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> variable auf volatile umbenannt

sicher, sie jetzt heist sie also nicht mehr interrupt sondern volatile 
und der compieler versteht das?

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sie heisst volatile uint8_t I_Flagt;

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sie heisst volatile uint8_t I_Flag;

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

Bewertung
0 lesenswert
nicht lesenswert
Nein.

Sie heißt "I_Flag"
Und sie ist vom Datentyp "volatile uint8_t"

(und I_Flag ist immer noch ein selten dämlicher Name. Er sagt so rein 
gar nichts darüber aus, welche Aufgabe diese Variable hat, was es 
anzeigt, wenn sie 0 oder 1 ist.

Benenne Variablen weder nach ihrem Datentyp noch wer sie setzt. Benenne 
sie nach ihrer Funktion. Die Variable zeigt an, dass eine Taste gedrückt 
wurde (das rate ich jetz, weil ich nicht weiß woher der INterrupt 
bedient wird). Also könnte sie einen Namen bekommen, der das ausdrückt. 
Wenn dieser Interrupt ausschliesslich dafür zuständig ist, dass dein 
Benutzer sich beim System bemerkbar macht um mmitzuteile "Was immer du 
momentan tust, hör auf damit", dann könnte man auch das als Name nehmen, 
irgendwas mit den Worten Cancel und Operation. Mglw. auch noch ein 
Request da mit drinnen

dann liest sich die Schleife plötzlich

  while( irgendwas    &&
         ! OperationCanceled )


oder
  while( irgendwas    &&
         ! CancelRequested )

oder
  while( irgendwas    &&
         ! KeyPressed )

und das ist dann schon fast Klartext.

Lass dich bei deiner Namenswahl von der Verwendung der Variablen leiten! 
Sieh dir an, wie und wo sie abgefragt wird und dann denk über einen 
Namen nach, der in diesem Abfragezusammenhang maximalen Sinn ergibt.

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hab sie  I_Flag genannt wegen Interrupt. leitet sich so her wenn ein 
Interrupt eintrifft wird das I_Flag (Interrupt Flag) gesetzt. In der 
Originalsoftware heisst sie Start.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lies mal was zum Thema Interrupt. Das erspart die 1001 philosopische 
Diskussion über das ewig gleiche Thema.

MfG
Falk

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> ich hab sie  I_Flag genannt wegen Interrupt.

es gibt aber sehr viele Interupts bei dem Atmel, nennst du sie dann 
I_Flag1, I_Flag2 ...

Autor: Klaus Dietz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum den nicht? Aber wenns mehr werden dann bevorzuge ich schon das was 
Karl Heinz gesagt hat. Spricht ja auch irgendwie dafür das man einen 
Code selbsterklärend schreibt.

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

Bewertung
0 lesenswert
nicht lesenswert
Klaus Dietz schrieb:
> warum den nicht? Aber wenns mehr werden dann bevorzuge ich schon das was
> Karl Heinz gesagt hat. Spricht ja auch irgendwie dafür das man einen
> Code selbsterklärend schreibt.


Nicht: 'spricht ja irgendwie dafür'

Es spricht alles dafür!

Unter anderem auch die Erfahrung, dass diejenigen mit den 
fehleranfälligsten und unwartbarsten Programmen auch meistens die sind, 
die sich einen feuchten Kehrricht um formale Dinge, wie Codeformatierung 
oder Funktions- und Variablennamen, Konsistenz etc. kümmern.

Seltsamerweise haben die Programmierer, die auf solche Dinge achten, 
meistens auf lange Sicht deutlich weniger Probleme :-)

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.