Forum: Mikrocontroller und Digitale Elektronik [AVR] Timer lässt sich nicht mehr "starten"


von Draco (Gast)


Lesenswert?

Ich habe da ein kleines Problem.

Ich möchte einen Timer stopen und starten - jedoch stehe ich da vor 
einem kleinen Rätsel.

Ich starte und initialisiere den / die Timer folgendermaßen:

1
void SetupTimer1(uint16_t Prescaler)
2
{
3
  TCCR1A |= (1<<COM1A0);  //Pintoggle on Com1a0 / OC1A / PB5
4
  
5
  switch (Prescaler) 
6
  {
7
    case 8:
8
       TCCR1B = (1<<WGM12) | (1<<CS11);             //Prescaler 8
9
       break;
10
    case 64:
11
       TCCR1B = (1<<WGM12) | (1<<CS10) | (1<<CS11); //Prescaler 64 
12
       break;
13
    case 256:
14
       TCCR1B = (1<<WGM12) | (1<<CS12);             //Prescaler 256
15
       break;
16
   }
17
   //TIMSK1 |= (1<<OCIE1A);  //for Interrupt - not needet at moment
18
}

Das läuft tadellos und funktioniert auch. Dann stoppe ich den Timer über 
CSxn = 0 damit er keine Clock mehr hat. Folgendermaßen:
1
void StopTimer1()
2
{
3
  TCCR1B &= ~((CS10) | (CS11) | (CS12));   //Set Clock to zero, no execution
4
}

Auch das klappt wunderbar und der Timer schaltet ab... Sooo.... nun 
komme ich aber zu dem Problem, wenn ich nun den Timer mit der ersten 
Funktion ( SetupTimer1 ) wieder starten will. Macht er - nüx - er macht 
nüx. Warum? Zwischen den Prescalern kann ich doch auch on-the-fly 
wechseln. Warum regt er sich nicht mehr wenn ich in von no-clock auf ein 
Prescaler setze? WGMxn taste ich ja auch nicht an beim löschen, und beim 
neu starten wird ja das komplette TCCRxB Register neu geschrieben.

Achja... µC ist ein Atmega32u4.

Jemand einen Tipp?!

von Christian D. (chris83)


Lesenswert?

Draco schrieb:
> TCCR1B &= ~((CS10) | (CS11) | (CS12));

Wenn dann TCCR1B &= ~((1<<CS10) | (1<<CS11) | (1<<CS12));
aber da du das Register eh neu beschreibst wieso nicht gleich
TCCR1B = 0x00;
?
Ob es daran liegt, kann ich dir so nicht sagen. Aber das fällt mir jetzt 
spontan auf.

von Stefan F. (Gast)


Lesenswert?

Hast du vielleicht einen Stack Überlauf oder einen Amok laufenden 
Pointer, so dass dir der Inhalt der prescaler Variable zwischenzeitlich 
verloren geht?

von Draco (Gast)


Lesenswert?

Christian D. schrieb:
> Draco schrieb:
>> TCCR1B &= ~((CS10) | (CS11) | (CS12));
>
> Wenn dann TCCR1B &= ~((1<<CS10) | (1<<CS11) | (1<<CS12));
> aber da du das Register eh neu beschreibst wieso nicht gleich
> TCCR1B = 0x00;
> ?
> Ob es daran liegt, kann ich dir so nicht sagen. Aber das fällt mir jetzt
> spontan auf.

Ja kann ich auch so machen... hab ich nun auch so übernommen. Da ist 
wenigstens der gesamte Register gelöscht.

Stefan U. schrieb:
> Hast du vielleicht einen Stack Überlauf oder einen Amok laufenden
> Pointer, so dass dir der Inhalt der prescaler Variable zwischenzeitlich
> verloren geht?

Das war der Hinweis in die richtige Richtung :D Zwar kein Überlauf und 
auch nicht auf dem µC, sondern in meinem Programm auf dem Rechner. Dort 
wird eine Befehlsvariable gesendet welche dem µC das Ausschalten der 
Timer mitteilt... diese Position wurde aber nicht zurück gesetzt - so 
das alle weiteren Befehle auf die Position des Ausschaltens gelaufen 
sind.

Danke für eure Hilfe!

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.