Forum: Mikrocontroller und Digitale Elektronik MSP430 Launchpad interrupt service routine beenden


von Martin G. (kptlt)


Lesenswert?

Hallo Zusammen,

ich bastle zum 1.mal an einem Mikrocontroller herum.
In meinem C Code den ich mit CCStudio erstellte, habe ich eine PWM 
geschrieben, um ein Servo zu steuern.
Im Code enthalten ist eine interrupt service routine die auf den Button 
S2 hört. Allerdings wird die ISR nicht verlassen, sobald der Interrupt 
abgearbeitet ist. Was mache ich falsch?

hier der Code:

# include <MSP430G2553.h>

void main(void)
{


 WDTCTL = WDTPW + WDTHOLD; // Stop WDT

 // CPU Frequence
 BCSCTL1 = CALBC1_1MHZ;
 DCOCTL = CALDCO_1MHZ;

 // define Ports
 P1DIR = 0x40; // P1.6 to output
 P1SEL |= 0x40; // P1.6 to ???

 // interrupt
 P1IE = BIT3;  // P1.3 interrupt enabled
 P1IFG &= ~BIT3;// P1.3 cleared
 __enable_interrupt(); // enable all interrupts


 // PWM
 TACTL = TASSEL_2 + MC_1;
 CCR0 = 20000; // PWM Period
 CCR1 = 1300; // CCR1 PWM duty cycle
 CCTL1 = OUTMOD_7; // CCR1 reset/set


 while(1)
 {}
}
// Anschlag links 2100
// Mittelstellung 1300
// Anschlag rechts 500



// interrupt service routine ausgelöst durch S2
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)

{
  if(P1IFG & BIT3)
  {
   int a=1300;
    do
    {
     a=a-1;
     CCR1=a;
     __delay_cycles(2000); // Verzögerung
    }while(a!=500);  // Bedingung

    do
    {
     a=a+1;
     CCR1=a;
     __delay_cycles(2000); // Verzögerung
    }while(a!=2100); // Bedingung
  }

 }

Gruß Martin

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Martin Gattig schrieb:
> do
>     {
>      a=a+1;
>      CCR1=a;
>      __delay_cycles(2000); // Verzögerung
>     }while(a!=2100); // Bedingung

Argh! So etwas gehört NICHT in eine Interruptroutine.

von Martin G. (kptlt)


Lesenswert?

Hallo Rufus,

was der Code für einen Sinn macht soll im Moment keine Rolle spielen. 
Die Frage ist warum er die Routine nicht verläßt.

Nützliche Beiträge wären echt supi.

Schöne Grüße
Martin

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Rein formell ist die ISR korrekt geschrieben, das "Verlassen" 
funktioniert nicht anders als bei anderen Funktionen auch.

Das Problem liegt einerseits darin, daß Du viel zu viele Dinge in der 
ISR treibst, und andererseits dürfte Dein Taster nicht prellfrei sein, 
so daß die ISR schlichtweg mehrere Male hintereinander aufgerufen werden 
wird.

Prinzipiell löst man nie direkt mit Tastern Interrupts aus (weil eben 
Taster prellen).

Ansonsten scheinst Du Port1 sowohl für Deinen Taster als auch für die 
Ausgabe der PWM zu nutzen - überprüfe doch mal, ob nicht das Ausgeben 
der PWM sich auf das Interruptauslöseverhalten des Ports auswirken 
könnte.

Probiere mal aus, den Taster an einem anderen Port zu betreiben.

von Peter D. (peda)


Lesenswert?

Martin Gattig schrieb:
> Die Frage ist warum er die Routine nicht verläßt.

Da könnte ein Blick ins Datenblatt helfen.
Manche CPU-Architekturen löschen das Pending-Flag einfach automatisch 
beim Interrupt-Eintritt.
Andere benötigen einen speziellen Salm an Instruktionen, um einen 
Interrupt korrekt zu beenden.


Peter

von Martin G. (kptlt)


Lesenswert?

Servus

Zum Erfolg führte die abschließende Zeile in der ISR:
P1IFG &= ~BIT3;  // Clear Interrupt Request

Gruß Martin

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.