1 | /* Definition Taktfrequenz */
|
2 | #ifndef F_CPU
|
3 | #define F_CPU 16000000UL
|
4 | #endif
|
5 |
|
6 | /* Einbinden von Headerdateien */
|
7 | #include <avr/io.h>
|
8 | #include <avr/interrupt.h>
|
9 | #include <avr/sleep.h>
|
10 | #include <stdio.h>
|
11 | #include <stdint.h>
|
12 |
|
13 | /* Definitionen */
|
14 | #define TOGGLE_LED (PORTB ^= (1 << PORTB5)) /* LED An/Aus per XOR-Operator */
|
15 |
|
16 | /* Variablendeklaration */
|
17 | volatile uint16_t timer_03_ms = 0 ; /* 16-bit Variable, um bis 1000 (1 Sekunde) zählen zu können */
|
18 |
|
19 | /* Deklaration der verwendeten Funktionen */
|
20 | void init_timer_03(void) ;
|
21 | void start_timer_03(void) ;
|
22 |
|
23 | /*
|
24 | INTERRUPTVEKTOREN:
|
25 | Configure Interrupt Vector Timer 3 - Compare A
|
26 | Flag OCF3A des TIFR3-Registers wird gesetzt, wenn OCR3A=16000 erreicht wird.
|
27 | Immer dann soll der Timer hochgezählt werden.
|
28 | Durch den Takt von 16MHz geschieht dies pro Sekunde 1000 Mal.
|
29 | Man erhält Millisekunden-Auflösung.
|
30 | */
|
31 | ISR(TIMER3_COMPA_vect)
|
32 | {
|
33 |
|
34 | timer_03_ms = timer_03_ms + 1 ; /* Timer um eine Millisekunde erhöhen */
|
35 |
|
36 | if (timer_03_ms == 1000) /* Nach 1 Sekunde */
|
37 | {
|
38 | TOGGLE_LED ; /* LED An/Aus per XOR-Operator */
|
39 | timer_03_ms = 0 ; /* Timer zurücksetzen */
|
40 | }
|
41 |
|
42 | }
|
43 |
|
44 | /* HAUPTFUNKTION */
|
45 | int main(void)
|
46 | {
|
47 |
|
48 | /* Hier soll Pin PB5 als Ausgang deklariert werden */
|
49 | DDRB |= (1 << DDB5) ;
|
50 |
|
51 | /*
|
52 | Initialisierung des Timers:
|
53 | */
|
54 | init_timer_03() ;
|
55 | start_timer_03() ;
|
56 |
|
57 | /*
|
58 | Enable Interrupts globally
|
59 | */
|
60 | sei() ;
|
61 |
|
62 | while(1)
|
63 | {
|
64 |
|
65 | SMCR |= (1 << SE) ; /* Enable Sleep Mode */
|
66 | set_sleep_mode(SLEEP_MODE_IDLE) ; /* Select Sleep Mode: Idle */
|
67 | sleep_mode() ; /* Enter Sleep Mode */
|
68 |
|
69 | }
|
70 |
|
71 | }
|
72 |
|
73 | void init_timer_03(void)
|
74 | {
|
75 |
|
76 | // Timer/Counter 3 Control Register A:
|
77 | // Select Normal Port Operation(i.e. Counter Mode), Output Compare Pins(COM1Xn) disconnected, Waveform Generation Mode = Normal Mode
|
78 | TCCR3A |= ( (0 << COM3A1) | (0 << COM3A0) | (0 << COM3B1) | (0 << COM3B0) | (0 << COM3C1) | (0 << COM3C0) | (0 << WGM31) | (0 << WGM30) ) ;
|
79 |
|
80 | // Timer/Counter 1 Control Register B:
|
81 | // Select CTC Mode, Clock is still deactivated -> Counter isn't started yet!
|
82 | TCCR3B |= ( (0 << ICNC3) | (0 << ICES3) | (0 << 5) | (0 << WGM33) | (1 << WGM32) | (0 << CS32) | (0 << CS31) | (0 << CS30) ) ;
|
83 |
|
84 | // Timer/Counter 1 Control Register C:
|
85 | // All non-mentioned bits in this register are unused by default
|
86 | // FOC3B and FOC3C don't exist in the register according to datasheet
|
87 | TCCR3C |= (0 << FOC3A) ;
|
88 |
|
89 | // Interrupt Mask Register TIMSK3
|
90 | // Enable Output Compare Match A Interrupt
|
91 | TIMSK3 |= ( (0 << ICIE3) | (0 << OCIE3C) | (0 << OCIE3B) | (1 << OCIE3A) | (0 << TOIE3) ) ;
|
92 |
|
93 | OCR3A = 0b0011111010000000 ; /* Setze das 16-bit Timer-Vergleichs-Register OCR3A auf 16000 */
|
94 |
|
95 | return;
|
96 |
|
97 | }
|
98 |
|
99 | void start_timer_03(void)
|
100 | {
|
101 |
|
102 | TCNT3 = 0 ;
|
103 |
|
104 | // Timer/Counter 3 COntrol Register B:
|
105 | // Select External clock(16 MHz Quarz-Oscillator), Clock on Rising Edge
|
106 | // Starting of clock should also start the timer(TCNT3)
|
107 | TCCR3B |= ( (1 << CS32) | (1 << CS31) | (1 << CS30) ) ;
|
108 |
|
109 | return ;
|
110 |
|
111 | }
|