Forum: Mikrocontroller und Digitale Elektronik Interrupt startet zweimal


von Fabian S. (fabian727)


Angehängte Dateien:

Lesenswert?

moin,

ich habe angehängte Schleife programmiert. Funktioniert auch fast alles 
wie es soll. Mein Problem ist nur, wenn ich den externen Interrupt 
"aufrufe" läuft er ihn auch sauber durch, springt danach in die 
Hauptschleife: loop und geht danach unverzüglich weiter in die Schleife 
des externen Interrupts und läuft sie somit ein zweites mal durch. 
Danach springt er wieder in die loop (also Hauptprogramm) und arbeitet 
ganz normal weiter.

Woran liegt es, dass er diese Interruptschleife doppelt abarbeitet?
Die anderen beiden Interrupts läuft er, wie er soll, nur einmal durch.

Habe gerade festgestellt, dass er zumindest doppelt abarbeitet, wenn ich 
den PIN für den externen Interrupt länger als 1 Takt halte. Halte ich 
ihn nur 1 Takt lang auf "1", geht er den Interrupt auch nur einmal durch

von Fabian S. (fabian727)


Lesenswert?

ich arbeite mit dem attiny2313 und verwende dort die PinChangeInterrupt.
Jede Änderung am PIN löst einen Interrupt aus. D.h. bei low->high und 
bei high->low.

Kann man das einstellen, dass er nur mit einer Flanke den Interrupt 
auslöst?

von gunti (Gast)


Lesenswert?

Fabian S. schrieb:
> Kann man das einstellen, dass er nur mit einer Flanke den Interrupt
> auslöst?

Nein, beim PCINT nicht.

von Spess53 (Gast)


Lesenswert?

Hi

>Kann man das einstellen, dass er nur mit einer Flanke den Interrupt
>auslöst?

Nei. Aber man kann in der ISR den Pegel des Pins abfragen und damit 
herausbekommem welche Flanke ausgelöst hat.

Die initialisierung des Stacks sollte übrigens das erste sein, was das 
Programm macht.

MfG Spess

von Fabian S. (fabian727)


Lesenswert?

hat jeder IC dieses Register? Ich find kein wort davon im datasheet des 
Attiny2313.

von Fabian S. (fabian727)


Lesenswert?

inzwischen habe ich eine andere lösung dafür, kostet mich allerdings ein 
register.

Ich speicher ab, ob ich schon 1mal davor da war, wenn ja springt er 
wieder zurück in die Hauptschleife, wenn nicht, setzt ers auf 1mal da 
gewesen und geht die interruptschleife durch.
Da ich ja weiß, dass ich 2mal in die Schleife gehe, wenn ich 1 Interrupt 
hatte, funktioniert das ganze auch.

Trotzdem ist irgendwo noch ein anderer Fehler, den ich gerade nicht 
finde.

Das Programm soll die Zeit messen, die ich zwischen 2mal Taste drücken 
brauche, durch 12 teilen und dannimmer dieses zwölftel warten und meine 
Lichterkette um 1 weiterschieben. Wenn keine Taste gedrückt wird und 
beide clo register hochgezählt sind, solls in den "idle-mode" gehen -> 
jede zweite LED an.

Für den Idle-mode dauert es entweder zu lange, oder er wird nicht 
aufgerufen. sobald ich einmal die Taste gedrückt habe, lässt er immer 
die LEDS durchlaufen. Is auch super, wie er soll. Nur leider kann ich 
die Zeit nicht variieren. Wo ist da der Fehler?

von (prx) A. K. (prx)


Lesenswert?

Fabian S. schrieb:
> hat jeder IC dieses Register?

Welche?

von (prx) A. K. (prx)


Lesenswert?

Spess53 schrieb:
> Die initialisierung des Stacks sollte übrigens das erste sein, was das
> Programm macht.

Noch vor der expliziten Initialisierung des Stackpointers könnte 
freilich ein Blick ins Datasheet stehen. Um festzustellen, ob das 
überhaupt notwendig ist. Bei den meisten AVR-Typen macht der Controller 
das nämlich bereits selbst, so auch hier.

von Fabian S. (fabian727)


Lesenswert?

ich meinte das ISR Register. Ich finde davon nix im Datasheet.


Ich brauch beim attiny2313 dieses
.org 0x000
     rjmp main
...
gar nicht?
praktisch

Den Fehler, warum er die dividierte Zeit nicht annimmt und dadurch den 
Compare-Match zeitlich verändert, findet aber keiner?
Ich weiß im moment einfach nicht weiter.
thanks,

Fabi

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

Hallo.. ein paar Gedanken dazu:

Taste entprellt (per Kondensator oder per Software)?

Den Rat von Spess53 befolgt (Zustand des Pins in der ISR abfragen)?
Z.B.:
1
sbis PINx,PPORTxb
2
reti
zu Beginn der Interrupt-Routine.

Warum nimmst du den PCI? INT0 oder INT1 wären hier besser geeignet, weil 
man diese gezielt auf Flanken parametrieren kann.

Den Code habe ich nicht angeschaut, sondern nur ganz grob überflogen. Du 
verwendest r24 (heißt bei dir "idle") sowohl in den ISR als 
Zwischenspeicher für SREG als auch im Hauptprogramm als temporäre 
Ablage. Das kann nicht gut gehen...

von Markus W. (Firma: guloshop.de) (m-w)


Lesenswert?

P.S.:

Warum teilst du eigentlich durch 12? Das kostet viel Rechenzeit und ist 
grad in einer ISR nicht immer ideal. Teilen durch 8 oder 16 geht viel 
schneller, und wenn es etwas dazwischen sein muss, dann vielleicht 
besser 3/32. Das lässt sich durch Verschieben und Addieren ganz ohne 
Schleife erledigen.

Jetzt hab ich aber genug kritisiert. :-) Das meiste sind ja 
Kleinigkeiten, jetzt ist erstmal wichtig, dass das Programm läuft!

von Fabian S. (fabian727)


Lesenswert?

moin,

danke für die Antworten. Ich teile durch 12. Da ich 12 LEDS habe, die 
ich nacheinander ansteuern möchte. 8 sind leider zu wenig (zu dunkel) 
und 16, ja so viele Ausgänge habe ich leider nicht um alle anzusteuern. 
Somit kam dabei die Mitte davon raus 12.
Aber apropos Mitte: neue Idee, zwei Divisionen, einmal durch 8, einmal 
durch 16, daraus die differenz und davon die Hälfte einfach auf das 
Ergebnis der 8 addieren. Müsste schneller als meine Schleife sein.

von Fabian S. (fabian727)


Lesenswert?

okay, ich habe das Problem gefunden. Sobald er in das MatchA Register 
etwas reinschreibt, gibt er kein Overflow Interrupt mehr aus.

von Fabian S. (fabian727)


Lesenswert?

auch dieses Problem gelöst. Neues dafür größeres Problem, meine abwarte 
Zeit ist verkehrt.

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.