Frequenzanzeige

Eine der wohl wichtigsten Funktionen eines Oszilloskops, neben der Anzeige der Kurve, ist die Messung der Frequenz. Um die Berechnung weniger kompliziert und ungenau zu gestallten, wird das Aufzeichnen der Eingangswerte durch den ADC über einen der 16Bit Timer gesteuert. Die Einstellmöglichkeiten für den Timer sind dabei in einem Array fest voreingestellt. Die einzelnen werte in dem Array entsprechen dabei gängigen Messstellen eines Laboroszilloskops.

Über die Einstellungen wissen wir nun, wie lang das Aufzeichnen eines Pixelwertes dauert.

Zur Berechnung der Frequenz benötigen wir weiterhin die Länge (in Pixeln) einer oder mehrerer Perioden der anliegenden Eingangsfunktion. Ursprünglich haben wir die Berechnung nur über das Ausmessen einer einzigen Periode laufen lassen. Allerdings stellte sich schnell heraus, dass dies sehr ungenau wurde, sobald die Periode nur noch wenige Pixel auf dem Display einnahm.

Die Messung der Periodenlänge erfolgt über die Triggerfunktion. Damit zählen wir die Durchgänge durch den Y-Triggerpunkt und speichern uns die letzte Position dieses Punktes.

Zur Berechnung am Ende können wir damit ausrechnen, wie groß (in Pixeln) eine Periode ist und können aus unserer Timereinstellung wiederum auf die Frequenz schließen.

Codebeispiel: Definition der Timersettings / Initialisierung

volatile char* sampleTimerVal[SAMPLESIZE] = {"  10s", "   5s", "   2s", "   1s", "500ms", "200ms" ... );
volatile long double sampleTimerS[SAMPLESIZE] =	{10, 5, 2, 1, .5, .2 ... };
volatile int sampleTimerOCR[SAMPLESIZE] = {31249, 15624, 24999, 12499, 6249 ... };
volatile int sampleTimer[SAMPLESIZE] = {0b00000100, 0b00000100, 0b00000011, 0b00000011, 0b00000011, 0b00000010 ... };
sbi(TIMSK,OCIE1A); // Timer1 Overflow Compare A
 
...
 
void sampleTimerInit(int intSampleSet)
{
	TCCR1B = 0x00; // Timer abschalten
	TCCR1A = 0x00; // Normal port opperation fuer den Compare Match, kein WGM 
	TCNT1 = 0x00; // Zaehler auf 0 zuruecksetzen
 
	OCR1A = sampleTimerOCR[intSampleSet]; // Compare Match Value einstellen
 
	// Timer mit prescaler einschalten + CTC fuer den OCR
	TCCR1B = 0x00 | 0b00001000 | sampleTimer[intSampleSet];
}

Codebeispiel: Berechnung der Frequenz

// Die Formel leitet sich ab aus der Formel zur Berechnung der f_osc
// f_osc = f_clkio / ( 2 * N * (1 + OCRnA))
// f_clkio = Clock
// N = Prescaler
// OCRnA = Overflow Compare Wert
 
long double frequence = (1 / (((sampleTimerS[sampleset]) / 10)
                        * (fabs(periodEnd - periodStart) / periodCount))) * 2;

Probleme

Die Frequenzanzeige kann aktuell nicht berücksichtigen, wenn eine Unterabtastung der Eingangswerte erfolgt und wird als Folge dessen einen falschen Frequenzbereich anzeigen. Als Hilfestellung, wo der µCompozzel eine Periode erfasst hat, wird diese Farblich hervorgehoben. Es ist für eine korrekte Anzeige wichtig, dass man die Periode gut auf dem Display erkennen kann.

authoring tool: counter
content: © 2012 Gerry Weißbach @ gammaproduction.de