/********************************************************************* Frequenzzähler (Berich: 1Hz bis etwa theor. 8MHz). Mit Vorteiler einfach erweiterbar für höhere Messfrequenzen Dieses Programm stellt die am T0 Eingang (PD4) eines Atmega8 (16Mhz) anliegende Frequenz (TTL Pegel Rechteck) auf einem LCD Hz-genau dar. Weiterhin gibt es die Möglichkeit eines Abgleiches der Frequenz mittels Korrekturfaktor bei Bedarf wegen der unvermeidlichen "Quarz-Schwingfrequenzabweichung"). Die Abweichungen sind ohne Abgleich innerhalb 0,03% Bereich (linear) bei annähernd konstanter Raumtemperatur. Für normale Zwecke völlig ausreichend. Zum Abgleich wird die Variable "korrekturfaktor" anpasst. d.h. es wird eine bekannte, stabile Frequenz (Rechteck, TTL - sollte mindestens 10Khz, besser 1Mhz sein) angelegt und der angezeite Wert ermittelt. Anschließend wird der wahre Wert durch den angezeigten Wert geteilt und sinnvoll auf 5 oder 6 Stellen nach dem Komma gerundent. z.b. 100000Hz/100026Hz=0.99974 Dieser Wert wird dann der Variable "korrekturfaktor" zugeteilt. Genauigkeit nach Abgleich 1Hz genau. Zumindestens bei meinen Referenzmessungen. Viel Spass damit! Swen *********************************************************************/ #include #include "lcd-routines.h" #include "avr/interrupt.h" int count = 0, a = 0; float korrekturfaktor = 1; //hier anpassen für Abgleich (z.b 0.99974) int ztmp = 0; unsigned long freq = 0; char anz[20]; volatile int s=0; volatile unsigned short z=0; /***************************************************************** Funktion für Unwandlung Unsigned Long to Char (Für LCD Ausgabe) ******************************************************************/ void uLongtoChar(unsigned long u,char* Buffer) { int i = 0; int j; char tmp; // die einzelnen Stellen der Zahl berechnen do { Buffer[i++] = '0' + u % 10; // = String "0" (=48) + Rest von u/10 u = u/10; } while( u > 0 ); // den String in sich spiegeln (d.h. Reihenfolge umkehren) for( j = 0; j < i / 2; ++j ) { tmp = Buffer[j]; Buffer[j] = Buffer[i-j-1]; Buffer[i-j-1] = tmp; } Buffer[i] = '\0'; } /********************************* Timer 0 und 2 Interruptroutinen **********************************/ ISR(TIMER2_COMP_vect) // Löst aus alle (16Mhz/1024/125) 8ms { s++; } ISR(TIMER0_OVF_vect) // Eingangsignal Overflow Zähler Timer 0 { z++; TIFR = (1< 125) TIMSK |= (1<Fließkommazahl zu Ganzzahl - "korrekturfaktor" ist die SW-Korrektur zur Kompensation der lin.Quarzungenauigkeit **********************************************************************************/ uLongtoChar(freq,anz); // Unwandlung Long zu String für Displayausgabe set_cursor (0,1); // Cursor Pos setzen lcd_string( anz ); // Anzeige der ermittelten Frequenz set_cursor (8,1); // Cursor Pos setzen lcd_string( "Hz" ); // Anzeige Hz } } return 0; }