Forum: Mikrocontroller und Digitale Elektronik msp430 Timer A Interrupts


von Bernhard (Gast)


Lesenswert?

Hallo an alle,

ich habe eine Frage bezüglich des Timers A des msp430 und den damit 
verbundenen Interrupts.
Ich habe schon verzeifelt gegoogelt, das Kapitel im Datenblatt über den 
Timer ganz gelesen und hab immer noch Fragen.

Und zwar werden ja im Up-Mode immer 2 unmittelbare Interrupts ausgelöst, 
nämlich wenn das TAR-Register den Wert des TACCR0-Register erreicht und 
dann noch einen Clk-Zyklus später, nämlich, wenn das Zählregister wieder 
auf 0 geht.
Wie sollen denn da jemals beide Interrupts abgearbeitet werden? Die 
Interrupt-Routinen gehen ja von Haus aus schon 11 Zyklen, ohne den noch 
auszuführenden Code.
Und wie sprech ich den Interrupt, den ich möchte, an? Ich habs bisher 
mit TIMERA0_VECTOR probiert, aber irgendwie geht der MC nie in die 
entsprechende Routine, da ich versuchsweise eine LED ausmachen möchte, 
die aber immer anbleibt.
Könnte da mal jemand Licht in mein Unwissen bringen? Vielen Dank!

Mein jetziger (nicht funktionierender) Code:
1
#include "msp430x20x3.h"
2
3
// ISR:
4
#pragma vector=TIMERA0_VECTOR
5
__interrupt void WATCHDOG_ISR (void)  // Wird jede Sekunde ausgeführt
6
{
7
    P1OUT = 0x0;
8
}
9
10
11
void init(void)
12
{
13
  BCSCTL2 = 6;                      // SMCLK mit Vorteiler 8, SMCLK von DCO
14
  P1DIR = 0x1;
15
  P1OUT = 0x1;
16
  
17
  TACTL |= TASSEL_2;                // SMCLK ist Source für Timer A
18
  TACTL |= ID_3;                    // Vorteiler ist nochmals 8
19
  TACTL |= MC_1;                    // Up-Mode
20
  TACTL |= TAIE;                    // Interrupt für Timer A einschalten
21
  
22
  TACCR0 = 1000;                    // set timer length
23
  TACCTL0 |= CCIE;                  // enable CCRO interrupt 
24
}
25
26
  
27
28
int main( void )
29
{
30
  WDTCTL = WDTPW + WDTHOLD;
31
  init();
32
  _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt
33
  return 0;
34
}

Vielen Dank für eure Hilfe!
Bernhard

von Christian R. (supachris)


Lesenswert?

Bernhard wrote:

> Und zwar werden ja im Up-Mode immer 2 unmittelbare Interrupts ausgelöst,
> nämlich wenn das TAR-Register den Wert des TACCR0-Register erreicht und
> dann noch einen Clk-Zyklus später, nämlich, wenn das Zählregister wieder
> auf 0 geht.

Logisch, wenn du das TAIE Bit im TACTL-Register und das CCIE Bit im 
TACCTL0-Register setzt. Das geht schief, der MSP verhaspelt sich in den 
Interrupts. Beim Up-Mode macht das so keinen Sinn.
Schalte einfach eins von beiden aus.

Und in der ISR musst du das TAIV Register noch prüfen, ob der Int jetzt 
vom Überlauf, vom CCR0 oder vom CCR1 kam.

von szimmi (Gast)


Lesenswert?

Hiho,
verhaspeln is gut. Wenn der TAIFG zuschlägt, findet er keine ISR und 
geht in den Wald =8-o.
Dieser MSP kennt zwei Timer-Interrupts (die Capture-Events lasse ich mal 
weg).
1. TIMERA0_VECTOR (0xFFF2), die wird gerufen, wenn der TAR den Wert in 
TACCR0 erreicht. Er wird mit TACCTL0 |= CCIE scharf gemacht. Diese ISR 
hast Du definiert.

2. TIMERA1_VECTOR (0xFFF0), die wird gerufen, wenn der TAR überläuft 
oder TAR den Wert in TACCR1 erreicht. Die Ursache kannst Du, wie 
supachris bereits erwähnte, im TAIV abfragen. Er wird mit TACTL |= TAIE 
bzw.  TACCTL1 |= CCIE  scharf gemacht. Diese ISR hast Du nicht 
definiert, aber freigegeben.

Wenn Dein Programm erstmal laufen soll (momentan stürzt es aus meiner 
Sicht aus obengenanntem Grund ab), musst Du
TACTL |= TAIE;                    // Interrupt für Timer A einschalten
erstmal rausnehmen.
Wenn Du den Überlauf trotzdem brauchst, lass die Zeile drin und 
definiere zusätzlich:

// Timer_A2 Interrupt Vector (TAIV) handler
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A(void)
{
 switch( TAIV )
 {
   case  2: break;                          // CCR1 not used
   case 10: P1OUT ^= 0x01;                  // overflow
            break;
 }
}

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.