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?
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
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...
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
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?
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.
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
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.
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?
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.
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.
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.
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.
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).
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.
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)
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.
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?
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)
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
Klaus Dietz schrieb:> variable auf volatile umbenannt
sicher, sie jetzt heist sie also nicht mehr interrupt sondern volatile
und der compieler versteht das?
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.
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.
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 ...
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.
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 :-)