Forum: Mikrocontroller und Digitale Elektronik ATMega32 Timer-Einstellung mit CTC Modus


von Björn (Gast)


Lesenswert?

Hallo,
ich möchte alle 10ms einen Interrupt mit Timer2 des ATMega32 auslösen.
Dazu habe ich die Formel des Datenblattes benutzt:
f = f_clk / ( 2  N  OCR )

f_clk ist bei mir 14,7456 MHz.
N habe ich auf 1024 gesetzt und OCR2 auf 71, da müsste eine Frequenz von 
genau 100Hz raus kommen. Es ist aber deutlich mehr (ca 3 mal zu schnell)

Hier der Initialisierungscode:
1
DDRB = (1<<PB0) | (1<<PB1) | (0<<PB2) | (1<<PB3) | (1<<PB4) | (0<<PB5) | (0<<PB6) | (1<<PB7);
2
  PORTB = (1<<PB5) | (1<<PB6);  // Pullups der Taster aktivieren
3
  DDRC = (1<<PC4) | (1<<PC5) | (1<<PC6);  //als Ausgang konfigurieren
4
  UBRRH = UBRR_VAL >> 8;
5
  UBRRL = UBRR_VAL & 0xFF;
6
     
7
  UCSRB = (1<<RXEN)|(1<<TXEN)| (1 << RXCIE);  //UART TX einschalten
8
  UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);  //8 data, 2 stop bits
9
10
  MCUCR |= (1<<ISC00);    //INT0 auf fallende und steigende Flanke triggern
11
  GICR |= (1<<INT0);    //INT0 wird aktiviert
12
13
  TCCR2 = 6;        // Timer2 auf FCPU/1024 einstellen
14
  TCCR2 |= (1 << WGM21);  // CTC Modus (Timer 2 wird bei erreichen von OCR2 zurück gesetzt
15
  OCR2 = 71;         // Compare Match alle 10ms
16
  TIMSK |= (1<<OCIE2);  // CTC-Interrupt von Timer 2 wird aktiviert
17
18
  TCCR0 = 5;  // Timer0 auf FCPU/1024 einstellen
19
20
  TIMSK |= (1<<TOIE0);    //Timer0 wird aktiviert

einiges davon wird nicht interessieren, aber besser zuviel als zuwenig.

Und hier dann der Interrupt:
1
ISR(TIMER2_COMP_vect){  // wird alle 10ms ausgeführt
2
...
3
}
Ich kann mir schlecht vorstellen dass die Formel falsch ist, aber ich 
wüsste nicht was ich da falsch gerechnet haben sollte. Mit OCR2 = 230 
stimmt es ca., aber ich würde schon lieber korrekt gerechnete Werte 
nehmen, statt sie empirisch ermitteln zu müssen.

von spess53 (Gast)


Lesenswert?

Hi

>vielleicht solltest Du den H-Teil von UBRR_VAL auch in das H-Register
>laden und den L-Teil in das L-Register...

Wieso? Ist doch richtig.

MfG Spess

von Michael U. (amiga)


Lesenswert?

Hallo,

TCCR2 = 6;        // Timer2 auf FCPU/1024 einstellen

Warum schreibst DU hier nicht die Bitnamen?

1024 ist CS22 = 1, CS21 = 1, CS20 = 1
kann also nicht stimmen.

Gruß aus Berlin
Michael

von Michael U. (amiga)


Lesenswert?

Hallo,

spess53 schrieb:
> Hi
>
>>vielleicht solltest Du den H-Teil von UBRR_VAL auch in das H-Register
>>laden und den L-Teil in das L-Register...
>
> Wieso? Ist doch richtig.

Du bist einfach zu schnell, hatte ich schon bemerkt und den Post 
gelöscht...

Gruß aus Berlin
Michael

von Stefan E. (sternst)


Lesenswert?

Erstens hast du bei der Formel ein "1 +" unterschlagen, zweitens 
beschreibt das f dort nicht die von dir gewünschte Interrupthäufigkeit, 
sondern die Frequenz an einem getoggelten Pin.

Ein Interrupt alle 10 ms sind 100 Interrupts pro Sekunde, daraus ergibt 
sich als OCR-Wert:
1
14,7456 MHz / 1024 / 100 - 1 = 143

von Björn (Gast)


Lesenswert?

ah danke,

alles klar.

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.