Morgen,
ich spiele gerade bisl mit den Timern meines ATmega16 und deren Modi.
Jetzt ist mir etwas seltsames aufgefallen:
Ich benutze den Timer0 (8 Bit) und Timer1 (16 Bit), beide im CTC Modus.
Mein Atmel rumpelt mit 16 MHz.
Der Timer0 benutzt den Prescaler 64 und das Compare Register lade ich
mit 250.
Das sollte einen CompareMatch Interrupt alle 1 ms ergeben.
Timer1 benutzt als Prescaler 8 und das Compare Register wird mit 5000
geladen, das sollte einen Interrupt alle 2.5 ms ergeben.
Um die Funktion zu testen toggle ich im IR jeweils eine LED.
Allerdings nicht jedesmal.
Bei Timer0 lasse ich eine Variable auf 1000 zählen, bei Timer1 bis 400.
D.h. beide LEDs sollten alle 1 s getoggelt werden.
Mein Atmel macht sonst rein garnichts mehr, auch keine anderen IRs.
Allerdings laufen die LEDs "auseinander". Je länger ich die Schaltung in
Betrieb habe desto versetzter gehen die LEDs an und aus. Und zwar
merklich mit bloßem Auge :/
Hab ich einen Denkfehler bei meinen Register/Variablen Werte?
Hier der Code der main:
1 | volatile uint16_t counter_Timer1 = 0;
|
2 | volatile uint16_t counter_Timer0 = 0;
|
3 |
|
4 | ISR (TIMER0_COMP_vect)
|
5 | {
|
6 | counter_Timer0++;
|
7 | if (counter_Timer0 >= 1000)
|
8 | {
|
9 | TOGGLE_PIN(0, PORTB);
|
10 | counter_Timer0 = 0;
|
11 | }
|
12 | }
|
13 |
|
14 | ISR (TIMER1_COMPA_vect)
|
15 | {
|
16 | counter_Timer1++;
|
17 | if (counter_Timer1 >= 400)
|
18 | {
|
19 | TOGGLE_PIN(1, PORTB);
|
20 | counter_Timer1 = 0;
|
21 | }
|
22 | }
|
23 |
|
24 | int main(void){
|
25 |
|
26 | DDRB = 0xFF;
|
27 |
|
28 |
|
29 | Timer1_Init();
|
30 | Timer0_Init();
|
31 | sei();
|
32 |
|
33 | while(1);
|
34 |
|
35 | return 0;
|
36 | }
|
Und hier meine Timer Inits:
1 | void Timer0_Init()
|
2 | {
|
3 |
|
4 | /* Compare Interrupt für Timer 0 aktivieren */
|
5 | TIMSK |= (1 << OCIE0);
|
6 |
|
7 | /* laden mit 250 */
|
8 | OCR0 = 0xFA;
|
9 |
|
10 | /* Prescaler 64 */
|
11 | TCCR0 = (1<<CS01) | (1<<CS00) | (1<<WGM01);
|
12 | }
|
1 | void Timer1_Init()
|
2 | {
|
3 |
|
4 | /* Compare Interrupt A für Timer 1 aktivieren */
|
5 | TIMSK |= (1 << OCIE1A);
|
6 |
|
7 | /* laden mit 5000 */
|
8 | OCR1A = 0x1388;
|
9 |
|
10 | /* Prescaler 8 und Moduswahl */
|
11 | TCCR1A = (0 << WGM11) | (0 << WGM10);
|
12 | TCCR1B = (0 << CS12) | (1 << CS11) | (0 << CS10);
|
13 | TCCR1B |= (0 << WGM13) | (1 << WGM12);
|
14 | }
|
Kann da jemand vielleicht drüberschaun? Wahrscheinlich was ganz
triviales...
Viele Grüße!