Hi!
Also wenn du einen Timer starten willst, hab ich hier mal was für dich:
1 | #include <avr/interrupt.h>
|
2 | //#include <avr/math.h>
|
3 |
|
4 |
|
5 | #define MCU_FREQ 16000000
|
6 | #define SAMPLINGRATEHZ 300
|
7 | #define PRESCALER 8
|
8 | //1 Tick = 16e6 / 8 Prescaler => 2.000.000 Ticks pro Sekunde => 2.000.000/HERTZ = TimerTicks
|
9 | //(entspricht bei 300Hz 6666 Ticks = 0x1A0B) => Timer Offset muss auf 0xFFFF-0x1A0B gestellt werden
|
10 | // damit alle 0x1A0B Ticks ein Overflow entsteht
|
11 |
|
12 | int timer1Offset = 0xFFFF - (MCU_FREQ/(PRESCALER*SAMPLINGRATEHZ));
|
13 |
|
14 | void setup()
|
15 | {
|
16 | //Configure Timer 1
|
17 | PRR &= ~(1<<PRTIM1); //disable Power Reduction Timer 1 (PRTIM1);
|
18 | TCCR1A = 0x00; //Normal Mode
|
19 | TCNT1 = timer1Offset; //Setz den Timer auf den Startwert.
|
20 |
|
21 |
|
22 | if (1== PRESCALER) TCCR1B = 0b0000001; //Normal mode with prescaler 1
|
23 | if (8== PRESCALER) TCCR1B = 0b0000010; //Normal mode with prescaler 8
|
24 | if (64== PRESCALER) TCCR1B = 0b0000011; //Normal mode with prescaler 64
|
25 | if (256== PRESCALER) TCCR1B = 0b0000100; //Normal mode with prescaler 256
|
26 | if (1024== PRESCALER) TCCR1B = 0b0000101; //Normal mode with prescaler 1024
|
27 |
|
28 | TIMSK1 |= (1<<0); //Enable Overflow Interrupt
|
29 | sei(); //set_interrupts(), nicht sicher, ob man das auch noch braucht
|
30 |
|
31 | }
|
32 |
|
33 |
|
34 | //diese Funktion wird aufgerufen, wenn der Timer überlauft (TCNT1 == 0xFFFF)
|
35 | ISR (TIMER1_OVF_vect)
|
36 | {
|
37 | // ändere die wählnummer hier
|
38 |
|
39 | //reset des Timers auf den Startwert
|
40 | TCNT1 = timer1Offset;
|
41 | }
|
In diesem Beispiel wird der Timeroverflow 300 mal/sekunde aufgerufen.
Um auf einmal in 10 Sek. zu kommen müsstest du dein timer1Offset so
berechnen:
0xFFFF - ((MCU_FREQ/PRESCALER) * 10), was aber nicht geht weil selbst
bei Prescaler 1024 kommst du beim Klammernterm auf 156250, was keine
16bit Zahl mehr ist!
Daher kannst du nur zb. 0xFFFF - ((MCU_FREQ/PRESCALER) * 2) ausrechnen,
also bei 1024 Prescaler 0xFFFF - 0x7A12 = 0x85ED.
Dann wird die Interruptroutine alle 2 Sekunden aufgerufen.
Die musst du dann so ändern, dass der Code nur jedes 5te mal ausgeführt
wird:
1 | int i = 0;
|
2 | ISR (TIMER1_OVF_vect)
|
3 | {
|
4 | i++;
|
5 | if (i>5)
|
6 | {
|
7 | // ändere die wählnummer hier
|
8 | i=0;
|
9 | }
|
10 |
|
11 | //reset des Timers auf den Startwert
|
12 | TCNT1 = timer1Offset;
|
13 | }
|
Ich hoffe das war verständlich und v.a. dass ich mich nicht verrechnet
hab.
Bitte zu bedenken, dass ich selbst auch noch Anfänger bin es geht sicher
noch besser/schöner, aber so sollte es funktionern.
Viel Glück!