Forum: Mikrocontroller und Digitale Elektronik Interrupt INT0 als Programm-Verzweigung


von Patrick (Gast)


Lesenswert?

Hallo zusammen,

ich möchte mit dem Interrupt-Eingang INT0 am ATtiny12 erreichen, dass 
das Programm an eine bestimmte Marke springt und dort normal weiter 
macht, und zwar sowohl aus dem normalen Betrieb als auch aus dem 
Power-down-Modus heruas. Ich kenne nur den Fall, dass man mit reti 
wieder normal zurückkehrt, was ich in meinem Fall nicht brauche. Ich 
würde einfach INT0 konfigurieren und aktivieren und in die 
Interrupt-Vektortabelle den gewünschten Ort eintragen und an diesem Ort 
dann wieder das Global Interrupt Flag setzen.

Meine Frage nun hierzu: Geht das so einfach oder muss ich noch was mit 
dem Program counter / Stack Pointer machen? Geht das auch ganz normal 
aus dem Sleep-Modus raus?

Vielleicht noch wichtig: Ich möchte als Taktquelle einen externen 
32,768kHz - Quarz verwenden.


Viele Grüße und schönen Rest-Sonntag,
Patrick

von ... .. (docean) Benutzerseite


Lesenswert?

Dann setz in deiner INT0 Funktion ein Flag (oder mehrere), z.B eine 
Variable auf 1.

Diese Flags kannst du dann im Hauptprogramm prüfen und passende 
Funktionen ausführen...

So wird die INT0 Routine schön kurz, und der nächste kapiert noch was du 
da programmiert hast..

von spess53 (Gast)


Lesenswert?

Hi

>Dann setz in deiner INT0 Funktion ein Flag (oder mehrere), z.B eine
>Variable auf 1.

Oder in der ISR Z mit der Adresse bestücken und im Hauptprogramm einen 
'ijmp'.

MfG Spess

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Wenn du ASm benuzt mußt du vor der Freigabe der Interrupts einfach die 
Rücksprung addresse vom Stack löschen (mittels 2xpop) und mit sei die 
Interupts wieder freigeben.

von Patrick (Gast)


Lesenswert?

Hallo ihr drei,

danke für die Ideen. Ich glaube ich tendiere der Einfachheit halber zu 
Nr. 3. (Außer mir muss es vermutlich erstmal keiner entziffern können 
;-) )

Kleine Frage am Rande: Was ist ASm?

Grüße
Patrick

von spess53 (Gast)


Lesenswert?

Hi

>Wenn du ASm benuzt mußt du vor der Freigabe der Interrupts einfach die
>Rücksprung addresse vom Stack löschen (mittels 2xpop) und mit sei die
>Interupts wieder freigeben.

?????????????????
Im Hauptprogramm sinnlos, da keine Rücksprungadresse. In der ISR-> jmp 
Nirvana. Wenn, dann müsste die neue Adresse danach auf den Stack 
'gepusht' werden.

MfG Spess

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

@spess53

Ich schrieb doch ASM (= Assembler)!


Wenn du an der Stelle des Interuptvektors (zb. INT0) ein rjmp machst zu 
einem Program teil deiner Wahl der NICHT mit reti beendet wird, mußt du 
die Rücksprungadresse (welche beim Aufruf des ISR Vektors auf den Stack 
gelegt wurde) entfernen und dann die Interupts wieder freigeben.

Das führt dazu das das Programm nicht an der Stelle an der es 
unterbrochen wurde vortgeführt wird, aber das ist ja auch gewünscht.

Zumindest hab ich es so verstanden das es das ist was der 
Threadersteller bewirken wollte.

von Peter D. (peda)


Lesenswert?

Beim alten ATtiny12 hast Du den Sonderfall des Hardwarestacks. Du kannst 
also gefahrlos aus dem Interrupt irgendwo hinspringen.

Du mußt natürlich berücksichtigen, ob Du irgendwelche Hardware neu 
initialisieren mußt, da deren Zustand bei Unterbrechung zufällig ist.


Peter

von Patrick (Gast)


Lesenswert?

Hallo zusammen,

genau, das Programm soll im Prinzip unendlich lange laufen und ab und zu 
ein wenig schlafen. Rückspringen will ich nicht, sondern an eine 
bestimmte Stelle springen.

Mache ich das jetzt mit der Interrupttabelle
.org 0x001
rjmp stelle

oder einfach mit

int0_isr:
rjmp stelle

Grüße
Patrick

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

1
.org 0x0
2
 rjmp init
3
.org INT0addr
4
 rjmp int0_isr
5
6
.org INT_VECTORS_SIZE
7
init:
8
9
.
10
.
11
.
12
.
13
14
loop:
15
rjmp loop
16
17
int0_isr:
18
 pop r0
19
 pop r0
20
 sei
21
 rjmp stelle
So z.B. benuzt mal die Namen der Vektoren aus der Definitionsdatei ist 
übersichtlicher ;)

von Patrick (Gast)


Lesenswert?

Okay danke, das probiere ich morgen mal, habe heute leider keine Zeit 
mehr.

Hast recht, sollte die Namen aus der Definitionsdatei verwenden, hatte 
aber gerade das Datasheet offen und war zu faul nachzuschauen ;-)

Grüße
Patrick

von Gast (Gast)


Lesenswert?

Ich frag mich nur, ob das funktioniert. Wenn das Programm zufällig in 
einer Unterroutine (oder in einer Unterroutine einer Unterroutine einer 
Unterroutine...) verweilt, wenn der Interrupt ausgelöst wird, wie soll 
dann verfahren werden? Nur oberste Stackadresse löschen? Und die anderen 
durch die Unterroutinen-Calls erzeugten liegenlassen? Und nachdem sich 
das 20 mal wiederholt hat, läuft der Stack über? Oder muss der Stack 
immer ganz gelöscht werden?

Außerdem: Kann einem das wirklich egal sein, ob das Programm im 
Interrupt-Moment gerade aus irgendwelchen Eingaben irgendeine Ausgabe 
berechnet hat, und der Interrupt erst nach dem Sichern des Ergebnisses 
ausgelöst wird, oder aber kurz davor?

von Peter D. (peda)


Lesenswert?

Gast wrote:
> Ich frag mich nur, ob das funktioniert.

Ja doch.
Der Hardwarestack merkt sich nur die letzten 3 Returnadressen, ältere 
fallen gnadenlos heraus. Überlauf ist unmöglich.


Peter

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Naja wenn unteroutinen aufgerufen werden sollte man trozdem den ganzen 
Stack löschen da man die Rücksprungadressen dadrauf ja eh nie nuzt. Oder 
wenn es wirklich so ist das nur die 3 lezten "übrig" bleiben könnte man 
in diesem Fall sogar ganz auf das "popen" der Return Adresse 
verzichten... Aber ich hab jezt auch das Datenblatt nicht offen als im 
Zweifel einfach nochmal selber checken ;)

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.