1 | // ----------------------------------------------------------------------------
|
2 | // INCLUDES
|
3 | // ----------------------------------------------------------------------------
|
4 |
|
5 | #include <stdint.h> // Standard Int-Datentypen
|
6 | #include <avr/io.h> // avr Header File für IO Ports
|
7 | #include <avr/interrupt.h> // Interrupt Vektoren
|
8 | #include <inttypes.h> // Makros für int Datentypen
|
9 |
|
10 |
|
11 | // ----------------------------------------------------------------------------
|
12 | // DEFINES
|
13 | // ----------------------------------------------------------------------------
|
14 | #ifndef F_CPU
|
15 | #define F_CPU 8000000UL // processor clock frequency 8Mhz
|
16 | #endif
|
17 |
|
18 | // Pin Defines
|
19 | #define LED1 PB4 // rote LED1
|
20 | #define TAKTGEBER PB7 // Taktgeber
|
21 |
|
22 | #define LED2 PC0 // rote LED2
|
23 |
|
24 | // Port Defines
|
25 | #define PORTLED1 PORTB
|
26 | #define PORTLED2 PORTC
|
27 |
|
28 | // Initialisierungsfunktionen
|
29 | void init_ports(void);
|
30 | void init_timer1(void);
|
31 |
|
32 |
|
33 |
|
34 | //Timer1 16-bit Input Capture Service Routine
|
35 | ISR (TIMER1_CAPT_vect){
|
36 | if ( !(TCCR1B & (1<<ICES1) )){ // Interrupt bei fallender Flanke
|
37 | // LED anschalten
|
38 | PORTLED2 &= ~(1 << LED2);
|
39 | }
|
40 | else{
|
41 | // LED ausschalten
|
42 | PORTLED2 |= (1 << LED2);
|
43 | }
|
44 | TCCR1B ^= ( 1 << ICES1 );
|
45 | TIFR = ( 1 << ICF1 );
|
46 | }
|
47 |
|
48 |
|
49 | //Timer1 16-bit Compare Match B Interrupt Service Routine
|
50 | ISR (TIMER1_COMPB_vect){
|
51 | // Aufruf 280x pro Sekunde --> 140Hz
|
52 | PORTB ^= (1 << TAKTGEBER);
|
53 | PORTLED1 ^= ( 1 << LED1 ); // Referenz-LED für Taktanzeige
|
54 |
|
55 | OCR1B = OCR1B+((F_CPU/8000000UL)*28571);
|
56 |
|
57 | }
|
58 |
|
59 | int main(void)
|
60 | {
|
61 |
|
62 | init_ports();
|
63 | init_timer1();
|
64 |
|
65 |
|
66 | while (1){
|
67 |
|
68 | } // Ende main loop
|
69 | } // Ende Hauptprogramm
|
70 |
|
71 |
|
72 |
|
73 | void init_ports(void) {
|
74 |
|
75 |
|
76 | DDRB = 0x00;
|
77 | DDRB |= (1 << DDB4) | (1 < DDB7) ; // LED und Taktgeber als Ausgänge
|
78 | PORTB |= (1 << PB0) | (1 << PB1) | (1 << PB2) | (1 << PB3) | (1 << PB4) | (1 << PB6) | (1 << PB7); // Pullup am ICP (PB0 ein)
|
79 |
|
80 |
|
81 | DDRC = 0x00;
|
82 | DDRC |= (1 << PC0); // LED2 als Ausgang
|
83 | PORTC |= (1 << PC1) | (1 << PC2) | (1 << PC3) | (1 << PC4) | (1 << PC5);
|
84 |
|
85 |
|
86 | DDRD = 0x00;
|
87 | PORTD |= (1 << PD1) | (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5) | (1 << PD6) | (1 << PD7) ;
|
88 |
|
89 | sei(); // setzt globales Interrupt enable
|
90 |
|
91 | return;
|
92 | }
|
93 |
|
94 | void init_timer1(void) {
|
95 | OCR1B = ((F_CPU/8000000UL)*28571);
|
96 | TIMSK |= (1 << TICIE1) | (1 << OCIE1B); // Input Capture Interrupt enable, Compare Match B enable
|
97 | TCNT1 = 0; // Timer1 16-bit bei 0 starten
|
98 | TCCR1B |= (1 << CS10); // kein Prescaler, Timer1 läuft maximal durch für höchste Auflösung
|
99 | return;
|
100 | }
|