Forum: Mikrocontroller und Digitale Elektronik MSP430 Timer-Problem


von Rainer (Gast)


Lesenswert?

Hallo,

betreibe einen MSP430F1611 mit 8 MHz und möchte den Timer B quasi als 
Zeitmesser für max. 7 (gibt halt 7 Compare-Register) unabhäbgige 
Funktionen als Zeitbasis einsetzen. Allerdings sollen auch Zeiten, die 
mittels 16-Bit nicht mehr darstellbar sind (>= ~8,2 ms bei 8 MHz), 
gemessen werden. Nach Ablauf der entsprechenden Zeit gibt es einen 
Interrupt und es kann eine Aktion ausgeführt werden.

Die Variablen sind alle (bis auf longTempTBR) unsigned long, global und 
volatile!

In der Interruptroutine wird - bei festem Intervall - der Vergleichswert 
für den Counter berechnet und in TBCCR2 abgelegt:
1
__interrupt void Timer_B1(void);
2
TIMERB1_ISR(Timer_B1)
3
__interrupt void Timer_B1(void)
4
{
5
  unsigned long  longTempTBR;
6
7
   switch( TBIV )
8
   {
9
    case  4: // Timer B 2 Intterupt
10
             longTempTBR = (unsigned long) TBR; // Counter-Wert holen
11
         
12
             ... macht etwas...
13
        
14
             longEnableTime = longTempTBR + longEnableIntervall;
15
           
16
             longEnableTimeOverflow = longEnableTime >> 16;     // durch 2^16 teilen, um die Zahl der Overflows zu bestimmen
17
             TBCCR2 = (unsigned int) (longEnableTime & 0xFFFF); // Rest der Division in TBCCR2 als Vergleichswert ablegen
18
           
19
             if (longEnableTimeOverflow > 0) TBCCTL2 &= ~CCIE; // falls Overflow erforderlich (longEnableTime größer als 2^16), Interrupt B2 erstmal blockieren
20
             else TBCCTL2 |= CCIE; // falls kein Overflow notwendig (longEnableTime kleiner als 2^16), Interrupt B2 sofort freischalten
21
                            
22
         
23
             break;                              
24
25
    case 14: // Timer B Overflow
26
             if (longEnableTimeOverflow > 0) longEnableTimeOverflow--; // Overflow-Zähler runterzählen
27
             if (longEnableTimeOverflow == 0) TBCCTL2 |= CCIE; // Overflow-Zähler abgelaufen, also Interrupt freischalten
28
                  
29
             break;
30
    }
31
}

Mit Werten unter 2^16 (0 < longEnableIntervall <= 0xFFFF) für 
longEnableIntervall funktioniert das alles wunderbar! Aber sobald 
longEnableIntervall größer als 65536 wird, wird es erratisch... Hat da 
jemand eine Idee?

von Rainer (Gast)


Lesenswert?

P.S.: Der Timer B läuft auf M_CLOCK mit 16 Bit im Continious-Mode
1
  // no Group, SMCLK, continuous  mode, 16 Bit, Clockdivider /1
2
  TBCTL = TBCLGRP_0 + TBSSEL_2 + MC_2 + CNTL_0;
3
  TBCTL |= TBIE;  // OverflowInterrupt enabled
4
  TBR = 0;        // Counter B nur einmal initial zurücksetzen

von Jörg S. (joerg-s)


Lesenswert?

D.h. in der Zeile
1
longEnableTime = longTempTBR + longEnableIntervall;
bekommt longEnableTime einen falschen Wert wenn longEnableIntervall 
größer 0xFFFF ist?

von Rainer (Gast)


Lesenswert?

nein - das komische ist, dass die summe korrekt ist. ich habe aber 
festgestellt, dass der TBR, also der eigentliche Counter, meistens (in 
über 90% der Fälle) eine Wert von 186 hat, was eigentlich überhaupt 
nicht sein dürfte! Der TBR müßte doch eigentlich  "durchlaufen", also 
jedesmal einen anderen Wert und langfristig alle möglichen Werte 
zwischen 0 und 0xFFFF annehmen...

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.