mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 Interrupt Port1


Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen alle zusammen

Beim MSP430F149 sind ja die Ports 1+2 interruptfähig.
Ich frage mich nun, wie man mit einem Interruptvektor 2 verschiedene
Sachen ausführen kann. z.bsp. Soll bei Port1.0 bei der fallenden Flanke
etwas anderes passieren, als bei der steigenden Flanke an P1.7

Die Interruptroutine lautet ja bekanntlich folgendermassen:

#pragma vector=PORT1_VECTOR
__interrupt void Port1_Interrupt (void)
{

   Anweisungen;
}

Muss man zusätzlich das P1IFG Flag mit der Software zurücksetzen oder
geschieht dies automatisch?

Gruss Mike

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann prüf doch einfach hart die Ports ab:

#pragma vector=PORT1_VECTOR
__interrupt void Port1_Interrupt (void)
{
  if (P1IN|0x01) tu_was_besonderes();  // 0x01 ist ja P1.0
  else if (P1IN|0x02) tu_was_anderes_tolles();  // 0x02 ist P1.1 usw.
}

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
soviel ich weiss, hat es ja für jeden port ein eigenes interruptflag

geht das so nicht:


#pragma vector=PORT1_VECTOR
__interrupt void Port1_Interrupt (void)
{
if((P1IFG&0x01)==1)   //Wenn Flag von P1.0 gesetzt ist
    {
    LPM3_EXIT;
    lcd_initialisierung();
    }
if((P1IFG&0x80)==1)    //Wenn Flag von P1.7 gesetzt ist
    {
    P6OUT=0x00;
    P3OUT=0x00;
    LPM3;
    }
P1IFG=0;   //Inerruptflag zurücksetzen
}

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn allerdings beide Möglichkeiten bestehen, dann kein else if, sondern
ein einfaches neues if:

#pragma vector=PORT1_VECTOR
__interrupt void Port1_Interrupt (void)
{
  if (P1IN|0x01) tu_was_besonderes();      // 0x01 ist ja P1.0
  if (P1IN|0x02) tu_was_anderes_tolles();  // 0x02 ist P1.1 usw.
}

Geht auch mit switch-case:

  switch ((int)P1IN)
  {
    case 0x01:  /* P1.0 */
      break;

    case 0x02:  /* P1.1 */
    case 0x04:  /* P1.2 */
      break;

    case 0x03:  /* P1.0 && P1.1   */
    default:    /* unknown source */
      break;
  }

Gruß,
Patrick...

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hups, hab Dein Posting übersehen!
Kannst natürlich auch die Flags anstelle der Ports abfragen!

Gruß,
Patrick...

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, noch was: das "|" (fällt mir grad erst auf) muss ein "&" sein!

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, sehe ich genauso. Die Lösung mit den Flags ist sogar noch eleganter.
:-)

Und ob man das Flag zurücksetzen muss, steht 100%ig im User Guide.
Probier es doch einfach aus. Ich würde aber mal tippen, dass das
automatisch resettet wird (so wie z.B. beim USART-IR-Flag).

Grüße, Sebastian

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
muss man das P1IFG Flag wieder mit der Software zurücksetzen??

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Oh, noch was: das "|" (fällt mir grad erst auf) muss ein "&"
sein!

Mea culpa. Es ist noch so früh am morgen ... :-)

Grüße, Sebastian

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> muss man das P1IFG Flag wieder mit der Software zurücksetzen??

AAAAAARGH! LIES! WAS! ICH! SCHREIBE!

Probier es doch einfach aus! Das dauert ca. 2 Minuten ... Debugger an,
IR-Flag in den Watch und los. Einmal mit resetten, einmal ohne. Dann
siehst du es doch. ;-)

Autor: Ingo Henze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Muß man sich nicht auch noch irgendwie den Vohergehenden Zustand der
Port-Pins merken und zusätzlich auswerten.
Denn wenn im ersten Interrupt P1.0 auf 1 geht, dann wird die Funktion
abgearbeitet.

Im nächsten Interrupt für Flanke von P1.1 wird dann aber wieder die
Funktion für P1.0 mit abgearbeitet, weil dieser ja noch immer 1 sein
könnte.

Oder seh ich da was falsch?

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Genau darum geht es ja gerade. Das Flag wird entweder automatisch zurück
gesetzt, oder Mike muss das manuell machen. Keine Ahnung, wie das war,
hab ich vergessen. Steht aber sicherlich irgendwo im User Guide. Und
dann passiert das von dir beschriebene nicht.

Autor: Ingo Henze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich meine aber nicht das Interrupt-Flag, sondern den Zustand der
Port-Pins selber.

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Oldbug: Wieso machst du eigentlich einen Typecast?!

> switch ((int)P1IN)

Das ist doch überflüssig, da die Portpins eh byteweise ausgewertet
werden?!

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich meine aber nicht das Interrupt-Flag, sondern den Zustand der
> Port-Pins selber

Häh? Ja, das war mir schon klar. Und ich sage: Brauchst du nicht! Wenn
du das IR-Flag korrekt zurücksetzt, sollte dir der Zustand der Pins
völlig egal sein. Denn du triggerst ja auf FLANKEN, nicht auf ZUSTÄNDE!

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
War mir nicht sicher, ob der IAR (weil ich selber nur gcc verwende), das
anmeckert (switch muss immer nach int "geswitched" werden, Register
sind aber als unsigned char definiert).

Also: nur zur Sicherheit, kann sein, daß das auch ohne Funktioniert und
nicht beanstandet wird. Hatte auch jetzt keine Lust, das extra
auszuprobieren g

Gruß,
Patrick...

Autor: Ingo Henze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja klar, getriggert wir auf Flanken, aber in der Interrup-Routine fragst
Du doch aber dei Zustände der Pins ab, um entsprechend zu
verzweigen.
if (P1IN|0x01) ...
if (P1IN|0x02) ...
Und die ändern sich nicht mit dem Zurücksetzen den Interrupt-Flags,
oder?

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Völlig richtig. Das Abfragen der Zustände war ja auch nur so meine erste
Idee. Die ist aber suboptimal, wie sich mittlerweile herausgestellt
hat. Aber ist doch auch egal, Mikes Problem scheint ja gelöst zu sein.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Und die ändern sich nicht mit dem Zurücksetzen den Interrupt-Flags,
>oder?

Richtig! Das kann sogar "Fehler" verursachen. Beispiel:
Flankengetriggerter Interrupt auf P1.0 freigeschaltet
Flanke tritt auf
if(P1IN & 0x0X)... arie wird abgearbeitet, findet aber nie ein
Ergebnis, da die Flanke (und mglw. auch der Zustand des Pins) längst
nicht mehr repräsentativ ist.

Gruß,
Patrick...

Autor: Ingo Henze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moment mal, dann hab ich das aber nicht verstanden :-)
Wie erfahre ich in der Interrupt-Routine, welcher meiner Eingänge am
Port den Interrupt ausgelöst hat?
Doch nur über den Zustand des Pins, oder?
Kann mir das bitte nochmal jemand erklären.

Danke!

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Über das Interrupt Flag Register (PxIFG).

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Ingo: Mach doch einen neuen Thread auf. Jetzt fangen hier zwei Leute
an, verschiedene Fragen zu stellen, das wird tierisch unübersichtlich.
Du stellst Fragen, die Mike schon längst geklärt hat, und ich blicke
bald gar nicht mehr durch ... ;-)

Autor: Ingo Henze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also so, wie Mike es weiter oben selbst vorschlägt?
if((P1IFG&0x01)==1) ...
if((P1IFG&0x80)==1) ...

Na dann hab ich es wohl doch begriffen :-=
Danke!

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich sage nur verwirrung pur ;o)

Die Interrupts funktionieren glaube ich so langsam aber sicher. Muss
noch einwenig daran herumfeilen..

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas kann man auch schlecht vermitteln. Ich vermute, daß es daran
liegt, daß derjenige, der sich gerade erst damit beschäftigt, ein
völlig falsches Bild von dem hat, was er da macht. Am vermittelnden (so
lange seine Aussagen richtig sind) liegts meistens nicht :-)

Gruß,
Patrick...

Autor: Ingo Henze (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, dann halte ich mich besser aus Sachen raus, von denen ich nicht
wirklich was verstehe, um nicht noch mehr Verwirrung zu stiften.
"Schuster bleib bei deinen Leisten", ich bleib dann doch erstmal bei
meinen AVRs :-)

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Mike: Hat sich eigentlich mittlerweile was ergeben? Klappen deine
flankengetriggerten Interrupt-Routinen? Ich bräuchte sowas jetzt
nämlich auch, und wenn dein Code funktioniert, wäre es nett, wenn du
ihn mal hier posten könntest. Man muss das Rad ja nicht zwei mal
erfinden. Insbesondere, was das IR-Flag angeht; du hast ja mittlerweile
bestimmt rausgefunden ob es automatisch resettet wird ;-)

Autor: Mike (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Sebastian, ja, funktioniert alles einwandfrei. Dann kann ich ja
auch dir mal helfen ;o)
Das Flag muss mit der Software geresetet werden...

Der Code sieht folgendermassen aus:

_BIS_SR(GIE);         //algemeiner Interrupt enable
P1IE|=0x01;           // P1.0 ist jetzt Interrupt-fähig
P1IES|=0x00;          // Interrupt bei low-->high Übergang=0



//Interrupt Routine

#pragma vector=PORT1_VECTOR
__interrupt void Port1_Interrupt (void)
{
if((P1IFG&0x01)==0x01)   //Wenn Flag von P1.0 gesetzt ist
    {
    Anweisungen;
    }

P1IFG=0;   //Inerruptflag zurücksetzen
}


Gruss Mike

Autor: Sebastian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Mike,

das mit dem resetten hatte ich mittlerweile auch im User's Guide
nachgelesen -- in der Tat, das Ding muss manuell resettet werden.
Komisch, beim USART geht das ja automatisch ...

Ich grübele gerade noch über dem GIE-Bit. Weisst du eigentlich, ob das
nach einem Power-On per default gesetzt ist? Ich schicke meinen MSP430
in den LPM3 mit GIE (_BIS_SR(LPM3_bits + GIE);), da ist es mir eh egal,
aber falls ich das mal nicht mache, müsste ich ja dann aufpassen, immer
zuerst das GIE zu setzen, falls es nicht sowieso per default gesetzt
ist.

Welche IDE benutzt du noch mal? IAR? Und wo hast du die Namen des
IR-Vektors her? Ich hab da zum Verrecken nix gefunden. OK, die Namen
sind ziemlich logisch, die hätte ich auch erraten können, aber da muss
es doch irgendwo eine Übersicht geben?! Oder hast du das einfach aus
dem Header-File "erraten"?

Autor: Mike (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
nein, die Vektoren sind in dem slas... file (seite9), welches ich dir
angehängt habe.danach habe ich mit der adresse im headerfile
nachgeschaut und den verwendbaren Vektor gefunden.
Wegen dem Power up habe ich leider keine Ahnung, aber du kannst das GIE
ja immer setzten, wenn du einen Interrupt brauchst.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Btw.: DAS sieht ziemlich unübersichtlich aus:

>//Interrupt Routine
>
>#pragma vector=PORT1_VECTOR
>__interrupt void Port1_Interrupt (void)
>{

Besser die Makros verwenden:

interrupt[PORT1_VECTOR] void Port1_Interrupt (void)
{
    /* something */
}

für IAR, oder für gcc:

interrupt(PORT1_VECTOR) void Port1_Interrupt (void)
{
    /* something */
}

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.