1 | #include <stdint.h>
|
2 | #include <avr/io.h>
|
3 | #include <avr/interrupt.h>
|
4 | #include <inttypes.h>
|
5 |
|
6 | #ifndef F_CPU
|
7 | #define F_CPU 8000000UL // processor clock frequency 8Mhz
|
8 | #endif
|
9 |
|
10 | #define PrescalerTC1 64
|
11 |
|
12 | #define Input PB0 //Pin des Input Captures PB0=ICP
|
13 | #define LED PB1
|
14 | #define LED1 PB2
|
15 |
|
16 |
|
17 | #ifndef TRUE
|
18 | #define TRUE 1
|
19 | #define FALSE 0
|
20 | #endif
|
21 |
|
22 | // ----------------------------------------------------------------------------
|
23 | // Variabeln Interrupt
|
24 | // ----------------------------------------------------------------------------
|
25 | volatile unsigned char NrOverflowsTC1 = 0; //Overflows TC1
|
26 |
|
27 | volatile unsigned int StartZeit= 0; // Wert 1.Flanke
|
28 | volatile unsigned int EndZeit = 0; // Wert 2. Flanke
|
29 | volatile double Gesamtzeit = 0.0; // enthält die Gesamtzeit in Taktzyklen
|
30 | volatile unsigned char Grenze=50; // Grenzfrequenz
|
31 | volatile unsigned long Frequenz=0; // enthält die Frequenz
|
32 | volatile unsigned char NrOverflowsCompareTC1 = 0; // Anzahl Overflows bis zum Compare Match A
|
33 |
|
34 |
|
35 | ISR( TIMER1_CAPT_vect ){
|
36 | /*hier erfolgt zuvor eine Frequenzberechnung
|
37 | Programm wurde gekürzt
|
38 | */
|
39 | Gesamtzeit = (NrOverflowsTC1 * 65536) + Endzeit - StartZeit ;//Zeit in Taktzyklen
|
40 | Frequenz = (F_CPU/PrescalerTC1)/Gesamtzeit; // Zeit in Hz
|
41 | if (Frequenz>=Grenze){
|
42 | Gesamtzeit = Gesamtzeit/2; // halbe Zeit in Taktzyklen
|
43 | NrOverflowsCompareTC1 = Gesamtzeit/65536; // Anzahl overflows (ganzzahlig, da char, Overflows sind immer kleiner als 256)
|
44 | OCR1A = TCNT1+Gesamtzeit; // Compare Match Register, Anzahl OVF bereits berücksichtigt
|
45 | // da unsigned gerechnet wird, spielen Überläufe keine Rolle, es kommt der richtige Wert heraus
|
46 | TIMSK |= (1 << OCIE1A); // Compare Match Interrupt aktivieren
|
47 | PORTB &= ~(1 << LED1); // LED anschlaten
|
48 | }
|
49 |
|
50 | ISR (TIMER1_OVF_vect){
|
51 | NrOverflowsTC1++; // Overflows zur Frequenzmessung
|
52 | if (NrOverflowsCompareTC1){ // wenn TRUE und damit ungleich 0
|
53 | NrOverflowsCompareTC1--; // NrOverflowsCompareTC1 dekrementieren bis es 0 --> dann wird erst Aufgabe im Compare Match ausgeführt
|
54 | }
|
55 |
|
56 | }
|
57 |
|
58 | ISR (TIMER1_COMPA_vect){
|
59 | if (!NrOverflowsCompareTC1){ // wenn Wert !FALSE und damit gleich 0
|
60 | TIMSK &= ~(1 << OCIE1A); // Compare Match Interrupt deaktivieren (wird erst wieder in ISR ICP aktiviert, wenn nötig)
|
61 | PORTB |= (1 << LED1); // LED ausschalten
|
62 | }
|
63 | }
|
64 |
|
65 | //Hauptprogramm
|
66 | int main()
|
67 | {
|
68 |
|
69 | DDRB = 0x00; //alle Eingang
|
70 | DDRB |= (1 << DDB1) | (1 << DDB2); //PB2 Ausgang(LED)
|
71 | PORTB |= (1 << Input) | (1 << LED1); //Pullup Input Capture, LED ausschalten
|
72 |
|
73 | TCCR1B = (1 << CS00) | (1 << CS01) | (1 << ICNC1); // Prescaler 64, Noise Cancellor
|
74 | TCCR1B &= ~(1<<ICES1); // IC fallende Flanke
|
75 | TIMSK = (1<<TICIE1) | (1<<TOIE1); // IC, Timer OVF enable
|
76 | TCCR1A &= ~ ((1 << COM1A0) | (1 << COM1A1)); // Timer1 16-bit Compare Match eingestellt
|
77 |
|
78 |
|
79 | while(1){
|
80 |
|
81 | if (NrOverflowsTC1 >= 250){ //sichert, dass der Datentyp char des OverflowTC1 nicht überläuft
|
82 | NrOverflowsTC1 = 0;
|
83 | }
|
84 | }
|
85 | }
|