www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Port1 Interrupt bei MSP430 hat Fehler im Batteribetrieb


Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe ein Problem mit meinem Port1-Interrupt

Also im normalen (Netzteil) Betrieb funktioniert alles wunderbar wie ich 
es mir vorstelle, doch wenn ich dann die Speisung wegnehme (Batterie) 
wechselt der MSP in den LPM4 wie ich das auch wünsche.

Nun kommt jetzt im Batteriemodus ein Port 1 Interrupt, indem ich kurz 
etwas mache und dann soll er gleich wieder in den Sleep Modus.

Am Anfang der ISR lösche ich das P1IFG gleich wieder und schalte GIE 
frei, weil es auch eine Verschachtelung geben könnte (im Batteriemodus 
allerdings nicht). Das funktioniert alles im Normalen Betrieb nur eben 
im Batteriebetrieb löscht er das P1IFG nicht (im Debugger obwohl er 
sollte) und nachdem ich GIE wieder freischalte springt er dann gleich 
wieder in die ISR, wenn ich GIE nicht freischalte springt er einfach am 
Schluss der ISR wieder rein, da das P1IFG eben noch gesetzt ist.

Das merkwürdige daran ist allerdings, dass während ich debugge und er 
mitten in der ISR steckt und ich dann das Netzteil einschalte, dass er 
von da an das P1IFG wieder löschen kann, obwohl er noch immer im LPM4 
ist (da kann er erst raus, wenn die Port1-ISR fertig ist und dann die 
Port2-ISR kommt wo er aufgeweckt wird).
Also liegt es irgendwie nicht am LPM4, aber verstehen tu ich es trotzdem 
nicht, denn im Batteriemodus hat der MSP noch immer 2.3V (zu 3.3V im 
normalbetrieb).

Habt ihr da Ideen was das sein könnte?

#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
{
  if (P1IFG & 0x04)                   // Wenn SSI-Interrupt ...
  {
     TACCR0  = 0x140;                 // 20us Monoflop Timer neu starten
     ssi_value = ssi_value << 1;      // Wert schieben
     while (!(P1IN & 0x04));          // Warte bis SSI-CLK pos. Flanke
     P1OUT |= (((ssi_value & 0x80000000)>>28) & 0x08);
                                      // Bit n ausgeben
     P1IFG &= ~0x04;                  // SSI Interrupt freigeben
  } else
  {
     P1IFG &= ~0x03;                  // Hier sollte er das BIT eigentlich löschen
     __bis_SR_register(GIE);          // Interrupt auf pos. Flanke
     // Multiturn Position anpassen
     par.reed1 = P1IN & 0x01;         // REED 1 einlesen
     par.reed2 = P1IN & 0x02;         // REED 2 einlesen

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hat da keiner eine Idee oder schon ein ähnliches Problem gehabt?

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schade, hat wirklich keiner eine Idee?

Autor: Jörg S. (joerg-s)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht erkennt er auf Grund der niedrigen Spg. (oder sonstwas) 
tatsächlich einen neuen Interrupt.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht werden noch andere Interrupts ausgelöst von vielleicht 
unbeschalteten Eingängen an P1?!?

Ich würde auf jeden Fall als letzte Zeile folgendes reintun:
P1IFG = 0;

Autor: Peter S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also bei Port 1 habe ich folgende Pins interuptfähig geschalten: 
"0,1,3".

Im Prinzip sind das zwei verschiedene Interrups, welche einfach die 
selbe Sprungadresse besitzen (da ja nur eine Port 1 interruptadresse 
vorhanden).

Der erste oben (SSI mit dem Flag P1IFG=0x04) wird während diesem 
Batteriegespiesenen Zustand nie ausgelöst, sehe ich auch im Debugger.

Nur der zweite: 0x01, 0x02 oder halt wenn beide Pins 0x03, deshalb mache 
ich auch "P1IFG &= ~0x03".

Port 1 hat keine unbeschaltenen Pins bei mir (Rest ist für JTAG 
Interface).

Einfach eben im batteriegespiesenen Zustand (2.3V) wird diese eine 
C-Code Zeile nicht ausgeführt.

Autor: Johnny (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber wenn Du bei Pin 3 den Interrupt aktivierst und im Code diesen Pin 
(P1OUT |= (((ssi_value & 0x80000000)>>28) & 0x08)) ansteuerst, dann ist 
es doch normal, dass der Controller gleich wieder in den Interrupt 
springt?!?

Ich würde den Code so umstellen, dass Du in einem Durchlauf der ISR alle 
gesetzten Flags abarbeitest und am Schluss die Flags rücksetzts.

In diesem Sinne:

if (P1IFG & 0x01)
{
  blahblah
}

if (P1IFG & 0x02)
{
  blahblah
}

if (P1IFG & 0x04)
{
  blahblah
}

...

P1IFG = 0;

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.