Forum: Mikrocontroller und Digitale Elektronik Interrupt beenden


von Siegfried S. (dieleena)


Lesenswert?

hallo,

MPLAP 8.4; C18; PIC18F4580;

um mehr Übersicht in meinem Projekt zu erhalten, habe ich per asm goto 
den
Interrupt in ein anderes Modul umgelenkt. Leider funktioniert das 
beenden des Interupt nicht, da das Modul "read_data_spi" mit RETURN 
beendet und nicht mit RETFIE. Desweiteren werde einige Register nicht 
mit den alten Werte wieder geladen.
Ein Aufruf als Unterpramm wäre eine Möglichkeit, habe mir aber sagen 
lassen, das man in einer ISR kein Unterprogramm aufruft.

Am besten wäre, wenn man die einzelne Interrupts direkt als Module 
schreiben könnte.

gibt es hierzu eine Möglichkeit?
1
void InterruptHandlerHigh()
2
{
3
//---->>>>  INT0 - Interrupt
4
if( INTCONbits.INT0IF == 1 )
5
  {
6
  ...
7
  }
8
//  ---->>>>  ..... 
9
else if (PIR1bits.SSPIF == 1)
10
  {
11
  PIR1bits.SSPIF   = 0;
12
    _asm
13
      goto read_data_spi
14
    _endasm
15
  }
16
}

vielen Dank im voraus.
Gruß Siegfried

von Karl H. (kbuchegg)


Lesenswert?

Siegfried Saueressig schrieb:
> hallo,
>
> MPLAP 8.4; C18; PIC18F4580;
>
> um mehr Übersicht in meinem Projekt zu erhalten, habe ich per asm goto
> den
> Interrupt in ein anderes Modul umgelenkt.

Was soll der Blödsinn?
Auch in einer Interrupt Funktion kann man andere Funktionen ganz normal 
aufrufen.


Ehe du in Zukunft versucht bist, eine Assembler Lösung einzusetzen, 
solltest du erst 10 mal ums Haus laufen, eine rauchen, gut essen, gut 
schlafen und wenn du dann immer noch der Meinung bist, du brauchst 
Assembler, dann stellst du dich vor den Spiegel und haust dir eine rein.

Dieses Verhalten machst du jetzt erst mal das erst halbe bis ganze Jahr. 
Und dann kannst du anfangen, in Ausnahmefällen (!) über 
Assemblerlösungen nachzudenken.

von Karl H. (kbuchegg)


Lesenswert?

> Ein Aufruf als Unterpramm wäre eine Möglichkeit, habe mir aber sagen
> lassen, das man in einer ISR kein Unterprogramm aufruft.

Natürlich versucht man das zu vermeiden, weil der Aufruf an sich Zeit 
kostet. Aber das ist der Preis, den man für Modularisierung zu zahlen 
hat. Bei kleineren Funktionen gibt es immer noch die Möglichkeit der 
inline-Funktionen, bei größeren Funktionen spielt dann der zusätzliche 
Overhead durch den Funktionsaufruf immer weniger eine Rolle.

Du agierst jetzt nach dem Motto:
Ich habe mir sagen lassen, dass man keine Wohnungstüren aufbricht.
Hab ich auch nicht gemacht, ich bin durchs Fenster eingestiegen.

von Peter D. (peda)


Lesenswert?

Ein Interrupthandler hat immer einen Prolog+Epilog.
Wenn Du da mit GOTO rausspringst, ist Dein Stack kaputt.


Peter

von Siegfried S. (dieleena)


Lesenswert?

Hallo Karl Heinz,

bin ein sehr ruhiger Mensch und deshalb frage ich dich, was ist denn dir 
über die Leber gelaufen?
Können wir uns in dem Forum nicht wie zivilisierte Menschen benehmen?
Es kann doch nicht sein, das du von „oben“ nach Lust und gedeihen auf 
die Forums Teilnehmer einklopfst, und nicht das erstemal!
Nehme dir ein Beispiel an Peter.
Frage von mir, zweizeilige einfache Antwort von ihm.
Damit ist die Frage von mir beantwortet.

Gruß Siegfried

von funky (Gast)


Lesenswert?

ach, der ist immer so ;D
aber er meint es nur gut, meints nich persönlich und hat Ahnung. (und 
liebt anscheinend blumige Umschreibungen für einfache Sachverhalte ^-^ )

von Karl H. (kbuchegg)


Lesenswert?

Die Antwort ist deswegen so drastisch ausgefallen, damit du dir 
tatsächlich eines merkst:
Ehe du daran denkst, deinen Compilat mittels Assembler-Zusätze zu 
pimpen, solltest du die Voraussetzungen dafür gründlichst überlegen.

Wenn jemand der Ansicht ist "Och, ich hab da ein C-Problem; das ich 
nicht in C lösen will aber dafür weich ich eben nach Assembler aus", 
dann ist das fast immer der falsche Weg!

Und bei dir ist es dann so, dass dir der gesunde Programmiererverstand 
schon sagen muss, dass du auf dem Holzweg bist. Ohne Not und ohne zu 
wissen was man tut, pfuscht man dem Compiler nicht ins Handwerk. 
Funktionsaufrufe bzw. die dazugehörigen Konventionen muss man gut 
kennen, ehe man sich da als Programmierer einmischt.

von Falk B. (falk)


Lesenswert?

@  Siegfried Saueressig (dieleena)

>um mehr Übersicht in meinem Projekt zu erhalten, habe ich per asm goto
>den Interrupt in ein anderes Modul umgelenkt.

Das ist ein Oxymoron ;-)

von (prx) A. K. (prx)


Lesenswert?

Karl heinz Buchegger schrieb:

> Auch in einer Interrupt Funktion kann man andere Funktionen ganz normal
> aufrufen.

Bei den 8-Bit PICs ist das leider etwas komplizierter, abhängig davon 
welches Speichermodell verwendet wird. Im bei solchen PICs traditionell 
verwendeten statischen Speichermodell wird für lokale Variablen und 
Parameter statischer Speicher verwendet, der per Callgraph-Analyse von 
mehreren Funktionen überlappend verwendet werden kann. Was eine 
Sonderbehandlung bei Interrupts erfordert, die über eine einfache 
"reentrant" Option hinausgehen kann.

Der C18 Compiler kann freilich auch mit einem Stack arbeiten, wodurch 
sich das Problem entschärft. Leider ist das nur mit dem erweiterten 
PIC18 Befehlssatz leidlich effizient, der von der kostenlosen Version 
des Compilers nicht unterstützt wird.

Solche Probleme mit Reentrancy, auch bei anderen statischen Speicher 
bevorzugenden Plattformen, könnten dafür verantwortlich sein, dass sich 
hartnäckig das Gerücht hält, in Interrupts solle man keine Funktionen 
aufrufen.

> Ehe du in Zukunft versucht bist, eine Assembler Lösung einzusetzen,
> solltest du erst 10 mal ums Haus laufen, eine rauchen, gut essen, gut
> schlafen und wenn du dann immer noch der Meinung bist, du brauchst
> Assembler, dann stellst du dich vor den Spiegel und haust dir eine rein.

Nettes Bild, aber ich fürchte du hast nie mit PICs gearbeitet. Es gibt 
grad im Interrupt-Bereich Stellen, wo ganz offziell mit ASM-Statements 
gearbeitet wird (rund um die Entry-Vektoren). Das hat zwar nichts mit 
dem Problem hier zu tun, senkt aber die Hemmschwelle.

von Oliver (Gast)


Lesenswert?

Siegfried Saueressig schrieb:
> um mehr Übersicht in meinem Projekt zu erhalten, habe ich per asm goto
> den
> Interrupt in ein anderes Modul umgelenkt. Leider funktioniert das
> beenden des Interupt nicht, da das Modul "read_data_spi" mit RETURN
> beendet und nicht mit RETFIE.

Na ja, eine Fix für dieses Problem wäre, mit einem weiteren asm goto aus 
dem anderen Module ans Ende der Original-ISR zurückzuspringen.

So etwas versusacht zwar Augenkrebs beim lesen, aber wenns nicht anders 
geht, gehts halt nicht anders.

Oliver

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Nettes Bild, aber ich fürchte du hast nie mit PICs gearbeitet. Es gibt
> grad im Interrupt-Bereich Stellen, wo ganz offziell mit ASM-Statements
> gearbeitet wird (rund um die Entry-Vektoren).
Da waren die allerersten PICs noch so richtig gut. Die kamen ganz ohne 
Interrupts aus... :-o
Das war dann auch genau der Zeitpunkt, als sich unsere Wege (die PICS 
und ICH) kurz gekreuzt haben. Ich bin heute noch froh drum...  ;-)

>>  RETFIE
> So etwas versusacht zwar Augenkrebs beim lesen...
Etwas aus dem Zusammenhang gerissen, trotzdem wahr... ;-)

von Mike J. (emjey)


Lesenswert?

@ Siegfried Saueressig
Darf man mal fragen was es werden wird wenn es fertig ist?

Ich will ja nicht neugierig sein, aber wenn du sagst was über SPI 
eingelesen werden soll erinnert sich jemanden vielleicht an eine gute 
Lösung dafür.

von Siegfried S. (dieleena)


Lesenswert?

Hallo,

das Projekt:
über SPI ein LCD füttern.
wenn das SPI Schieberegister voll ist, dann Interrupt, mit
1
else if (PIR1bits.SSPIF == 1)
in einen Ringbuffer übertragen.

Werde weiterhin beim C18 Compiler im Interrupt in einem Unterprogramm 
den notwendigen Code abarbeiten.

Gruß Siegfried

von Mike J. (emjey)


Lesenswert?

Siegfried Saueressig schrieb:
> wenn das SPI Schieberegister voll ist, dann Interrupt, mit
else if (PIR1bits.SSPIF == 1)
> in einen Ringbuffer übertragen.

Also das empfangene Byte schiebst du in einen Ringbuffer ...

> Werde weiterhin beim C18 Compiler im Interrupt in einem Unterprogramm
> den notwendigen Code abarbeiten.

Du kannst die gesammelten Bytes doch im Hauptprogramm aus den Ringbuffer 
auslesen und auswerten, muss es denn so schnell passieren?

Kann es sein dass der "ISP-Empfangs-Buffer-Interrupt" auftritt während 
die Daten in dem Unterprogramm der ISR noch ausgewertet werden?
Dann würdest du vielleicht ein Byte verlieren.

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.