Forum: Mikrocontroller und Digitale Elektronik MSP430 timerA interrupt


von Fips B. (becphi)


Lesenswert?

Hallo Leute,
ich möchte den TimerA so programmieren, dass er alle Minute einen 
Interrupt auslöst.
Die Einstellungen, die ich bisher gemacht habe bringen mich aber nur auf 
max. 16 sekunden (32kHz Quarz).
Gibt es eine Möglichkeit diese Dauer zu verlängern?

Mein code:

#include  <msp430x12x2.h>

void main(void)
{
  WDTCTL = WDTPW+WDTHOLD;                  // Stop WDT
  P2DIR = 0x001;                           // P2.0 output

  TACCTL0 = CCIE;                          // TACCR0 interrupt enabled
  TACCR0 = 65536-1;
  TACTL = TASSEL_1 + MC_1 + ID_3;          // ACLK, upmode, divider 8
  P2OUT = ~0x001;                          // P2 out

  _BIS_SR(LPM3_bits + GIE);                // LPM3, enable interrupts
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)
{
  P2OUT ^= 0x001;                           // Toggle P2.0
  int i;
  for (i = 32000; i>0; i--);                // Delay
  P2OUT  = ~0x001;                          // P2 out
}

Danke!!!

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Deine Interruptroutine sieht sehr merkwürdig aus

>   P2OUT ^= 0x001;                           // Toggle P2.0
>  int i;
>  for (i = 32000; i>0; i--);                // Delay
>  P2OUT  = ~0x001;                          // P2 out

Die erste Zeile reicht; was soll die "Delay" genannte Schleife *im 
Interrupthandler*? Die hat da nichts verloren.

ACLK wird mit 32 kHz getaktet. Je nach verwendetem MSP430-Derivat kannst 
Du hier noch einen Vorteiler anwenden. Beim 'F1611 und artverwandten 
sind das die DIVAx-Bits in BCSCTL1, mit denen durch bis zu 8 geteilt 
werden kann.

  BCSCTL1 |= DIVA_3;

Damit resultiert ein ACLK von 4 kHz.

Die Taktquelle von Timer_A kann ebenfalls durch 8 geteilt werden (was Du 
ja auch schon tust).

Daraus resultiert ein Takt von 500 Hz (2 msec).

Die langsamste Interruptrate beträgt ein 65536tel davon, das sind 0.0076 
Hz bzw. 131.072 Sekunden Periodendauer.

Das sind etwas über zwei Minuten.

Wenn Du in Deiner Interruptroutine den P2OUT nur einmal invertierst, 
dann resultiert eine Frequenz mit einer Periodendauer von über vier 
Minuten.


Wenn der verwendete MSP430 ein 'F5438 o.ä. ist, dann bietet der Timer_A 
noch einen weiteren Vorteiler, der das ganze nochmal um den Faktor 8 
verlängern kann, das sind die Bits IDEX im Register TAxEX0.

von Fips B. (becphi)


Lesenswert?

Danke für diesen tip!!!  Jetzt funktionierts:-)

Die interruptroutine sieht so aus, damit ich nur ein kurzes Blinken an 
einer LED erzeuge, die an P2.0 hängt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Die interruptroutine sieht so aus, damit ich nur ein kurzes Blinken an
> einer LED erzeuge, die an P2.0 hängt.

Das ist Murks. Verwende eine höhere Interruptfrequenz und eine 
Zählvariable, die Du im Interrupt inkrementierst, und in Abhängigkeit 
des Wertes schaltest Du die LED um:
1
static uint8_t zaehl = 0;
2
3
4
#pragma vector=TIMERA0_VECTOR
5
__interrupt void Timer_A (void)
6
{
7
  zaehl++;
8
9
  if ((zaehl == 1) || (zaehl == 2))
10
    P2OUT ^= 0x01;                           // Toggle P2.0
11
12
  if (zaehl == 16)
13
    zaehl = 0;
14
15
}

Warum schreibst Du eigentlich 12-Bit -Konstanten in Deinen Code?

  P2DIR = 0x001;                           // P2.0 output

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.