Forum: Compiler & IDEs Kurze Frage zum Interrupt


von Klaus Dietz (Gast)


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?

von Sauger (Gast)


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

von Justus S. (jussa)


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

von Sauger (Gast)


Lesenswert?

Moin,

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

deswegen

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

MfG

von Klaus Dietz (Gast)


Lesenswert?

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

von Sauger (Gast)


Lesenswert?

Moin,

gepackte Archive wurden schon vor längerer Zeit erfunden!

MfG

von Klaus Dietz (Gast)


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

von Peter (Gast)


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?

von Klaus Dietz (Gast)


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.

von Floh (Gast)


Lesenswert?

ISR vorhanden ?
Interrut eingestellt ?
sei ?

von Sauger (Gast)


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

von Klaus Dietz (Gast)


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.

von Peter (Gast)


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?

von Klaus Dietz (Gast)


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.

von Hc Z. (mizch)


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.

von Klaus Dietz (Gast)


Lesenswert?

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

von Klaus Dietz (Gast)


Lesenswert?

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

von Klaus Dietz (Gast)


Lesenswert?

oh sry da bin ich wohl einmal zu oft auf den button gekommen :)

von Peter (Gast)


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.

von Sauger (Gast)


Lesenswert?

Moin,

Vermutung:

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

MfG

von Wayne (Gast)


Lesenswert?

Es sei denn, die Bitabfrage ist so geschrieben, dass die 
Interruptsgespert sind.
1
cli(); // ATOMIC_BLOCK(ATOMIC_FORCEON) wäre auch eine Möglichkeit...
2
while(1)
3
{
4
  if(Bitabfrage())
5
  {
6
    do();
7
  }
8
} 
9
sei();

von Peter (Gast)


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.

von Sauger (Gast)


Lesenswert?

Moin,

Mit dem lesen des Registers hat sich die Sache erledigt.

MfGS

von Hc Z. (mizch)


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

von Klaus Dietz (Gast)


Angehängte Dateien:

Lesenswert?

ich hab den Prägnanten teil des Programms mal zusammengefasst.

so sieht das dann ungefähr aus.

von Karl H. (kbuchegg)


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.

von Klaus Dietz (Gast)


Lesenswert?

Lektion von gestern?
ich glaub du verwechselst mich mit jemandem...

von Karl H. (kbuchegg)


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)

von Peter (Gast)


Lesenswert?

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

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

wir wissen nicht wie "Interrupt" definiert ist. (Stichwort: volatil)
1
int main (void)
2
{ 
3
  sei();                   // Interrupts einschalten
4
  interrupt();             // Interrupt Unterprogramm aufrufen
5
  init(); 
6
  initusart();
7
8
  if (bit_is_set (PINA,PINA0))
9
   {Serielle Daten();}
wo ist die entlosschleife? das if (bit_is_set (PINA,PINA0)) wird also 
nur beim programmstart einmal ausgewertet.
1
#ifdef UCSRA
woher sollen wir wissen ob das true oder false ist?

von Klaus Dietz (Gast)


Lesenswert?

ich werde ein fertiges Programm schreiben. Drüfte aber ein wenig dauern

von Karl H. (kbuchegg)


Lesenswert?

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

von Klaus Dietz (Gast)


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.

von Justus S. (jussa)


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?

von Klaus Dietz (Gast)


Lesenswert?

nein wie soll den das gehen?

von Peter (Gast)


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#Steuersignale_zwischen_ISR_und_Hauptprogramm

von Justus S. (jussa)


Lesenswert?

Klaus Dietz schrieb:
> nein wie soll den das gehen?

indem man die lss-Datei öffnet...

von Karl H. (kbuchegg)


Lesenswert?


von Karl H. (kbuchegg)


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)

von Klaus Dietz (Gast)


Lesenswert?

so jetzt gehts... die variable auf volatile umbenannt und schon 
funktionierts.

Danke :)

von Justus S. (jussa)


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

von Peter (Gast)


Lesenswert?

Klaus Dietz schrieb:
> variable auf volatile umbenannt

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

von Klaus Dietz (Gast)


Lesenswert?

sie heisst volatile uint8_t I_Flagt;

von Klaus Dietz (Gast)


Lesenswert?

sie heisst volatile uint8_t I_Flag;

von Karl H. (kbuchegg)


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.

von Klaus Dietz (Gast)


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.

von Falk B. (falk)


Lesenswert?

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

MfG
Falk

von Peter (Gast)


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

von Klaus Dietz (Gast)


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.

von Karl H. (kbuchegg)


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

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.