PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : verursachen 2 Interrupts probleme?



raptor_79
10.10.2006, 23:42
hallo.

ich hab eine anwendung, in der ich bei einem ATmega32 int0 und int1 verwende.
wenn int0 ausgelöst wird, bleibt er in der schleife hängen, und macht bis zum auslösen von int1 nichts.
wenn ich int1 auslöse, spricht die anwendung an (nur ein mal sehr kurz) und dann nicht mehr, obwohl der interrupt noch gegeben wäre.

sind int1 und int0 unterschiedliche interrupts? und stören sich die gegenseitig?
kann das sein?
hab jetzt schon absolut alles ausprobiert, und es wird einfach nicht besser. immer der selbe effekt.
einzeln getestet geht das ganze. ich kann sie auslösen, dann druchläuft das ganze die ISR, und geht zurück ins programm.
zusammen wird auf gut deutsch nur scheiß draus.
an was kanns liegen, jemand eine idee??

danke schon mal im vorraus.

x-ryder
11.10.2006, 10:31
interrupts machen folgendes:

wenn ein INT0 z.b. angesprochen wird also von außen her als pin, dann wird im controller auf eine bestimmte adresse verwiesen, ich glaub 0004 iss das bei int0, in dieser adresszeile im codespeicher steht dann ein goto line sowieso (der sprung in die ISR) und da springter dann hin, und führt die entsprechenden befehle nacheinander aus, danach geht er zurück ins hauptprogramm, oder dahin, wo er unterbrochen wurde.

beim int1 isses genauso, nur dass der z.b. 0008 belegt (die adressen dazwischen werden von anderen interrupts belegt) und dann eben das ausführt was im goto dieser zeile steht und zurückspringt.

wenn du also nen interrupt hast und er springt in die ISR, dann springter danach wieder raus, auch wenn der interrupt noch anliegt, das müsstest du dann in einer schleife überprüfen, ob der noch anliegt oder nicht.

wenn du dafür ne endlosschleife in die ISR legst, dann bleibter dadrin auf jeden fall hängen, weiler dann niemals ins hauptprogramm zurückkehrt

ich hoff das hat geholfen ^^

Martin

SprinterSB
11.10.2006, 11:18
Diesei Interrupts arbeiten unabhängig voneinander.

Das Problem liegt ziemlich wahrscheinlich in deiner Software. Daß die Routinen einzeln funktionieren heisst ja nicht, daß sie korrekt sind!

-- Dürfen die IRQs kaskadieren (rekursive IRQs)? Das kann Probleme machen
-- Sind die IRQs flankengetriggert? Pulsgetriggert ist hier nicht angesagt!!!
-- Sind die ISRs frei von Warteschleifen, etc?
-- Sind Zugriffe auf Objekte, die in den ISRs verändert werden, atomar? Falls nicht, bekommst du sporadisch unsinnige Daten.
-- STellst du alle GPRs und das SREG wieder her (falls du Asm proggst)?

raptor_79
11.10.2006, 12:00
also, in der ISR wird nur einmal eine anweisung durchlaufen. und ich hab die irq´s "falling", weil da eben am pin high ist, und wenn der irq kommt, fällt es ab auf low. denk, das sollte passen.

was anderes, wie geht das mit dem kaskadieren?
im übrigen verwende ich Bascom-AVR zum proggen.

Vitis
11.10.2006, 13:34
Das ist ganz schlechter Code in ner ISR hängen bleiben.
Man durchläuft eine ISR, setzt ein Flag und geht raus bis zum nächsten
Event. Der AVR kennt keine Prioritäten bei Int.

AVR denkt: "Int ist ausgelöst, OK, dann mach ich jetzt das und nur dieses,
der Restliche Code interessiert mich nicht mehr, bis ich mit dem hier fertig
binn. Danach schau ich mal was sonst noch so anliegt, aber jetzt nur das hier"

raptor_79
11.10.2006, 13:43
würds was bringen, wenn ich den interrupt disable?


was heißt, bleibt hängen. er springt nicht zurück.
er macht schon da, was er soll, nur hört er nicht mehr damit auf.
er bleibt einfach stehen. sozusagen eingefrohren.
und der andere, macht was er soll, und geht sofort raus. auch wenn die interruptbedingug immer noch erfüllt wird.

Felix G
11.10.2006, 14:36
Vielleicht solltest du einfach mal die fehlerhafte ISR hier posten, dann braucht man auch keine Kristallkugel um den Fehler zu finden ;)

raptor_79
11.10.2006, 15:00
da is nix falsch.
ich setzt da einfach einzelne pins auf 1 oder 0.
dann ist schon return angesagt.
aber werd ich machen, wenn ich zuhause bin.
gibts da eine bestimmte größe, die die ISR haben darf?

hatte auch schon goto und gosub drin. immer das geleiche ergebnis.

liegt es evtl. an soft/hw-stacks?
hab die schon vergrößtert und verkleinert.

Felix G
11.10.2006, 15:28
Also Sprünge in andere Programmteile sind in einer ISR absolut tabu, denn man weiss ja nicht ob der Compiler schlau genug ist sowas korrekt zu erkennen. (Ich bezweifle es mal, und vermute daß der Programmteil in den man per goto springt noch zur ISR gezählt wird)

Funktionsaufrufe sind noch akzeptabel, aber man sollte sich da wirklich auf ganz kurze einfache Funktionen beschränken. (denn jede innerhalb einer ISR aufgerufene Funktion wird nunmal vollständig innerhalb der ISR ausgeführt und führt zu entsprechenden Verzögerungen)

einen konkreten Wert für die maximal zulässige ISR-Länge gibt es nicht. Wenn man nur einen Interrupt verwendet muss sie jedenfalls kurz genug sein daß sie auf jeden Fall fertig ist bevor der Interrupt erneut ausgelöst werden kann. Bei mehreren Interrupts gilt einfach nur: so kurz wie möglich.

raptor_79
11.10.2006, 16:23
was ist kurz? ich mein, wieviele zeilen?

ich hätte da 6-8 zeilen, in denen er einzelne pins auf 0/1 setzen soll.
meinst du, das ist ok?

SprinterSB
11.10.2006, 16:38
Das sollte echt kein Thema sein (vorausgesetzt es werden wirklich nur Pins gesetzt und der Compiler setzt das gut um).

Kann es evtl. sein, daß du in INT0 den INT1-Pin wechselst und umgekehrt? Dann hängen sich die IRQs natürlich auf...

Die "Länge" einer ISR kannst du eigentlich nicht in Codezeilen messen. Was da entscheidend ist, ist die Anzahl der erzeugten Instruktionen. Und da gilt: So kurz wir nötig. Bei deinem Code sollte es aber wie gesagt absolut unkritisch sein.

Und wenn nix falsch ist an deine Code, was willst du dann wissen???

raptor_79
11.10.2006, 17:01
weil es eben nicht geht.
dachte, daß es da z.b. noch spezielle einstellungen gibt, oder saß man nur den int0 oder den int1 oder int2 verwenden darf/kann.

oder was weiß ich, drum frag ich ja.
ist mir halt ein rätsel, warum der eine nicht zurückspringt, und der andere sofort, auch wenn die int. bedingung noch erfüllt ist.

Felix G
11.10.2006, 17:10
Also das setzen einiger Pins ist im Normalfall kein Problem, ein guter Compiler verpackt das in ganz wenigen Assemblerbefehlen.


In ganz kritischen Fällen beschränke ich meine ISRs wirklich nur auf gaaanz wenige Befehle, nämlich:
- setzen eines Flags in irgendeiner Variable, um dann im Hauptprogramm ganz in Ruhe auf den Interrupt reagieren zu können

und falls nötig:
- speichern eines Wertes in einer Variable (z.B. Zählerstand, ADC-Wert etc.)
- setzen von interruptspezifischen Registern (bei Overflow-Interrupts z.B. das entsprechende TCNT Register)

Im Normalfall kann eine ISR aber auch deutlich länger ausfallen ohne daß Probleme entstehen.


was ich in einer ISR grundsätzlich niemals verwende sind Schleifen und Bibliotheksfunktionen (denn man weiss ja bei Funktionen die man nicht selbst geschrieben hat meist nicht wie lang sie wirklich sind). Und Sprünge aus einer ISR heraus an eine andere Stelle im Code sind sowieso verboten. (das kann nämlich dazu führen daß eine ISR zwar immer wieder neu aufgerufen wird aber niemals beendet, was dir deinen Stack überlaufen lässt)

raptor_79
11.10.2006, 19:52
das ist die ISR


Int0_isr:
Pwm1a = 0
Portd.6 = 0
Portc.3 = 0
Pwm1b = 0
Portc.2 = 0
Portc.4 = 0
Pwm1a = 180
Portd.6 = 0
Portc.3 = 1
Pwm1b = 0
Portc.2 = 0
Portc.4 = 0
Return

raptor_79
13.10.2006, 14:15
GELÖST:
waren falsch angesteckte leitungen an einem motor, warum er sich komisch verhalten ha.

danke trotzdem.