mikrocontroller.net

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


Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: ... ... (docean) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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..

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
.org 0x0
 rjmp init
.org INT0addr
 rjmp int0_isr

.org INT_VECTORS_SIZE
init:

.
.
.
.

loop:
rjmp loop

int0_isr:
 pop r0
 pop r0
 sei
 rjmp stelle
So z.B. benuzt mal die Namen der Vektoren aus der Definitionsdatei ist 
übersichtlicher ;)

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.