mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC - Interrupt Priority


Autor: Mirco H. (mirq)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich hab hier einen PIC18F4520 und benutze den C18-Compiler.

Für die serielle Kommunikation mit dem PC möchte ich nun Interrupts 
verwenden. Das funktioniert, wenn ich IPEN auf 0 setze und dann einen 
einen Vektor mit Adresse 0x08 verwende.

Ich möchte aber jetzt unterschiedliche Prioritäten ermöglichen und setze 
IPEN auf 1; sowie auch GIEL und GIEH.

Dazu Fragen...
Wo im Datenblatt finde ich eine Angabe dazu ob meine Interrupt-Quelle 
low- oder high-priority hat?! oder muss ich das für alle selbst 
zuweisen? wenn ja, dann weiß ich ebenfalls nicht wo :/
wenn ich mein programm teste stelle ich fest, dass ich wohl für den 
USART die high-ISR benötige...

Außerdem verwirrt mich, dass es auch ohne die folgende mittlere Zeile 
tut. Wird diese nicht benötigt?
#pragma code high_vector = 0x08
//#pragma interruptlow ISR_high  // NICHT BENÖTIGT?
void high_interrupt(void) {..}

Ist es die gängige Art bei diesem Controller dass man innerhalb der ISR 
erst prüft von wem der Interrupt ausgelöst wurde? Gibt es also wirklich 
insgesamt nur 2 Interrupt-Routinen?


Hoffentlich könnt ihr mir ein bisschen auf die Sprünge helfen :)

Viele Grüße, Mirco

Autor: MarioT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ein Interrupt auftritt, dann springt die Programmausführung an eine 
bestimmte Stelle im Programmspeicher. Diese Stellen sind festgelegt und 
können nicht geändert werden:

Autor: MarioT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Mirco H. (mirq)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, aber das ist alles in Assembler, hat nichts mit C18 zu tun und 
ist außerdem der falsche Controller?!


Ist beispielsweise für den UART standardmäßig eine high-priority 
implementiert? Kann ich das irgendwo nachlesen?

Grüße

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mirco H. schrieb:
> Ist es die gängige Art bei diesem Controller dass man innerhalb der ISR
> erst prüft von wem der Interrupt ausgelöst wurde? Gibt es also wirklich
> insgesamt nur 2 Interrupt-Routinen?

Ja, das ist (nur) beim PIC so.
Das ist ein ziemlicher Pferdefuß der PICs.
Andere MCs haben die Interruptvektoren nach Quelle verschieden, da kann 
man gleich loslegen, ohne was testen zu müssen.
Auch muß der Compiler dann nur die benötigten Register sichern.


Peter

Autor: Gast-O-mat (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Priorität der einzelnen Interrupts kanns Du mit jeweils einem Bit in 
den IPR-,  INTCON2- oder INTCON3-Registern einstellen. Nur nicht für den 
INT0, der ist immer high-priority.
Und ja, es gibt nur einen Vektor für high- und einen für low-interrupts. 
Dort muß man dann per Software auseinanderdröseln, wer den Interrupt 
ausgelöst hat.

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt für jeden Interrupt 3 Register:

PIR - hier sind die Interrupt-Flags drin, wenn der Interrupt ausgelöst 
hat
IPR - hier legst du die Priority fest (0 = high und 1 = low, oder 
umgekehrt, weiß ich nicht aus dem Kopf)
PIE - damit kannst du die die gewünschten Interrupts 
aktivieren/deaktivieren

Low-Priority-Interrupts können von High-Priority-Interrupts unterbrochen 
werden.
High-Priority-Interrupts können NICHT unterbrochen werden.

Verwendung von Prioritäten musst du aber erst mit RCON.IPEN = 1 
festlegen.

Der Einsprungsvektor für High-Interrupts ist 0x0008h und der für 
Low-Interrupts ist 0x0018h

Autor: MarioT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Mirco H. schrieb:
>> Ist es die gängige Art bei diesem Controller dass man innerhalb der ISR
>> erst prüft von wem der Interrupt ausgelöst wurde? Gibt es also wirklich
>> insgesamt nur 2 Interrupt-Routinen?
>
> Ja, das ist (nur) beim PIC so.

Ich habe wieder was gelernt.
Was es nicht alles gibt?

Autor: Mirco H. (mirq)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ahh, danke. Das klappt jetzt alles mit high und low :)
Und auch wenn es wohl eine Umstellung bedeutet kann man sich sicher an 
die nur zwei ISR gewöhnen..

Könnt ihr mir auch noch sagen wieso die Zeile:
#pragma interruptlow ISR_low
scheinbar völlig unnötig ist? Funktioniert auch wenn sie an der gleichen 
stelle ein 'interrupt' statt 'interruptlow' hat oder sogar auch wenn sie 
auskommentiert ist..
Im C18-compiler-Handbuch und in allen Bsp. im Internet ist die Zeile 
immer vorhanden... Wird sie wo anders noch benötigt?

Grüße

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese Zeile bewirkt ein automatisches Context-Saving. Also da kümmert 
sich dann der Compiler drum.

bei "#pragma interrupt" kommen die Inhalte aus WREG, BSR und STATUS in 
sogennante Shadow-Register.
"pragma interruptlow" hingegen, legt die Inhalte auf den Softwarestack.

Autor: Mirco H. (mirq)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist dann eins von beiden möglicherweise als Standard festgelegt, so dass 
ich die Zeile nicht unbedingt schreiben muss? Funktionieren tut es bei 
mir nämlich auch ohne. Danke für die verständliche Formulierung!

Grüße

Autor: Meister Eder (edson)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger schrieb:
> Ja, das ist (nur) beim PIC so.
> Das ist ein ziemlicher Pferdefuß der PICs.
> Andere MCs haben die Interruptvektoren nach Quelle verschieden, da kann
> man gleich loslegen, ohne was testen zu müssen.

Kleine Korrektur: Das ist bei allen 8-Bit PIC so. Die anderen Familien 
sind da moderner ausgerüstet.

Ein wirklich schlimmer Pferdefuss ist es meiner Meinung nach nicht, weil 
auch mit vielen separaten Interruptvektoren die ISR nicht gleichzeitig 
abgearbeitet werden können. Die Latenz beim Eintritt in eine spezifische 
ISR ist da natürlich etwas geringer, ob man von diesem Vorteil was hat 
ist aber sehr von der konkreten Anwendung abhängig.

Grüße,
Edson

Autor: Der Micha (steinadler)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mirco H. schrieb:
> Ist dann eins von beiden möglicherweise als Standard festgelegt, so dass
> ich die Zeile nicht unbedingt schreiben muss? Funktionieren tut es bei
> mir nämlich auch ohne. Danke für die verständliche Formulierung!
>
> Grüße

Ist mir nicht bekannt. Vergleich doch mal den assemblierten Code der 
beiden Varianten.
Sicher kann es auch ohne Context-Saving funktionieren. Aber irgendwann 
kommt der Punkt, wo du einen Fehler suchst, und dir nicht erklären 
kannst, wo der her kommt. Zum Beispiel Vorzeichen-/Rechenfehler.

Interrupt nach der Berechnung:
0. Register 1 und 2 rücksetzen
1. Berechnung mit Register 1 und 2, Schritt 1
2. Berechnung mit Register 1 und 3, Schritt 2
3. Interrupt verändert Register 1

das geht so.

aber bei Interrupt während der Berechnung:
0. Register 1 und 2 rücksetzen
1. Berechnung mit Register 1 und 2, Schritt 1
3. Interrupt verändert Register 1
2. Berechnung mit Register 1 und 3, Schritt 2

kommt Mist raus, weil das Register 1 vom Interrupt verändert wird.

Tritt der Interrupt WÄHREND einer Berechnung auf, kann der dir den 
aktuellen Registerinhalt zerschießen.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Micha schrieb:
> bei "#pragma interrupt" kommen die Inhalte aus WREG, BSR und STATUS in
> sogennante Shadow-Register.
> "pragma interruptlow" hingegen, legt die Inhalte auf den Softwarestack.

Das heißt im Klartext, "pragma interruptlow" ist für Interrupts, die 
selber unterbrechbar sein müssen, also "low priority".
Stack ist sicherer, aber wohl langsamer als Register.


Peter

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.