1 | #ifndef F_CPU
|
2 | #define F_CPU 8000000
|
3 | #endif
|
4 |
|
5 | #include <avr/io.h>
|
6 | #include <avr/interrupt.h>
|
7 | #include <avr/delay.h>
|
8 |
|
9 | #include <stdlib.h>
|
10 | #include "lcd.h"
|
11 |
|
12 | #ifndef TRUE
|
13 | #define TRUE 1
|
14 | #define FALSE 0
|
15 | #endif
|
16 |
|
17 | volatile unsigned char NrOverflows = 0; // Anzahl der Timer Overflows die während der Messung passiert sind
|
18 | volatile unsigned int StartTime = 0; // ICR-Wert bei der 1.High-Flanke speichern
|
19 | volatile unsigned int EndTime = 0; // ICR-Wert bei der 2.High-Flanke speichern
|
20 | volatile unsigned char UpdateDisplay; // Job Flag
|
21 |
|
22 | //#define LCD_LINE1 0x00 // Position an der das ERgebnis der Frequenzmessung ausgegeben wird
|
23 |
|
24 | ISR( TIMER1_CAPT_vect )
|
25 | {
|
26 | static unsigned char ErsteFlanke = TRUE;
|
27 |
|
28 | if (UpdateDisplay) // das Display wurde mit den Ergebnissen der vorhergehenden Messung
|
29 | return; // noch nicht upgedatet. Die nächste Messung verzögern, bis der Start
|
30 | // und EndTime Variablen wieder gefahrlos beschrieben werden können.
|
31 |
|
32 | // Bei der ersten Flanke beginnt die Messung, es wird der momentane
|
33 | // Timer beim Input Capture als Startwert gesichert
|
34 | //
|
35 |
|
36 | if ( ErsteFlanke )
|
37 | {
|
38 | StartTime = ICR1;
|
39 | NrOverflows = 0;
|
40 | ErsteFlanke = FALSE; // Die nächste Flanke ist das Ende der Messung
|
41 | }
|
42 |
|
43 | // das ist die zweite Flankte im Messzyklus. Die Messung wird gestoppt
|
44 |
|
45 | else
|
46 | {
|
47 | EndTime = ICR1;
|
48 | UpdateDisplay = TRUE; // Eine vollständige Messung. Sie kann ausgewertet werden
|
49 | ErsteFlanke = TRUE; // Bei der naechsten Flanke beginnt der nächste Messzyklus
|
50 | }
|
51 | }
|
52 |
|
53 | ISR( TIMER1_OVF_vect )
|
54 | {
|
55 | NrOverflows++;
|
56 | }
|
57 |
|
58 | int main()
|
59 | {
|
60 | char lcdCounterString[8];
|
61 | double Erg = 0.0;
|
62 |
|
63 | lcd_clrscr();
|
64 |
|
65 | TCCR1B = (1<<ICES1) | (1<<CS10); // Input Capture Edge, kein PreScale
|
66 | TIMSK = (1<<TICIE1) | (1<<TOIE1); // Interrupts akivieren, Capture + Overflow
|
67 |
|
68 | sei();
|
69 |
|
70 | while(1)
|
71 | {
|
72 | if( UpdateDisplay ) // liegt eine vollständige Messung vor?
|
73 | {
|
74 | // Berechnung der Zeitdauer zwischen den Takten
|
75 | // EndTime und StartTime sind unsigned darum braucht kann EndTime auf
|
76 | // kleiner sein als StartTime, nur Overflows müssen berücksichtigt werden
|
77 |
|
78 |
|
79 | Erg = ( NrOverflows * 65536 ) + EndTime - StartTime; // ausrechnen der Takte
|
80 |
|
81 | // aufbereiten fürs Display
|
82 |
|
83 | Erg = F_CPU / Erg; // f=1/t Signalfrequenz
|
84 |
|
85 | itoa(Erg, lcdCounterString, 8);
|
86 |
|
87 | //dtostrf( Erg, 5, 3, lcdCounterString ); // 3 Nachkommastellen
|
88 | // ausgeben
|
89 | lcd_clrscr();
|
90 | lcd_gotoxy ( 0,0 );
|
91 | lcd_puts (lcdCounterString);
|
92 |
|
93 | UpdateDisplay = FALSE; // nächste Messung kann Starten
|
94 | }
|
95 | }
|
96 | }
|