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; } }
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.