Forum: Mikrocontroller und Digitale Elektronik Timer läuft nicht mehr richtig


von Johannes (Gast)


Lesenswert?

Hallo,

ich hatte einen Timer (Atmega328P), welchen ich wie folgt erstellt habe
1
void timer1_init()
2
{
3
//  /* 20 ms */
4
//  //TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC-Mode clkIO/64
5
//  //OCR1A = (5000-1);
6
//  //TIMSK1 |= (1 << OCIE1A);
7
8
  /* 10 ms */
9
  TCCR1B |= (1 << WGM12) | (1 << CS11) | (1 << CS10); // CTC-Mode clkIO/64
10
  OCR1A = (2500-1);
11
  TIMSK1 |= (1 << OCIE1A);
12
}

Dieser lief auch. Getestet mit einer LED, die ich in der ISR sekündlich 
getoggelt habe.
Jetzt wollte ich die Funktion umschreiben, um gleiche auch für andere 
Timer zu benutzen.
1
timer_init(volatile uint8_t* counterRegisterA, uint8_t counterRegisterANewSate,
2
      volatile uint8_t* counterRegisterB, uint8_t counterRegisterBNewSate,
3
      volatile uint8_t* outputCompareUnit, uint16_t outputCompareUnitNewState,
4
      volatile uint8_t* interruptMaskRegister, uint8_t interruptMaskRegisterNewState)
5
{
6
  *counterRegisterA |= counterRegisterANewSate;
7
  *counterRegisterB |= counterRegisterBNewSate;
8
  *outputCompareUnit |= outputCompareUnitNewState;
9
  *interruptMaskRegister |= interruptMaskRegisterNewState;
10
}

aufgerufen habe ich diese
1
  timer_init(&TCCR1A, 0,
2
        &TCCR1B, ((1 << WGM12) | (1 << CS11) | (1 << CS10)), // CTC-Mode clkIO/64
3
        &OCR1A, (2500-1),
4
        &TIMSK1, (1 << OCIE1A));


Jetzt sehe ich, dass die LED viel schneller blinkt.
Woran liegt das? Wahrscheinlich habe ich jetzt den Timer falsch 
erstellt. Ich sehe aber keinen Fehler, da es ja auch eigentlich nur 1 zu 
1 kopiert ist.

Beitrag #6221460 wurde von einem Moderator gelöscht.
von Johannes (Gast)


Lesenswert?

Matthias S. schrieb im Beitrag #6221460:
> Pointer auf uint8_t, aber ein 16-Bit Register beschreiben (OCR1A)? Nö,
> das will man nicht.

Da haste recht :)

Besten Dank

von S. Landolt (Gast)


Lesenswert?

Nur interessehalber: welchen Sinn sollen all diese Veroderungen haben, 
ganz speziell aber bei OCR1A?

von Johannes (Gast)


Lesenswert?

S. Landolt schrieb:
> Nur interessehalber: welchen Sinn sollen all diese Veroderungen haben,
> ganz speziell aber bei OCR1A?

beim OCR1A ist es falsch und könnte sogar zum falschen Ergebnis führen.
Bei den anderen habe ich es immer so gemacht, da manchmal auch mehrere 
Werte in das Register eingetragen werden und somit nichts überschriben 
wird.

von S. Landolt (Gast)


Lesenswert?

Kann ich beim hier vorliegenden Fall, Initialisierung, nicht 
nachvollziehen.

von S. Landolt (Gast)


Lesenswert?

> beim OCR1A ist es falsch und könnte sogar zum falschen Ergebnis führen.
?
Bei den anderen Registern etwa nicht?

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Ich halte das Vorgehen des TE auch für viel zu kompliziert und 
fehlerträchtig. Ausserdem sind Timer 0 und Timer 2 ja nun mal keine 16 
Bit Timer, so das man da wieder was ändern sollte.
Abstrahieren ist ja schön und gut, aber für die Timer kann man es auch 
übertreiben.

von Johannes (Gast)


Lesenswert?

S. Landolt schrieb:
> Kann ich beim hier vorliegenden Fall, Initialisierung, nicht
> nachvollziehen.

So wurde es uns beigebracht. Es gab auch eine Begründung warum man das 
so macht. Diese weiß ich allerdings nicht mehr. Habe es aber immer schon 
so gemacht.

Jetzt auf dem ersten Blick, konnte ich auch kein Register finden, 
welches aus irgendwelchen Gründen doppelt beschrieben wird, wodurch |= 
nötig wäre

von S. Landolt (Gast)


Lesenswert?

> ... immer schon so gemacht

Ist ganz einfach: die timer_init zuerst mit
1
((1 << WGM12) | (1 << CS11) | (1 << CS10)), // CTC-Mode clkIO/64
anschließend mit
1
((1 << WGM12) | (1 << CS12) ), // CTC-Mode clkIO/256
aufrufen und schauen, was passiert.

von Peter D. (peda)


Lesenswert?

Johannes schrieb:
> Jetzt wollte ich die Funktion umschreiben, um gleiche auch für andere
> Timer zu benutzen.

Eine Funktion, die fast nichts macht, der aber 12 Byte an Argumenten 
übergeben werden müssen, ist nicht so der Brüller.
Den Flash kriegt man auch auf bessere Arten gefüllt.

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.