Forum: Mikrocontroller und Digitale Elektronik MSP430F5529 Launchpad Entprellen


von Martin (Gast)


Lesenswert?

Moin moin,
ich verzweifle seit ein paar Tagen an meinem MSP430F5529 Launchpad...

Folgendes Programm soll auf Tasterdruck den Modus zwischen 1 - 4 
wechseln und je nachdem die LEDs in unterschiedlicher Art und 
Geschwindigkeit blinken lassen...
Soweit so gut funktioniert auch alles.

Leider werden aber (ca jeder 3.) Status bei Tasterdruck übersprungen.
Es scheint so als würde der Taster Interrupt mehrfach ausgelöst werden.

Die Versuche den Taster mittels Timer zu Entprellen brachten etwas 
Besserung...jedoch werden immernoch Stati übersprungen.

Habe ich beim Entrpellen irgendwo einen Fehler drin??

Viele Grüße und Danke im voraus
Martin


Hier der Code:
#include <msp430.h>

unsigned count = 62000;
volatile unsigned int modus = 0;
void initialize_LEDS(void) {
  P1DIR |= 0x01;                          // LED links  = P1.0
  P4DIR |= 0x80;                          // LED rechts = P4.7
  P1OUT &=~0x01;                          // LED links ausschalten
  P4OUT &=~0x80;                          // LED rechts aus
}


void initialize_Taster(void) {
    P1REN |= 0x02;                          // P1.1 internen Pullup 
aktivieren
    P1OUT |= 0x02;                          // P1.1 internen Pullup auf 
VCC
    P1IE |= 0x02;                           // P1.1 Interrupt enable
    P1IES |= 0x02;                          // P1 hi/lo-Flanke
    P1IFG &= ~0x02;                         // P1.1 IFG lˆschen
}

void initialize(void) { // --------------- Initialisierung 
---------------------
  WDTCTL = WDTPW + WDTHOLD;                // Watchdog nicht benutzen
  TA1CTL = TASSEL_1+ID_0+MC_2+TACLR+TAIE;
  TA1R = count;
  TA1CTL &=~TAIE;                        // disable Timer A IR

  _BIS_SR(GIE);                          // Interrupts global freigeben
}

void sleep(unsigned int round) {
  for (unsigned int j=round;j>0;j--)
    for(unsigned int i=50000;i>0;i--);                   // Delay
}


void main(void) { // --------------------- Hauptprogramm mit main loop 
---------

  initialize();
  initialize_Taster();
  initialize_LEDS();
  modus = 0;
  while(1) {
    if (modus==0) {
      sleep(4); P1OUT ^= 0x01; P4OUT &=~0x80;
    }
    else if (modus==1) {sleep(3); P1OUT &=~0x01; P4OUT ^= 0x80;
    }
    else if (modus==2) {sleep(2); P1OUT ^= 0x01; P4OUT ^= 0x80;
    }
    else if (modus==3) {sleep(1); P1OUT &=~0x01; P4OUT ^= 0x80;
    }
  }
}



#pragma vector=PORT1_VECTOR // ----------- Interrupt Service Routine 
-----------
__interrupt void Port1_Interrupt (void) {
  P1IE &=~0x02;                           // P1.1 Interrupt disable
  TA1IV &= 0x00;
  TA1R = count;
  TA1CTL |=TAIE;                        // enable Timer A IR
  P1IFG &= ~0x02;                         // P1.1 IFG lˆschen

  if (modus<3) modus++;
  else modus = 0;
}



#pragma vector=TIMER1_A1_VECTOR
__interrupt void TIMER1_A1_ISR(void)
{
  switch (__even_in_range(TA1IV, 14))
  {
  case  0: break;                          // No interrupt
  case  2: break;                          // CCR1 not used
  case  4: break;                          // CCR2 not used
  case  6: break;                          // reserved
  case  8: break;                          // reserved
  case 10: break;                          // reserved
  case 12: break;                          // reserved
  case 14:
            P1IFG &= ~0x02;               // P1.1 IFG lˆschen
            P1IE |= 0x02;                 // P1.1 Interrupt enable

            P2IFG &= ~0x02;               // P2.1 IFG lˆschen
            P2IE |= 0x02;                 // P2.1 Interrupt enable

            TA1IV &= 0x00;
            TA1R = 0;
            TA1CTL &=~TAIE;                        // disable Timer A IR

            break;
  default: break;
  }
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Martin schrieb:
> Es scheint so als würde der Taster Interrupt mehrfach ausgelöst werden.

Taster prellen. Unabhängig vom verwendeten µC. Und deswegen werden 
Taster nie an Interrupteingänge angeschlossen, sondern im 
Timerinterrupt gepollt. Ist der Tasterzustand nach mehreren Durchläufen 
unverändert, kann der Tasterzustand als stabil übernommen und 
ausgewertet werden.

von Martin (Gast)


Lesenswert?

hey cool,
vielen dank für die schnelle antwort....

Wäre das dann so ne gangbare Lösung oder geht es auch eleganter?
1
#include <msp430.h>
2
volatile unsigned int modus = 0;
3
unsigned count = 59000;
4
void initialize_LEDS(void) {
5
  P1DIR |= 0x01; // LED links  = P1.0
6
  P4DIR |= 0x80; // LED rechts = P4.7
7
  P1OUT &=~0x01; // LED links ausschalten
8
  P4OUT &=~0x80; // LED rechts aus
9
}
10
11
12
void initialize_Taster(void) {
13
    P1REN |= 0x02; // P1.1 internen Pullup aktivieren
14
    P1OUT |= 0x02; // P1.1 internen Pullup auf VCC
15
}
16
17
void initialize(void) {
18
  WDTCTL = WDTPW + WDTHOLD; // Watchdog nicht benutzen
19
  TA1CTL = TASSEL_1+ID_0+MC_2+TACLR+TAIE; // ACLK, contmode, clear TAR, enable IR
20
  TA1R = count;
21
22
  _BIS_SR(GIE); // Interrupts global freigeben
23
}
24
25
void sleep(unsigned int round) {
26
  for (unsigned int j=round;j>0;j--)
27
    for(unsigned int i=50000;i>0;i--); // Delay
28
}
29
30
31
void main(void) {
32
  initialize();
33
  initialize_Taster();
34
  initialize_LEDS();
35
  modus = 0;
36
  while(1) {                   
37
    if (modus==0) {
38
      sleep(4); P1OUT ^= 0x01; P4OUT &=~0x80;
39
    } 
40
    else if (modus==1) {sleep(3); P1OUT &=~0x01; P4OUT ^= 0x80;
41
    }
42
    else if (modus==2) {sleep(2); P1OUT ^= 0x01; P4OUT ^= 0x80;
43
    }
44
    else if (modus==3) {sleep(1); P1OUT &=~0x01; P4OUT ^= 0x80;
45
    }   
46
  }
47
}
48
49
char button_down(void) {
50
    if ((P1IN & 0x02) == 0) return 1;
51
    return 0;
52
}
53
54
char haltezustand = 0;
55
char losgelassen = 1;
56
#pragma vector=TIMER1_A1_VECTOR          
57
__interrupt void TIMER1_A1_ISR(void)
58
{
59
  switch (__even_in_range(TA1IV, 14))
60
  {
61
  case  0: break; // No interrupt
62
  case  2: break; // CCR1 not used
63
  case  4: break; // CCR2 not used
64
  case  6: break; // reserved
65
  case  8: break; // reserved
66
  case 10: break; // reserved
67
  case 12: break; // reserved
68
  case 14: 
69
            if (button_down()) {
70
              if ((haltezustand) && (losgelassen)) {
71
                 if (modus<3) modus++;
72
                 else modus = 0; 
73
                 haltezustand=0;
74
                 losgelassen=0;
75
              } else haltezustand=1;  
76
            } else {
77
              haltezustand=0;
78
              losgelassen=1;
79
            }
80
          
81
            TA1IV &= 0x00;
82
            TA1R = count;
83
84
            break;
85
  default: break;
86
  }
87
}

--

Dir fällt auf, daß Dein Quelltext jetzt plötzlich lesbarer dargestellt 
wird?

Das könntest Du auch selbst erreichen, wenn Du die Hinweise oberhalb 
des Texteingabefensters lesen und anwenden würdest.

-rufus

: Bearbeitet durch User
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.