mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt von Hand aufrufen


Autor: mh123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Gibt es einen "schönen" Befehl, um eine Interrupt-SR von Hand 
aufzurufen. Ich nutze avr-libc.

Vielen Dank

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Warum sollte man so einen Unsinn machen?

Autor: antiholger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Testzwecke?
Initialisierung?
Unbeschränkte Ideen?

Autor: mh123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klasse! In der ersten Antwort werde ich gleich mit "Unsinn" beschimpft!

Aber gut. Ich möchte die Funktionalität, die normalerweise von einem 
Interrupt ausgelöst wird, bei Programmstart einmalig von Hand 
aufrufen, damit alles in einem definierten Zustand ist.

Ja, ich könnte alles in eine Funktion packen, die ich dann immer von der 
ISR als auch einmalig von der main() aus aufrufe. Das macht mein 
Programm aber unnötig langsam, denn bei jedem Interrupt habe ich einen 
unnötigen Funktionsaufruf und Rücksprung. Also möchte ich einmalig die 
ISR von Hand aufrufen (von mir aus auch, indem ich das Interrupt-Bit 
setze).

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du das Datenblatt des AVR's Deiner Wahl lesen würdest, wüsstest Du 
daß man die Interrupt Flags nur löschen, aber nicht setzen kann.

Was man machen kann, ist z.B. einen Timer so zu setzen, daß er sofort 
überläuft und damit einen OVF Int auslöst, oder man kann einen ext. Int 
auslösen, indem man den Intpin als Ausgang definiert und entsprechend 
toggelt.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs doch mit nem Call Interruptadresse in
Inline Assembler ;)

Autor: looser (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
um welche architektur handelt es sich denn?
es ist mithilfe von inline-asembler sicher möglich, das schön dreckig 
beim programmstart durchzuführen.

Autor: Svenk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei 8051 Derivaten kannst du die Interrupts durch setzen von bits in 
SFR-Registern erzwingen.

Ich meine das wäre das TCON Register bei 88h gewesen.

Autor: Patrick Markl (patrickmarkl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi mh123,

Du baust eine ISR die nichts anderes macht als eine andere Funktion 
auzurufen, in der der eigentlich Code drin ist. Diese Funktion kannst Du 
dann direkt aus main aufrufen.

Gruß
Patrick

ISR(void)  -> Aufruf aus Vektortabelle
{
  MyIsr();
}

void MyIsr(void)
{
}


void main(void)
{
  MyIsr();
  ...
}

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Patrick

Der Thread-Eröffner schrieb:

>Ja, ich könnte alles in eine Funktion packen, die ich dann immer von der
>ISR als auch einmalig von der main() aus aufrufe. Das macht mein
>Programm aber unnötig langsam, denn bei jedem Interrupt habe ich einen
>unnötigen Funktionsaufruf und Rücksprung.

Autor: mh123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dass das mit Assembler war mir klar. Deshalb habe ich nach einem schönen 
C-Befehl gefragt. Ich schrieb, dass ich avr-libc benutze.

Es ist ein AVR. Ich schrieb, dass ich avr-libc benutze. Und ich dachte, 
dass die avr-libc nur für AVRs geht.

Das mit der Extra-Funktion wusste ich auch schon. Das habe ich weiter 
oben schon beschrieben.

Leider ist es weder ein externer Pin noch ein Timer.


Da muss ich wohl doch einen der vielen möglichen Umwege nehmen. Da bin 
ich ein bisschen enttäuscht von avr-libc. Bin der sicherlich nicht der 
erste, der so eine Funktion gut gebrauchen kann.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Na wenn du noch genug Flash hast, musst du die Funktion zweimal 
schreiben, in der ISR und in der normalen Funktion.
Michael

Autor: Patrick Markl (patrickmarkl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@naja,

okay :-)

Autor: Naja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Da muss ich wohl doch einen der vielen möglichen Umwege nehmen. Da bin
>ich ein bisschen enttäuscht von avr-libc. Bin der sicherlich nicht der
>erste, der so eine Funktion gut gebrauchen kann.

Das sollte Dir eher ein Hinweis darauf sein, das es Gründe gibt, warum 
dies nicht implementiert wurde.

Im Grunde ist das nur notwendig, wenn Du absolut notwendig 
Programmspeicherplatz sparen musst. Ansonsten kanns Du eine C-Makro 
verwendenn. Der Code taucht dann nur einmal in Deinem Text auf. Du 
kannst das Makro dann in der ISR einsetzten und ein andermal in eine 
Funktion einfügen.

Autor: mh123 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht doch! Ganz einfach sogar.

Einfach den Interruptnamen als Funktionszeiger aufrufen.
Also z. B. ADC_vect();

(Ich dachte zwar, ich hätte es schon erfolglos ausprobiert, aber da 
hatte ich mich wohl vertan.)

@naja: Und, was wären diese Gründe Deiner Meinung nach? ;-)

Autor: (Gast) == (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann doch eine ISR per Vector auf ne andere springen lassen. Der 
Overhead müsste überschaubar sein (ohne mich tiefer mit beschäftigt zu 
haben)
Bsp.

ISR(PCINT0_vect)
{
...
// Code to handle the event.
}

ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));

Quelle: avr-libc-user-manual.pdf


Also irgend nen ungenutzten Timer etc. auslösen lassen...

Autor: Aahh (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Natuerlich kann man einen Interrupt von Hand aufrufen. Man braucht ja 
nur das passende Flag zu setzen. Um zB den timer0 Overflow Interrupt 
aufzurufen, braucht man das TOV0 im TIFR zu setzen

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

geht prinzipiell bei der AVR Architektur nicht. Es ist z.B. nicht 
möglich ein Flag in einem Interruptregister zu setzen, da laut 
Datenblatt ein Schreiben einer 1 das Flag löscht.

Die einzige Möglichkeit wäre Deine Interruptroutine an den gewünschten 
Interruptvektor und an den SPM-Interrupt zu binden (wird meist in der 
Applikation nicht benötigt), dann kannst Du einmalig zur Initialisierung 
den SPM-Interrupt freigeben und danach gleich wieder sperren. Dadurch 
wird sofort Deine Interruptroutine einmal augeführt.

Von dem Funktionsaufruf aus der Interruptroutine kann ich nur abraten 
(es sei denn es ist eine inline/static Funktion im gleichen File), da 
sonst der Compiler einen vollen Interruptframe erzeugt, was die 
Ausführungszeit unnötigerweise erhöht.

Gruss

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich würde es mit etwas Inline-Assembler über einen indirekten Aufruf 
versuchen:

asm volatile (
"mov r30,0xHH\n\t"      //High-Adresse des Interruptvektors (meistens 0)
"mov r31,0xLL\n\t"      //Low-Adresse des Interruptvektors
"icall\n\t"::);         //Indirekter Aufruf der ISR


0xHH und 0xLL bitte mit den richtigen Hex-Werte ersetzen.
Die Methode funkt aber nur bis 64kWords/128kBytes Codegrösse.
Die Adressen der Interruptvektoren findet man im AVR Datenblatt im 
Kapitel Interrupts.

Würde mich über eine Anwort freuen ob es funktioniert.

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mh123,

Du solltest nur das klitzekleine Detail beachten, daß der Compiler für 
das Ende einer ISR ein RETI erzeugt, während bei einer normalen Funktion 
ein RET steht.

Nicht daß Du Dich über merkwürdiges Verhalten wunderst :D

Autor: lol^^ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
reti schaltet interrupts generell ein, also verwende ein cli gleich nach 
dem return (falls nötig!)!

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>reti schaltet interrupts generell ein, also verwende ein cli
> gleich nach dem return (falls nötig!)

Genau das meinte ich, wollte aber dem TE das Erfolgserlebnis lassen, 
selbst draufgekommen zu sein, mennnooo... Alles wieder verraten ;-)

Wobei ich mir nicht sicher wäre, wenn zu diesem Zeitpunkt ein 
Interruptflag bereits gesetzt ist, ob dort nicht wieder sofort in die 
nächste ISR gesprungen, oder ob eben dieses CLI abgearbeitet würde.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wobei ich mir nicht sicher wäre, wenn zu diesem Zeitpunkt ein
>Interruptflag bereits gesetzt ist, ob dort nicht wieder sofort in die
>nächste ISR gesprungen, oder ob eben dieses CLI abgearbeitet würde.

Ein Befehl vom Hauptprogramm wird dann noch abgearbeitet.
In dem Fall das CLI.

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.