Hallo, ich habe mir einen kleinen Timer geschrieben, der auf einem ATmega32 mit 16MHz laufen soll. Ich will die getTime() Funktion in verschiedenen Modulen nutzen können und deshalb nicht in die main schreiben. Ich würde auch gerne eine globale Variable vermeiden... Kennt die main den Interrupt und führt ihn aus? time.h/time.c:
1 | #ifndef TIME_H |
2 | #define TIME_H |
3 | |
4 | #include <stdint.h> |
5 | #include <avr/interrupt.h> |
6 | #include <avr/io.h> |
7 | |
8 | static volatile uint32_t theTime;//reicht für 4294 sekunden ~ 71 minuten |
9 | |
10 | uint32_t getTime() |
11 | { |
12 | //interrupts ausschalten |
13 | uint8_t tmp_sreg = SREG;//statusregister sichern |
14 | cli(); |
15 | |
16 | uint32_t time = theTime; |
17 | |
18 | //interruptstatus zurücksetzen |
19 | SREG = tmp_sreg; |
20 | return time; |
21 | } |
22 | |
23 | void incrementTime() |
24 | { |
25 | //interrupts ausschalten |
26 | uint8_t tmp_sreg = SREG;//statusregister sichern |
27 | cli(); |
28 | |
29 | theTime += 100; |
30 | |
31 | //interruptstatus zurücksetzen |
32 | SREG = tmp_sreg; |
33 | } |
34 | |
35 | void initTime() |
36 | { |
37 | ASSR &= ~(1<<AS2);//io clock benutzen |
38 | TCCR2 &= ~((1<<WGM21) | (1<<WGM20));//normaler modus |
39 | TCCR2 |= (1<<CS20);//prescaler auf 8 setzen |
40 | TCNT2 = 55;//preloader setzen -> 100 µs |
41 | TIMSK |= (1<<TOIE2);//timer overflow einschalten |
42 | sei();//interrupts aktivieren |
43 | } |
44 | |
45 | /* |
46 | * t = takt |
47 | * p = precaler |
48 | * oiv = overflowinitvalue |
49 | * ov = overflowvalue |
50 | * time = 1/((t/p)/(ov-oiv)) |
51 | * time = 1/((16000000/p)/(255-oiv)) |
52 | * |
53 | * ovi = ov-(t/p)*time |
54 | * ovi = 255-(16000000/8)*time |
55 | * ovi=55 wartet 100 µs |
56 | */ |
57 | ISR(TIMER2_OVF_vect) |
58 | { |
59 | TCNT2 = 55;//preloader setzen -> 100 µs |
60 | theTime += 100;//100 µs weiterzählen |
61 | } |
62 | |
63 | #endif |
main.c:
1 | int main() |
2 | { |
3 | initTime(); |
4 | ... |
5 | getTime(); |
6 | ... |
7 | } |