Forum: Mikrocontroller und Digitale Elektronik MSP430 Timer & Capture/Compare register


von B. B. (bebu1)


Angehängte Dateien:

Lesenswert?

Hallo Leute!

Ich durchblicke die Bezeichnung der Timer Register/Interrupt Vector 
nicht ganz.

Momentan beginne ich wieder mich in die ganze Programmierung 
einzuarbeiten und versuche mich an kleinen Testbsp.

z.B. folgendes (Kombination aus Vorlage und Selbsterstelltem)
1
#include <msp430.h>
2
3
volatile int unsigned time;
4
volatile int wert=25000;
5
6
int main(void)
7
{
8
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
9
10
  BCSCTL1 = CALBC1_1MHZ;                  // DCO at 1 MHz
11
  DCOCTL = CALDCO_1MHZ;                   // DCO at 1 MHz
12
13
  BCSCTL2 = DIVM_3 + DIVS_3;              
14
                                        // Divider for MCL and SMCLK _1 --> /2; _2 -->/4; _3-->/8
15
                                                        // SMCLK: 125kHz MCLK= 125kHz
16
17
  P1DIR |= BIT2;                           // P1.2 output
18
  P1SEL |= BIT2;                           // P1.2 for TA0.1 output
19
  P1SEL2 = 0;       // Select default function for P1.2
20
  TA0CTL = TASSEL_2 + MC_1;  // SMCLK as source for Timer 0, Up mode: the timer counts up to TACCR0,
21
  TA0CCTL1 =  OUTMOD_2 + CM_1 ;            // CCR0 toogle/set
22
  TA0CCR0 = 65536-1;    // PWM Period for Timer 0 and Capture and Compare register 0
23
  TA0CCR1 = wert;    //~0,25s             // CCR1 PWM duty cycle
24
25
 //measure
26
   P2DIR |= 0x00;         // Port 2 as inputs
27
   P2SEL |= BIT5;      // select Capture function on P2.5
28
   P2SEL |= 0x02;
29
   P2SEL2 = 0x00;
30
31
   TA1CTL = TASSEL_2 + MC_2;  // SMCLK, continuous mode up to 0xffff
32
   TA1CCTL1 = CM_1 + CCIS_0 + SCS + CAP + CCIE;  
33
//capture on rising edge, CCIxB, Synchronous capture, capture mode,Interrupt enabled
34
35
36
  __bis_SR_register( GIE);                // Enter LPM0
37
}
38
39
#pragma vector = TIMER1_A1_VECTOR
40
__interrupt void Timer1_A1_ISR(void) {
41
  switch(TA1IV) {
42
    case  2:    time = TA1CCR1;                                 // stopTime auslesen
43
44
                break;
45
      case  4: 
46
      case 10:  break;
47
    }
48
}

Das Programm funktioniert soweit, bis auf das falsche Messergebnis aber 
dass muss ich mir erst ansehen. Ich will einfach eine PWM an einem Port 
ausgeben und an einem anderen  "messen".
Nun möchte ich als Input-Pin P2.5 anstatt P2.1 nehmen und daran 
scheitere ich. Im Datenblatt steht bei P2.5 CCI2B statt CCI1A.
Das kann ich ja über CCIS bei TA1CCTL1 einstellen.
Was sagt der 2er aus? 2. Register? Muss ich dann TA1CCTL2 nehmen?
Und was bezeichnet das A1 beim Interrupt vector? --> TA1CCTL1?

Danke!

--

Bitte die [ c ] [ /c ]-Tags für Sourcecode verwenden.

-rufus

: Bearbeitet durch User
von Clemens L. (c_l)


Lesenswert?

Bernhard B. schrieb:
> Im Datenblatt steht bei P2.5 CCI2B statt CCI1A.
> Das kann ich ja über CCIS bei TA1CCTL1 einstellen.
> Was sagt der 2er aus? 2. Register? Muss ich dann TA1CCTL2 nehmen?

Ja. (Siehe Table 13 im Datenblatt.)

> Und was bezeichnet das A1 beim Interrupt vector? --> TA1CCTL1?

Nein.  msp430g2553.h hat:
1
#define TIMER0_A1_VECTOR        ( 9)                     /* 0xFFF0 Timer0)A CC1, TA0 */
2
#define TIMER0_A0_VECTOR        (10)                     /* 0xFFF2 Timer0_A CC0 */
3
...
4
#define TIMER1_A1_VECTOR        (13)                     /* 0xFFF8 Timer1_A CC1-4, TA1 */
5
#define TIMER1_A0_VECTOR        (14)                     /* 0xFFFA Timer1_A CC0 */

In dem Symbolen TIMERx_Ay_VECTOR bezeichnet x das Timer-Modul, und y ist 
entweder 0 für den Interrupt für CCR0 oder 1 für den Interrupt für alle 
anderen CCRs und den TR-Überlauf.

von Klaus R. (klara)


Lesenswert?

Clemens L. schrieb:
> Bernhard B. schrieb:
>> Im Datenblatt steht bei P2.5 CCI2B statt CCI1A.
>> Das kann ich ja über CCIS bei TA1CCTL1 einstellen.
>> Was sagt der 2er aus? 2. Register? Muss ich dann TA1CCTL2 nehmen?
>
> Ja. (Siehe Table 13 im Datenblatt.)
>
>> Und was bezeichnet das A1 beim Interrupt vector? --> TA1CCTL1?
>
> Nein.  msp430g2553.h hat:#define TIMER0_A1_VECTOR        ( 9)
> /* 0xFFF0 Timer0)A CC1, TA0 */
> #define TIMER0_A0_VECTOR        (10)                     /* 0xFFF2
> Timer0_A CC0 */
> ...
> #define TIMER1_A1_VECTOR        (13)                     /* 0xFFF8
> Timer1_A CC1-4, TA1 */
> #define TIMER1_A0_VECTOR        (14)                     /* 0xFFFA
> Timer1_A CC0 */
> In dem Symbolen TIMERx_Ay_VECTOR bezeichnet x das Timer-Modul, und y ist
> entweder 0 für den Interrupt für CCR0 oder 1 für den Interrupt für alle
> anderen CCRs und den TR-Überlauf.

Genau damit hatte ich auch meine Probleme. Zudem war in den älteren 
Beispielen die Namensgebung schon mal anders gewählt worden. Clemens 
half mir damals, jetzt habe ich mir diesen Beitrag nochmals kopiert.

TI dokumentiert im Grunde genommen ganz ordentlich. Man hat aber auch 
den Eindruck das der Einsteiger nicht ganz im Focus liegt. Die 
Bezeichnungen der Interruptvektoren ist so ein typisches Beispiel. Sie 
ist nirgendwo klar beschrieben worden. Das Headerfile msp430g2553.h ist 
noch die beste Stelle.

Und dieser Satz ist für die Anwendung der Info sehr hilfreich.
> In dem Symbolen TIMERx_Ay_VECTOR bezeichnet x das Timer-Modul, und y ist
> entweder 0 für den Interrupt für CCR0 oder 1 für den Interrupt für alle
> anderen CCRs und den TR-Überlauf.

mfg klaus

von Felix A. (davinciclaude)


Lesenswert?

Hatte zu Beginn auch so meine Mühe.
Abschnitt 12.2.6 im SLAU144 sollte Licht ins Dunkel bringen :)

von Klaus R. (klara)


Lesenswert?

Claude D. schrieb:
> Hatte zu Beginn auch so meine Mühe.
> Abschnitt 12.2.6 im SLAU144 sollte Licht ins Dunkel bringen :)

Dann möchte ich doch noch für mich selber eine Syntaxfrage stellen.
1
#pragma vector = TIMER0_A1_VECTOR       // ISR for TACCR1 CCIFG and TAIFG
2
__interrupt void TIMER0_A1_ISR(void)
3
{
4
}

TIMER0_A1_VECTOR ist imHeaderfile msp430g2553.h definiert.
Was ist mit dem Namen der ISR-Funktion TIMER0_A1_ISR()?
Ist der frei wählbar?

Wenn nicht, dann hätte ich gerne gezeigt bekommen wo die Verknüpfung 
definiert ist.

mfg klaus

: Bearbeitet durch User
von threadersteller (Gast)


Lesenswert?

Klaus R. schrieb:
> interrupt void TIMER0_A1_ISR(void)

ja die kannst du nennen wie du magst.
zB Timer0_10ms()

von Klaus R. (klara)


Lesenswert?

threadersteller schrieb:
> Klaus R. schrieb:
>> interrupt void TIMER0_A1_ISR(void)
>
> ja die kannst du nennen wie du magst.
> zB Timer0_10ms()

Danke, jetzt ist mir einiges klarer.

von Felix A. (davinciclaude)


Lesenswert?

Aber die Vektornamen sind j.n.d. noch ziemlich mühsam rauszufinden.
Ich schaue immer im Device Datasheet, an welcher Adresse mein Vektor 
liegt. Dann suche ich mir im Headerfile die Adresse und klaube mir den 
Namen des Vektors raus. Keine Ahnung, ob das nicht elganter gienge...

von Klaus R. (klara)


Lesenswert?

Hallo,
die Samples von TI liefern schon einige Infos zur Anwendung, nur nicht 
vollständig. Also muss man sich doch intensiv durch die Doku wühlen. Und 
die Doku ist von Profies erstellt wurden. Deswegen gibt es für die nicht 
so Geübten die Tutorials. Wenn man Glück hat, dann findet man genau 
etwas zu seinem Problem.

Was die Vektornamen betrifft, die sind originär im Headerfile definiert.
mfg klaus

von B. B. (bebu1)


Lesenswert?

Danke für die Antworten und sorry für die späte Rückmeldung aber ich 
komme nicht regelmäßig dazu an meinem Projekt weiterzuarbeiten!

von B. B. (bebu1)


Lesenswert?

Leider check ich es noch immer nicht ganz. Ich habe jetzt nur folgende 
Zeile geändert:
1
TA1CCTL2 = CM_1 + CCIS_1 + SCS + CAP + CCIE;

Jetzt springt das Programm jedoch nicht mehr in den IR. Soweit ich es 
verstanden habe sollte es die selbe ISR sein wie vorher oder?

von Clemens L. (c_l)


Lesenswert?

Ersetze die magischen Zahlen (2,4,10) im Interrupt-Handler durch die 
entsprechenden TA1IV_xxx-Symbole.

von B. B. (bebu1)


Lesenswert?

Das Programm springt jetzt gar nicht mehr in die ISR. d.h. der Fehler 
liegt vorher.

und ob ich jetzt
case 2 oder case 0x02 schreibe ist ja egal.

von B. B. (bebu1)


Lesenswert?

Das Problem liegt tatsächlich in der ISR.. momentan verstehe ich es nur 
noch nicht warum ;)

von wv (Gast)


Lesenswert?

Du hast jetzt auf das CC-Register2 gewechselt. Also muß Du auch Deine 
case-Anweisung entsprechend ändern. Wenn man (wie Clemens schon sagte) 
dort die Konstanten verwendet, hättest Du das gleich selbst gesehen

Auszug Header-file;
1
/* T1_A3IV Definitions */
2
#define TA1IV_NONE             (0x0000)       /* No Interrupt pending */
3
#define TA1IV_TACCR1           (0x0002)       /* TA1CCR1_CCIFG */
4
#define TA1IV_TACCR2           (0x0004)       /* TA1CCR2_CCIFG */
5
#define TA1IV_6                (0x0006)       /* Reserved */
6
#define TA1IV_8                (0x0008)       /* Reserved */
7
#define TA1IV_TAIFG            (0x000A)       /* TA1IFG */

--wv

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.