Forum: Mikrocontroller und Digitale Elektronik Interrup bei MSP430 - Bewegungssensor


von PROJECT_X (Gast)


Angehängte Dateien:

Lesenswert?

servus,

hab da ein problem mit interrupts
der msp430 soll auf einen bewegungssensor reagieren
der sehr empfindlich ist.
dieser toggelt dann eine led in der ISR

hab bei der ISR ein DELAY eingefügt damit der
sensor ausschwingen kann und den PORT interrupt ausgescahltet

stoß ich jetzt meinen sensot ein wenig an, dann schaltet
sich die led ein, aber nachdem der timer abgelaufen ist
wieder aus!
es soll aber so sein, dass beim nächsten stoß sich erst die
led abschaltet.

bitte um hilfe
was mach ich da falsch?!?
danke

und allen einen guten rutsch ins neue jahr!!!!!

von Steven (Gast)


Lesenswert?

Hallo,

So habe ich das verstanden:

Sensor anstoßen
LED ein
Sensor anstoßen
LED aus

Du brauchst in diesem Fall nur ein Flag zu setzen und diese abfragen.

Sensor anstoßen()
{
   if flag then
   {
      LED=1;
      flag=0;
   }
   else
   {
     LED=0;
     flag=1;
   }
}

Müsste so passen. Wenn nicht, das Prinzip sollte klar sein.

von Steven (Gast)


Lesenswert?

Nochwas:

  for(;;){
    WDTCTL = WDTPW + WDTHOLD;          // Stop WDT
    P2IE |= 0x08;                      // P2.3 int enabled
    P2IES |= 0x00;                    // P2.3 low/high edge
    P2IFG &= ~0x08;                    // P2.3 IFG clear
    _EINT();                          //General Interrupt Enable
    _BIS_SR(LPM3_bits);                 //Enter LPM3

  }

Das solltest du nicht machen. Das ist die Initialisierung, die sollte 
nur 1x aufgerufen werden. Du hast sie in die Endlosschleife gesetzt und 
rufst sie immer wieder auf.

Bei deinem Beispiel wäre die Endlosschleife leer, da eh alles 
interrupgesteuert ist.

von szimmi (Gast)


Lesenswert?

Mal abgesehen davon, dass die Struktur Deines Programms ein bissl von 
hinten durchs Knie ist, liegt das Grundübel wohl in Deiner 
Interrupt-Routine:
pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
  _BIS_SR(LPM3_EXIT);
  P4DIR |= 0x01;     //Set P4.0 to Out
  P4OUT ^= 0x01;     //Toggle P4.0 => RED_LED
  P2IFG &= ~0x08;    // P2.3 IFG clear
  _DINT();
  P2IE &= ~0x08;
  c  delay_10us(7000);
  P2IE |= 0x08;
}

Du loescht vor dem Delay das Interruptflag (noch dazu gleich zweimal). 
Somit bist Du unmittelbar vor dem Delay wieder "aufnahmefähig" für das 
nächste Setzen des Interrupt-Request-Flag P2IFG durch Deinen Sensor. Mit 
dem Delay verzögerst Du nur die Ausführung der ISR(mal abgesehen davon, 
dass der MSP ohne Tricks keine nested interrupts unterstützt). Du 
unterdrückst nicht, wie Du das denke ich willst, das Setzen des 
Interrupt-Request-Flags für die 70ms. Wenn Du die Struktur so lassen 
willst, musst Du die Zeile
P2IFG &= ~0x08;
nach dem Delay einfügen. Dann sollte zumindest die Funktion erfüllt 
sein.

von PROJECT_X (Gast)


Lesenswert?

erst mal danke für die hilfe!!!

das problem ist, dass der sensor sehr lange nachschwingt!

wie kann man das den msp430 sagen, dass er nach dem interrupt
warten soll, also das port sperren, damit kein weiterer interrupt
ausgelöst wird???

ich weiß, dass mein code ein wenig dureinander ist
da ich viel herumprobiert hab, ohne nachzudenken
was ich da mache.

hätte auch eine generelle frage, da ich noch mich
noch nicht so gut damit auskenne.
was passiert genau wenn ein interrupt ausgelöst wird?
was macht das IFG dabei??

danke!!

von szimmi (Gast)


Lesenswert?

Hiho,
also, man muss zwei Dinge unterscheiden, das Interrupt-Request-Flag (in 
PxIFG) und das Interrupt-Enable-Flag (in PxIE).
PxIFG wird gesetzt, wenn eine Flanke am Pin erkannt wird (Art der Flanke 
wird in PxIES einegstellt). Das Rücksetzen muss über die SW vorgenommen 
werden. Falls keine Interrupts (ISR) verwendet werden sollen, kannst Du 
PxIFG pollen. Das Flag wird unabhängig von der Interrupt-Freigabe (PxIE 
bzw. GIE) gesetzt.
Über das Interrupt-Enable-Flag (PxIE) kannst Du steuern, ob bei 
Auftreten einer Flanke am Eingang die Interrupt-Service-Routine 
angesprungen wird.
Kurz zusammengefasst (Beipiel P2.0):

Fall 1: P2IE = 0x00 oder GIE = 0:
        1. Flanke
        2. P2IFG = 0x01 (durch HW)
        3. Pollen (z.B.in main)
        4. Reaktion (z.B. toggeln LED)
        5. P2IFG = 0x00 (durch SW)
Fall 2: P2IE = 0x01 und GIE = 1:
        1. Flanke
        2. P2IFG = 0x01 (durch HW)
        3. Anspringen ISR (in ISR z.B. toggeln LED)
        4. P2IFG = 0x00 (durch SW in ISR)
Ich persönlich verwende, falls möglich, die Polling-Methode, falls es 
nicht auf Stromverbrauch und zeitkritische Anwendung ankommt. Aber das 
ist natuerlich jedem selbst ueberlassen.
So, ich hoffe, ich habe prinzipiell nix vergessen und es ist halbwegs 
verständlich. In den User Manuals (z.B. slau049d.pdf)ist das Ganze auch 
ganz gut beschrieben.

von PROJECT_X (Gast)


Lesenswert?

DANKE
für die hilfe!!!


ja, ist stromkritisch, also LPM3 ist nötig!
werd morgen, des gleich ausprobieren!!
wenn ich dann noch ein problem hab, werd ich mich wieder melden!

mfg

von PROJECT_X (Gast)


Angehängte Dateien:

Lesenswert?

sodala, es ist soweit
das nächste problem steht an!

der IAR sagt beim debuggen, dass der STACK voll ist
in der zeile

       while(time_us != irq_count);                // Fertig?

bleibt das prog stecken.
ir_qcount ist dann 32941
und flag ist 244

irgendwo ist da ein überlauf, oder??


von szimmi (Gast)


Lesenswert?

Hiho,
ich denke mal, da laufen mehrere Port2 Interrupts verschachtelt, sodass 
der Stack überläuft.
Ich habe Dein Programm mal etwas ueberarbeitet (habe leider gerade 
keinen Compiler dabei, sind also sicherlich noch Fehler drin). Aber 
prinzipiell sollte es gehen. Probiere es mal aus.
Gruss
Steffen

von szimmi (Gast)


Angehängte Dateien:

Lesenswert?

Ups,
Anhang fehlte

von PROJECT_X (Gast)


Angehängte Dateien:

Lesenswert?

servus

danke, hab deine version getestet, bleibt aber in der ISR
des ports stecken.

hab selbst meine version umgeschrieben, und es funzt jetzt
so, wie ich mir das vorgestellt habe.
das problem war, wie du sagtest, das ein port interrupt
durch das nachschwingen des sensors, in die routine
des timers gefunkt hat, und deshalb denk ich mal
hats net gefunzt.

hab jetzt einfach das port interrupt in der ISR ausgeschaltet
und erst nachdem die LED funktion abgearbeitet ist,
wieder eingeschaltet, und jetzt gehts

schaus dir an, vl findest noch ein paar verbesserungs
vorschläge ;-)

mfg

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.