Globale Variable in ISR immer 0

Gast #2175087
Lesenswert?

Hallo,

ich beschäftige mich seit kurzem mit dem TI MSP430. Dazu habe ich mir 
ein Launchpad gekauft und versuche mich gerade mit einem kleinem 
Programm, das über Interrupts gesteuert LED's ansteuert.

Leider wird die globale Variable wahl zwar in der Routine erhöht, 
allerdings ist sie beim nächsten Einsprung in die ISR wieder den Wert 0.
Ich sehe da keine Ursache, wer weiß eine Lösung.

gruß
Korbinian
1
#include "msp430.h"
2
unsigned char wahl; /* global variable */
3

4
#pragma vector = TIMERA1_VECTOR
5
__interrupt void TIMERA_OVF(void)
6
{
7
  TACTL = 0x02E0; /* Timer counts to 0xFFFF, Divider 8, INT disabled , INTFLAG disabled */
8
  if(wahl < 0x80) 
9
  {
10
    P1OUT ^= BIT0;
11
  }
12
  else if (wahl >= 0x80)
13
  {
14
    P1OUT ^= BIT6;
15
  }
16
  else if (wahl == 0xFF)
17
  {
18
    wahl = 0;
19
  }
20
  wahl++;
21
  __delay_cycles(10000);
22
  TACTL = 0x02E2; // Timer counts to 0xFFFF, Divider 8, INT enabled , INTFLAG disabled
23
}
24

25
int main( void )
26
{
27
  P1DIR = 0xFF; /* PORT1 direction: output */
28
  P1OUT = 0x00; /* Init PORT1 */
29
  __enable_interrupt(); /* enable global interrupt */
30
  TACTL = 0x02E2; /* Timer counts to 0xFFFF, Divider 8, INT enabled , INTFLAG disabled */
31
  for(;;)
32
  {
33
    /* do nothing */
34
  }
35
}
Moderator (Firma: Titel) Persönliche Seite #2175111
Lesenswert?

Rufus Τ. Firefly schrieb:
> Das Stichwort lautet volatile.
Auch bei dieser Frage? Wie kommt der Compiler da drauf?

Wenn die Variable in der ISR geändert wird, dann sollte sie beim 
nächsten Interruptaufruf doch den geänderten Wert haben. Mag sein, dass 
ein volatile hier hilft, aber wo ist dieses Verhalten von globalen 
Variablen dokumentiert?


Aber das gibt mir in einer Interruptroutine doch sehr zu denken:
  __delay_cycles(10000);
Gast #2175128
Lesenswert?

Sorry für den Doppelpost.

Sascha schrieb:
> Hast du den Watchdog des MSP430 deaktiviert? Soweit ich das noch weiß,
> muss man den explizit deaktivieren, sonst zwingt er den uC dauernd in
> den Reset!

Den Watchdog kannst du so deaktivieren:
1
// Stop watchdog timer to prevent time out reset
2
WDTCTL = WDTPW + WDTHOLD;
Gast #2175133
Lesenswert?

AHHHHHH... jetzt wird mir auch klar warum in den Beispiel Projekten als 
erstes im Hauptprogramm steht:

[c]WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer[c]

Vielen Dank für den Hinweis, jetzt funktioniert es und ich hab schon 
fast an meinen Kenntnissen gezweifelt ;).
Gast #2175134
Lesenswert?

AHHHHHH... jetzt wird mir auch klar warum in den Beispiel Projekten als 
erstes im Hauptprogramm steht:
1
WDTCTL = WDTPW + WDTHOLD;             // Stop watchdog timer

Vielen Dank für den Hinweis, jetzt funktioniert es und ich hab schon 
fast an meinen Kenntnissen gezweifelt ;).

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