Forum: Mikrocontroller und Digitale Elektronik Problem mit Timer_A Overflow-Flag bei MSP430


von Jonny (Gast)


Angehängte Dateien:

Lesenswert?

Hallo alle zusammen!

Ich möchte den Timer_A dazu verwenden, eine kurze Zeit zu warten bis
der nächste Befehl vom uC ausgeführt wird. Dazu lade ich das CCR0
Register mit einem Wert und lasse den Timer im up-Modus starten. Hat
der Timer bis CCR0 gezählt und ist dann wird auf Null gesprungen,
müsste doch eigentlich das TAIFG (TimerA overflow flag) gesetzt werden.


.
.
// Timer init -> siehe Abbildung
.
.

CCR0 = xxxx; // starte Timer
while (TAIFG == 0) // solange kein overlow...
{
}

.
.
.

So habe ich mir das jedenfalls vorgestellt.
Das TAIFG ist das erste Bit des TACTL Registers. Im Anhang findet ihr
ein Abbild aus dem Debugger. Da ist zu erkennen, das das erste Bit
(also TAIFG) im TACTL Register Null ist. Aber TAIFG selber ist 1. TAIFG
ändert seinen Wert auch nicht.

Jetzt bin ich verwirrt und weiß ehrlich gesagt nicht weiter!
Kann mir bitte jemand zur Klarheit verhelfen!?

Vielen Dank
Schöne Grüße
Jonny

von Sebastian (Gast)


Lesenswert?

Ich kapiere dein Problem irgendwie nicht so ganz ...

Guck mal hier: http://mathar.com/msp_disco2.html, vielleicht hilft dir
das ja ein wenig weiter. Lass den Timer doch mal in demselben Modus
laufen, den ich da verwendet habe, und guck, was er dann macht.

von tenner (Gast)


Lesenswert?

moin,

zeig mal deinen gesamten code.
auf dem bild ist zu sehen das du das TACCR0 auf 0 setzt.
in die schleife
while (TAIFG == 0) // solange kein overlow...
{
}
wird das prog nie kommen, da TAIFG = 0x0001. TAIFG ist vom compiler als
feste bitmaske definiert um ggf mit einer &-verknüpfung das TAIFG im
TACTL register abzufragen. dies würde gehen

while ((TACTL & TAIFG) == 0)
{
}

allerdings nur innerhalb der interrupt-service-routine, da in der
routine das TAIFG zurück gesetzt wird.

dein programm müßte ungefähr so ausssehen

int bGo = 0;
void main(void){
....
  TACTL    = TASSEL_1 + TACLR + TAIE;
  TACCTL0  = CCIE;
  TACCR0   = 4096;         // let count 4096 cycles: 125ms (32768khz)
  TACTL    = | MC_1        // start timer in upmode
...
while( 1 ) {
  if( bGo ) {
    bGo = 0;
    machwas();
  }
}

  #pragma interrupt_handler Timer_A0: TIMERA0_VECTOR
  void Timer_A0(void)
{
  bGo = 1;
}

von Jonny (Gast)


Angehängte Dateien:

Lesenswert?

@tenner

Hier mal die main.c!
Ich verstehe jetzt dass TAIFG in ISR zurückgesetzt wird.
Werde das gleich einmal ausprobieren!
Vielen Dank erst mal!


@Sebastian
Hat mir leider nicht viel weiter geholfen, aber trotzdem danke

lg
Jonny

von tenner (Gast)


Lesenswert?

was soll das warten zwischen 2 tastendrücken bewirken?

wenn damit verhindert werden soll, dass eine taste mehfach gelesen
wird, weil nicht schnell genug losgelassen, geht das auch einfacher

...
int count = 0;
...
while( count < 4 )
{
  tmpButton = KeyPressed();
  if( tmpButton == button ){
    count = 0;
    continue;
    }
  count++;
}

sollte allerdings erst nach der zeichenverarbeitung gemacht werden.

von Jonny (Gast)


Lesenswert?

Hallo tenner,

das was du mir vorschlägst habe ich genau so bereits am Ende der
Funktion KeyPressed() implementiert.
Was auf dem LCD erscheint wenn ich eine Taste gedrückt halte ist eine
Art Dauerfeuer (weil Endlosschleife). Darum wollte ich zusätzlich den
Timer zwischen zwei Tastendrücken "einbauen".
Nichts desto trotz möchte ich wissen wie das mit dem Timer
funktioniert. Aber leider, es funzt noch nicht!

Deinen Vorschlag mit der ISR habe ich auch getestet - ohne Erfolg!
Im Debugger habe ich Einzelschrittmodus das Programm durchlaufen lassen
.Der Timer startet und zählt hoch. In dem Moment wenn der Timer von CCR0
auf 0 springt kommt die Meldung:

-FATAL ERROR-

Daraufhin schließt der Debugger!

Soweit der Stand der Dinge.
Ich werde mir jetzt ein Mittagessen gönnen.
Danach ist mein Kopf vielleicht wieder etwas freier!

Vielen Dank für deine Hilfe!
Jonny

von tenner (Gast)


Lesenswert?

hi jonny,

das TACCRO register solltest du in der interruptroutine zurück setzen.

ich weiß nicht mit welchem compiler du arbeitest, das beispiel für die
interrupt-routine war für den imagekraft icc430. beim ti compiler muß
die routine zb so aussehen

interrupt (TIMERA0_VECTOR) Timer_A(void)
{
  TACCR0 = 0;
  go = 1;
}

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.