Port Interrupt bei MSP430

Gast #361275
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
Gast #361276
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...
Gast #361277
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
Gast #361278
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
}
Gast #361279
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
Gast #361280
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
Gast #361281
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
Gast #361282
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
  }
}
Gast #361283
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.
Gast #361284
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren