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.