Forum: Mikrocontroller und Digitale Elektronik Port Interrupt bei MSP430


von MSP-Foo (Gast)


Lesenswert?

Hallo!
Ich versuche z.Zt. die Länge eines Impulses der an P2.0 (MSP430F1121)
anliegt zu messen. Ein Timer soll bei steigender Flanke gestartet
werden und bei fallender Flanke gestoppt werden.

Initialisiert habe ich den Port so:
1
  P2IE |= 0x01;      // P2.0 int enabled
2
  P2IES |= 0x00;     // P2.0 low/high edge
3
  P2IFG &= ~0x01;    // P2.0 IFG clear

Meine ISR: (da steckt irgendwo der Fehler denke ich...)
1
#pragma vector=PORT2_VECTOR
2
__interrupt void Port_2(void)
3
{
4
  // int bei low -> high
5
  if (P2IES & 0x00)
6
  {
7
    start_timer();
8
    // int bei high -> low
9
    P2IES &= ~0x01;
10
  }
11
  else
12
  {
13
    stop_timer();
14
     // int wieder bei low -> high
15
    P2IES |= 0x00;
16
  }
17
  P2IFG &= ~0x01;
18
}

Findet ihr den Denkfehler? Bin für jede Hilfe dankbar

von SupaChris (Gast)


Lesenswert?

Und was geht da nicht? Wird die ISR denn angesprungen? Mal nen
Breakpoint setzen? Auf den ersten Blick seh ich da jetzt keinen
großartigen Denkfehler. Hab ich bei meinem Komfortblinker ähnlich
gemacht. Also den Flankenwechsel für den Int.

Aber wieso nimmst du nicht die Capture Compare Einheiten in Hardware
dafür? Die sind doch extra für sowas...

von Martin Schneider (Gast)


Lesenswert?

Ich sehe zwei Probleme:

(P2IES & 0x00) ist immer FALSE -> dein if-Zweig wird nie angesprungen.

P2IES |= 0x00; bewirkt garnichts.

Vermutlich soll da irgendwo 0x01 stehen...

Ahoi, Martin

von MSP-Foo (Gast)


Lesenswert?

doch die ISR wird aufgerufen...aber er schreibt immer nur "count=0"
aufs LCD.

Hier der Rest von meinem Source:
1
unsigned int count = 0;
2
3
#pragma vector=TIMERA0_VECTOR
4
__interrupt void Timer_A0(void)
5
{
6
 count++;
7
 CCR0 += 5000;
8
}
9
10
11
void start_timer()
12
{
13
 // Timer für Zeitmessung starten 
14
15
    count = 0;
16
    TACTL = TASSEL_2 +  MC_1;  // ModeControl -> 1 = Up
17
                            // SourceSelect -> 2 = SMCLK
18
}
19
20
void stop_timer()
21
{
22
 // Timer für Zeitmessung stoppen 
23
    TACTL = TASSEL_2 +  MC_0;  // ModeControl -> 0 = Stop
24
                            // SourceSelect -> 2 = SMCLK
25
    
26
    position(2,1);
27
    printtext("count=");
28
    printzahl(count);                            
29
}

von MSP-Foo (Gast)


Lesenswert?

jetzt komm ich gar nicht mehr weiter.... hirn-block

kann mir bitte einer von euch eine ISR schreiben, die bei steigender
flanke "start_timer" aufruft und bei fallender flanke
"stop_timer"...
wäre sehr nett! Danke

von Thomas (Gast)


Lesenswert?

Diese Tabelle solltest du beachten wenn du das IES Flag setzt, wärend
die Interrupts aktiviert sind:

PxIESx  PxINx   PxIFGx
0 → 1   0       May be set
0 → 1   1       Unchanged
1 → 0   0       Unchanged
1 → 0   1       May be set

Einfacher wäre es das signal an 2 pinns anzulegen und dann einen auf
Positive Flanke, den anderen auf negative Flanke einzustellen.
Dann musst du in der ISR nur noch abprüfen welcher port den Interrupt
ausgelösst hat und dan timer dann entsprchend starten oder stoppen.

also so:
main()
{
 //Port 2.0 und P2.1 -> Signal
 P2SEL = 0x00;
 P2DIR = 0xFC;
 P2IE = 0x03;
 P2IES = 0x02;

//alle inerrupts einschalten
}

#
#pragma vector=PORT2_VECTOR
#
__interrupt void Port_2(void)
#
{
  if (! P2IFG & 0x01) //starte Timer
  if (! P2IFG & 0x01) //stoppe Timer
}

gruss Thomas

von SupaChris (Gast)


Lesenswert?

Oder halt die Flanke umschalten mit

P1IES |= 0x01;   //H->L Flanke

und P1IES &= ~0x01;   //L->H Flanke

die Überprüfung mit:

if (P1IES & 0x01)  //war H->L Flanke
if (!(P1IES & 0x01))  //war L->H Flanke

von MSP-Foo (Gast)


Lesenswert?

ganz ehrlich, so ganz durchgeblickt hab ich da noch net...
würde das mit der "umschalterei" so gehen?

#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
  if (P2IES & 0x01)  //war H->L Flanke
  {
   stop_timer();
   P2IES &= ~0x01;   //L->H Flanke
  }

  if (!(P2IES & 0x01))  //war L->H Flanke
  {
   start_timer();
   P2IES |= 0x01;   //H->L Flanke
  }
}

von SupaChris (Gast)


Lesenswert?

Nö, aber so vielleicht:

#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
  if (P2IES & 0x01)  //war H->L Flanke
  {
   stop_timer();
   P2IES &= ~0x01;   //L->H Flanke
   retrun;
  }

  if (!(P2IES & 0x01))  //war L->H Flanke
  {
   start_timer();
   P2IES |= 0x01;   //H->L Flanke
  return;
  }
}

Ganz wichtig das erste ruturn sonst ist ja die Bedingung für die 2. If
Abfrage immer erfüllt.

von Frank Voss (Gast)


Lesenswert?

Hallo,

habe ein ähnliches Problem. Ich möchte auch bei einem Taster erst die
Flanke von hight->low detektieren (Taster drücken) und dann low->high
(Taster loslassen).

Könnte man das ganze nicht mit

 if (P2IES & 0x01)  //war H->L Flanke
 {

 }
 else if (!(P2IES & 0x01))  //war L->H Flanke
 {
....

anstatt mit return.
Oder wird das else if dann trotzdem ausgeführt?


Gruß
Frank

von Christian S. (aliendrummer)


Lesenswert?

>> Aber wieso nimmst du nicht die Capture Compare Einheiten in Hardware
dafür? Die sind doch extra für sowas...


Wie würde das denn mit Capture & Compare gehen?

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.