Forum: Mikrocontroller und Digitale Elektronik Frequenzzähler mit ATMega32


von A. M. (skugga87)


Lesenswert?

Hallo,

ich habe schon einige Fragen bezüglich der Frequenzzähler gestellt.

Jetzt habe ich ein funktionierendes Programm gebastelt. Leider habe ich 
einen Versatz von ca. 250 Hz. Irgendwie kann ich mir das nicht so ganz 
erklären. Das sieht so aus, als würde der Timer zu viel Zählen.

Ich finde den Fehler einfach nicht. Könnte es eventuell auch an den 
Datentypen liegen?

Ich nutze einen ATMega32 mit externem 16MHz Quarz.

Vielen Dank im Voraus!

1
#define F_CPU 16000000UL
2
#include <math.h>
3
#include <stdint.h>
4
#include <string.h>
5
#include <stdio.h>
6
#include <stdlib.h>
7
#include <inttypes.h>
8
9
#include <avr/io.h>
10
#include <avr/interrupt.h>
11
12
#include <util/delay.h>
13
14
volatile int mode, tick = 0;
15
volatile unsigned char count_overflows = 0;
16
17
volatile uint32_t freq = 0;     // 32-bit für Ergebnis
18
19
double korrekturwert = 0.999985750203;  // Korrekturwert ausgemessen mit externem 16MHz XO
20
21
/*** Timer Routinen ***/
22
ISR(TIMER0_COMP_vect)  // wird mit 125Hz  aufgerufen (16MHz/1024/125, alle 8ms)
23
  {  
24
    uint8_t pina_temp;    // Var. für PINA
25
    uint16_t counter_temp;  // Var. zur zwischenspeicherung Zählerstand
26
    
27
    pina_temp = PINA;    // PINA in Var. schreiben
28
    counter_temp = TCNT1;  // Zählerwert in Variable lesen
29
30
    tick++;
31
    if(tick == 125)
32
      {
33
        PORTB |= (1<<PB0);    // 74HC393 clear
34
        asm volatile ("NOP");
35
        asm volatile ("NOP");
36
        PORTB &= ~(1<<PB0);    // 74HC393 ursprünglich
37
        TCNT1 = 0;
38
          tick=0;
39
        
40
        // Frequenzregister bilden, mit Korrekturwert  
41
        freq = ( (((uint32_t)count_overflows)<<24) | (((uint32_t)counter_temp)<<8) | pina_temp);
42
43
        count_overflows = 0;  // Timer1 OVF rücksetzen
44
      }
45
    
46
  }
47
48
ISR(TIMER1_OVF_vect)
49
  {
50
    count_overflows++;    // Timer1 zählen lassen
51
  }
52
53
/*** Main mit Frequenzanzeige ***/
54
int main()
55
    {  
56
    //LED+LCD Ansteuerung PM-8
57
    DDRD=0b00001100;
58
    PORTD=0b11100000;
59
    DDRC|=0b00001100;
60
61
    DDRA = 0x00;    // Port A auf Eingang setzen und Prescaler auslesen
62
    uint8_t bPortA;    // Variable für Port A
63
    bPortA = PINA;    // Wird in Variable geschrieben
64
65
    DDRB = 0x00;       // Port B auf Eingang (für T1-Pin) und
66
    DDRB |= (1 << PB0);   // T0/XCK-Pin (PB0) auf Ausgang für 74HC393
67
68
    sei();
69
70
    initI2C();
71
    if(LCDInit()) 
72
        {
73
        Schreibelcd(0, 0, 8, "  Test  ");
74
        Schreibelcd(0, 1, 8, "  Test2 ");
75
          //_delay_ms(2000);
76
        }
77
78
    /*** Timerbits setzen ***/
79
    // Timer0: Fenster in dem gezählt wird
80
     TCCR0 |= (1<<CS02) | (1<<CS00) | (1<<WGM01);// Timer0 Prescaler 1024 und CTC Modus (S.82)
81
    OCR0 = 124;            // Ab Zählschritt 125 INT auslösen (S.70)
82
    TIMSK |= (1<<OCIE0);       // Erlaube Overflow Interrupt, Timer0 (S.83)
83
    // Timer1: Flanken zählen (ohne Prescaler)
84
    TCCR1B |= (1<<CS10) | (1<<CS11) | (1<<CS12); // Steigende Flanke auf T1 Pin (S.111)
85
    TIMSK |= (1<<TOIE1);  // Interrupt erlauben, Timer1 (S.112)
86
87
88
    while(1)
89
      {
90
        uint32_t freq_ausgabe = 0;
91
        
92
        freq_ausgabe = ((double)freq * korrekturwert );      
93
94
        char b[9]={((freq_ausgabe%100000000)/10000000)+48,((freq_ausgabe%10000000)/1000000)+48,((freq_ausgabe%1000000)/100000)+48,((freq_ausgabe%100000)/10000)+48 ,((freq_ausgabe%10000)/1000)+48,((freq_ausgabe%1000)/100)+48,((freq_ausgabe%100)/10)+48,(freq_ausgabe%10)+48};
95
        Schreibelcd(0,0,8,"Freq./Hz");  
96
        Schreibelcd(0,1,8,b);      // Frequenz ausgeben
97
      }
98
  
99
  }

von Karl H. (kbuchegg)


Lesenswert?

A. M. schrieb:
> Hallo,
>
> ich habe schon einige Fragen bezüglich der Frequenzzähler gestellt.
>
> Jetzt habe ich ein funktionierendes Programm gebastelt. Leider habe ich
> einen Versatz von ca. 250 Hz.

Festgestellt bei welcher zu messenden Frequenz?

> Irgendwie kann ich mir das nicht so ganz
> erklären. Das sieht so aus, als würde der Timer zu viel Zählen.
1
> double korrekturwert = 0.999985750203;  // Korrekturwert ausgemessen mit 
2
> externem 16MHz XO
3
> 
4
5
...
6
>         freq_ausgabe = ((double)freq * korrekturwert );

Korrekturwert?
Welcher Korrekturwert?

Wenn dein Timer in 1/125 tel Sekunde 48 Flanken sieht, dann sieht er 
auch 48 Flanken. Da braucht man nichts korrigieren.

Hast du dir mal überlegt, bei deiner Frequenz, wie weit dein angezeigter 
Messwert streuen wird, wenn sich der Timer um +-1 'verzählt'? Denn das 
kann leicht passieren, weil ja niemand sagt, dass die erste zu zählende 
Flanke genau dann daher kommt, wenn sich dein Messfenster (realisiert 
mit dem Timer 0) öffnet, bzw. umgekehrt sich das Fenster ja auch nicht 
exakt mit einer Flanke der zu messenden Frequenz schliesst.

von Karl H. (kbuchegg)


Lesenswert?

Hä?
1
ISR(TIMER0_COMP_vect)  // wird mit 125Hz  aufgerufen (16MHz/1024/125, alle 8ms)
2
  {  
3
...
4
    pina_temp = PINA;    // PINA in Var. schreiben
5
6
....
7
        // Frequenzregister bilden, mit Korrekturwert  
8
        freq = ( (((uint32_t)count_overflows)<<24) | (((uint32_t)counter_temp)<<8) | pina_temp);

du hängst da das komplette PINA Register drann?

Was ist da der tiefere Sinn dahinter?

von A. M. (skugga87)


Lesenswert?

Danke für die schnelle Antwort.

Karl Heinz schrieb:
>
> Korrekturwert?
> Welcher Korrekturwert?

Der Korrekturwert ist an sich nur eine kleine Eichung. Ich habe die 
Frequenz meines eigenen Quarzes gemessen und prozentual verrechnet. 
Damit soll nur die Ungenauigkeit des Quarzes etwas minimiert werden.

> Hast du dir mal überlegt, bei deiner Frequenz, wie weit dein angezeigter
> Messwert streuen wird, wenn sich der Timer um +-1 'verzählt'? Denn das
> kann leicht passieren, weil ja niemand sagt, dass die erste zu zählende
> Flanke genau dann daher kommt, wenn sich dein Messfenster (realisiert
> mit dem Timer 0) öffnet, bzw. umgekehrt sich das Fenster ja auch nicht
> exakt mit einer Flanke der zu messenden Frequenz schliesst.

Da habe ich mir noch gar keine Gedanken drüber gemacht, das stimmt wohl. 
Mir erschliesst sich nur nicht, wie ich das jetzt unterbinde, bzw. 
berücksichtige

von A. M. (skugga87)


Lesenswert?

> du hängst da das komplette PINA Register drann?
>
> Was ist da der tiefere Sinn dahinter?

Da habe ich einen 8-Bit-Zähler drangehängt um mir mit Timer1 ein 24-Bit 
Register zu ermöglichen

von Karl H. (kbuchegg)


Lesenswert?

Ich würde mal vorschlagen, dass du erst mal das Künsteln sein lässt und 
dir die festgestellten Werte direkt ausgeben lässt.

Wieviele Overflows, welches ist der Zählerstand.

Und dann vergleichst du mal mit deiner zu messenden Frequenz, ob die 
Werte plausibel sind, bzw. welche Werte nicht plausibel sind.

Und wenn die dann im Rahmen sind, DANN siehst du zu, dass du deine 
ganzen Korrekturen und Zusatzanbauten in Betrieb nimmst. Aber nicht 
alles auf einmal. Denn dann kann kein Mensch sagen, wo die Abweichungen 
her kommen.

: Bearbeitet durch User
von Peter R. (pnu)


Lesenswert?

Ist doch ein gutes Ergebnis, was Dein Zähler liefert, aaaber:


Einen "Messfehler" durch einen Korrekturfaktor zu beheben ist wohl 
ziemlich blauäugig, wenn man nicht weiß, ob es ein Offset ist 
(Addition/Subtraktion motwendig)oder ob er in skalarer Art entstanden 
ist (Korrekturfaktor sinnvoll).

Die 250Hz Meßfehler an 12MHz entsprechen etwa 22ppm.Das ist meiner 
Meinung nach sogar ein überraschend gutes Ergebnis. Alleine der 
Temperaturgang von einmal abgeglichenen Quarzoszilltoren bringt einen 
solchen Fehler.
Du weißt aber nicht, ob dieser Messfehler durch den Taktoszillator oder 
durch den zu messenden Takt erzeugt wird.

Es gibt weitere Gründe, weshalb man bei diesem Messverfahren keine 
besonders große Messgenauigkeit erreichen kann. Deshalb ist ein 
Korrektur von 22ppm einfach Unsinn.

Aus der Arbeitsweise des Kontrollers bei ints ergibt sich noch weitere 
Messungenauigkeit (stichwort int-latency). Oder wegen der Tatsache, dass 
die Schaltschwelle des Eingangs durch die vielen Störsignale innerhalb 
des Kontrollers irritiert werden.

Also sei zufrieden, dass die Messung wohl um mindestens 100 ppm ungenau 
ist, eine Korrektur ist so notwendig wie 10Megapixel bei einer 
Handy-Kamera.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Peter R. schrieb:

> Die 250Hz Meßfehler an 12MHz

Hab ich was übersehen?
Wo kommen die 12Mhz her?

von A. M. (skugga87)


Lesenswert?

Peter R. schrieb:

> Die 250Hz Meßfehler an 12MHz entsprechen etwa 22ppm.Das ist meiner
> Meinung nach sogar ein überraschend gutes Ergebnis. Alleine der
> Temperaturgang von einmal abgeglichenen Quarzoszilltoren bringt einen
> solchen Fehler.
> Du weißt aber nicht, ob dieser Messfehler durch den Taktoszillator oder
> durch den zu messenden Takt erzeugt wird.

Nunja, wären die 250Hz in höheren Frequenzbereichen, würde mich das 
nicht im geringsten stören. Das Problem ist, dass er ab ca. 1kHz anfängt 
IMMER 250 Hz versatz zu haben. Zumindest soweit man das beurteilen kann 
bei sehr hohen Frequenzen. Die 250Hz stehen. Sowohl ab 1kHz, als auch 
bei 100kHz. Was mich sehr irritiert.

von A. M. (skugga87)


Lesenswert?

Peter R. schrieb:

> Einen "Messfehler" durch einen Korrekturfaktor zu beheben ist wohl
> ziemlich blauäugig, wenn man nicht weiß, ob es ein Offset ist
> (Addition/Subtraktion motwendig)oder ob er in skalarer Art entstanden
> ist (Korrekturfaktor sinnvoll).

Das Problem ist, dass ich in der ISR messe. Ich bekomme da automatisch 
einen Versatz rein, weil es ja seine Zeit dauert bis die Routine 
aufgerufen wird und die Messschleife ausgeführt wird. Genau dagegen soll 
der Korrekturwert wirken.

von chris (Gast)


Lesenswert?

Als bsp mal drüber nachgedacht das du nur den timer für 1s frei gibst 
und über int0/1 die impulse zählst. Oder du machst eine 
impulslängenmessung sobald an int0/1 die flanke kommt wird der timer 
gestartet und gestoppt wenn die 3te flanke kommt.

von A. M. (skugga87)


Lesenswert?

Timer0 legt bei mir die Toröffnung fest (Momentan noch 1s). Timer1 zählt 
in diesem Fenster die auftretenden (steigenden) Flanken.



Habs nochmal genauer bestimmt.

Ab 128Hz zählt er nahezu immer 255Hz zuviel dazu. Ab und zu zählt er 
aber auch genau, verzählt sich aber wieder sobald Frequenz geändert 
wird. Ich finde den Fehler einfach nicht.

: Bearbeitet durch User
von Peter R. (pnu)


Lesenswert?

Ein Verfahren, das die durch int-Nutzung entstehende ungenaue 
Zeitverzögerung umgeht:

Mit einem der Timer ein zeitexaktes PWM-Signal erzeugen, das auf einem 
Pin ausgegeben wird. Das kann auch ohne int-Einsatz ablaufen.

Mit diesem Signal (Messintervall) ein externes Tor (UND-Gatter)steuern.

Das durch das geöffnete Tor kommende Signal mit einem andren Zähler 
zählen.

Nach der fallenden Flanke des Torsignals kann man mit pin-change-int die 
Auswertung beginnen: Lesen des Messergebnisses, Nullen des Zählers usw.

Anderer Weg:
Man kann auch mit input-capture-int arbeiten. Auch damit lässt sich die 
interrupt-latency vom Messvorgang fernhalten.

von Peter R. (pnu)


Lesenswert?

Karl Heinz schrieb:
> Hab ich was übersehen?
> Wo kommen die 12Mhz her?

tut mit leid, ich weiß auch nicht mehr, wie ich auf die 12 MHz gekommen 
bin.

von None (Gast)


Angehängte Dateien:

Lesenswert?

Peter R. schrieb:
> Anderer Weg:
> Man kann auch mit input-capture-int arbeiten.

Zur allgemeinen Info, siehe Anhang. Ganz gut beschrieben. Denke, das 
Peter R. dies meinte.

von A. M. (skugga87)


Lesenswert?

Peter R. schrieb:

> Anderer Weg:
> Man kann auch mit input-capture-int arbeiten. Auch damit lässt sich die
> interrupt-latency vom Messvorgang fernhalten.

Ich habe es darüber mal versucht. Ich lasse das Tor jetzt gemeinsam mit 
einer steigenden Flanke 1s lang offen per INT. Aber der Zähler zählt 
immer noch zu viel.

Der Moment in dem der ext. Prescaler gelöscht wird, verursacht sehr 
schmale Pulse bei verschiedenen Frequenzen, wie ich gerade mit dem Oszi 
gemessen habe. Ich nehme an diese Pulse werden mitgezählt. Wie kann ich 
sowas unterbinden?

: Bearbeitet durch User
von Ulrich (Gast)


Lesenswert?

Durch die Interrupts und Verzögerungen gibt es ggf. mehr oder weniger 
Zufällige Fehler. Das ist schon mal nicht wirklich gut. Auch hier kann 
man einiges besser machen und mit einigem Aufwand (extra Warten, 
Overflow ohne Interrupts behandeln (s.u.)) den Fehler vermeiden.
Ein weiteres Problem ist wenn das Ende der Messzeit mit dem Overflow von 
timer 1 zusammenfällt. Da fehlt dann ggf. ein Overflow und man erhält in 
seltenen Fällen ein ganz falsches Ergebnis. Immerhin sollte mit externen 
Vorteiler (256 ?) der Überlauf erst bei gut 16 MHz kommen. Man kann den 
Fall über die Flags abfangen, ist aber nicht ganz einfach.
Eine mögliche Fehlerquelle für einen Offset ist, wenn die falsche Flanke 
am HC393 zum µC geht. Da wird dann ggf. schon bei 128 gezählt.

Viele kurze ungewollte Pulse könnten durch eine schlechte Entkopplung, 
schlechte Masse oder zu lange (mehr also etwa 30 cm) Leitungen 
entstehen. Ohne mehr Info zur Hardware ist das aber schwer zu sagen.

Das klassische Zählverfahren ist aber ohnehin in der Regel (etwa 
Frequenz kleiner als µC Takt) die schlechtere Wahl gegenüber der 
reziproken Messung über den ICP Pin.

von A. M. (skugga87)


Lesenswert?

Ok, die oben genannten Probleme sind bewältigt. Nun stehe ich vor neuen 
Problemen:

Ich möchte die Genauigkeit in den unteren Frequenzen erhöhen, in dem ich 
zusätzlich das reziproke Verfahren nutze.

Jedoch möchte ich es so gestalten, dass von 0 bis ca. 10kHz das 
reziproke Verfahren greift, und ab 10kHz die Flankenzählung.

Gleichzeitig können diese Verfahren ja nicht messen. Wie kann ich sie zu 
und abschalten?

Hier mein Tor:
1
ISR(TIMER0_COMP_vect)  // wird mit 125Hz  aufgerufen (16MHz/1024/125, alle 8ms)
2
  {    
3
    //if(tick==0) PORTB |=0x80;  // Toggle-Test
4
    uint8_t pina_temp;      // Var. für PINA
5
    uint16_t counter_temp;    // Var. zur zwischenspeicherung Zählerstand
6
7
    pina_temp = PINA;      // PINA in Var. schreiben
8
    counter_temp = TCNT1;    // Zählerwert in Variable lesen    
9
10
    tick1++;
11
    if(tick1 == 125)        // Torzeit: 1s, Sekundenbasis (16MHz/1024/125/125=1Hz)
12
      {
13
        //PORTB ^=0x80;      // Test-Toggle
14
        PORTB |= (1<<PB0);    // 74HC393 clear
15
        asm volatile ("NOP");
16
        asm volatile ("NOP");
17
        PORTB &= ~(1<<PB0);    // 74HC393 ursprünglich
18
        TCNT1 = 0;        // Zählerwert rücksetzen
19
        tick1 = 0;        // Tick rücksetzen
20
        
21
        // Frequenzregister bilden, mit Korrekturwert  
22
        freq1 = ( (((uint32_t)count_overflows)<<24) | (((uint32_t)counter_temp)<<8) | (uint32_t)pina_temp);
23
24
        pina_temp = 0;      // Variable Port A rücksetzen
25
        counter_temp = 0;    // Variable Zählerstand rücksetzen
26
          count_overflows = 0;  // Timer1 OVF rücksetzen
27
28
        if(freq1 < 10000)    // Wenn Freq. unter 10kHz, dann
29
          {
30
            TIMSK &= ~(1<<TOIE1);  // OVF1 Int aus
31
            TCCR1B &= ~(1<<ICES1);  // fallende Flanke an ICP-Pin
32
            
33
          }
34
      }
35
  }

Und hier meine Versuche für das reziproke. Über den ICP möchte ich das 
Signal direkt abgreifen und messen:
1
ISR(TIMER1_CAPT_vect)
2
  { 
3
    if( UpdateJob )
4
        return;     
5
    
6
    static unsigned char ErsteFlanke = TRUE;            
7
    if( ErsteFlanke )
8
        {
9
        StartTime = ICR1;
10
          count_overflows = 0;
11
          ErsteFlanke = FALSE;
12
        }
13
    else
14
        {
15
          EndTime = ICR1;
16
        UpdateJob = TRUE;
17
          ErsteFlanke = TRUE;
18
        
19
      }
20
21
  }

Hierbei nutze ich den UpdateJob um in der Main dieses dann aufzurufen. 
Timer1 zählt derweil overflows.

Ich kann mir nicht richtig vorstellen wie ich das realisieren soll beide 
zu nutzen.

Hat eventuell jemand eine Idee?

: Bearbeitet durch User
von Ulrich (Gast)


Lesenswert?

Gleichzeitig braucht man die beiden verfahren auch nicht. Es muss halt 
der Timer anders konfiguriert werden: einmal extern zählen und einmal 
mit CPU Takt. Das Signal darf dabei parallel an T1 und ICP anliegen.

Beim Reziproken verfahren sollte man gleich die erweiterte Variante mit 
der Messung über mehrere Perioden machen: Es wird also nicht nur die 
Zeit für eine Periode gemessen, sondern die Zeit für N Perioden, wobei N 
so gewählt wird das etwa die gewünschte Zeit (z.B. 0,5 s) genutzt wird. 
Die Zahl der Periode wird dabei in Software gezählt, bis die Zeit 
erreicht ist.

Damit hat man unabhängig von der Frequenz eine hohe Auflösung (Messzeit 
/ CPU Takt), besser als es mit dem direkten Zählen (ohne auslesbaren 
externen Zähler) gehen kann. Die obere Frequenzgrenze liegt je nach 
Software bei etwa 50-500 kHz (AVR mit 10-20 MHz Takt).
Für höhere Frequenzen reicht ein einfacher zuschaltbarer Vorteiler (etwa 
1:512). Das reicht dann um in 2 Bereichen bis etwa 100 MHz (oder was der 
Teiler verträgt, etwa 50 MHz mit 74HC...) zu messen. Die klassische 
Zählmethode braucht man dann gar nicht mehr.

Im Prinzip kommt das mit der Messung schon so etwa hin. Es gibt aber 
noch eine kleine Tücke bei der Zählung der Overflows. Dazu gibt es aber 
schon genügend Threads. Die Erweiterung um nicht nur eine Periode zu 
messen, sollte nicht so schwer fallen.

von A. M. (skugga87)


Lesenswert?

Erstmal vielen Dank für die schnelle Antwort.

Das Problem seh ich nicht in den Auflösungen. Mein Problem ist in erster 
Linie, dass ich sehr wenig Erfahrung in C und AVR habe. Deshalb fallen 
mir hier einige Sachen sehr schwer, was viele als "schnell gemacht und 
einfach" abtun.

Ich kann mir nicht so ganz vorstellen wie ich die Timerkonfiguration 
jetzt speziell erweiter um beides nutzen zu können.

von Karl H. (kbuchegg)


Lesenswert?

A. M. schrieb:

> Ich kann mir nicht so ganz vorstellen wie ich die Timerkonfiguration
> jetzt speziell erweiter um beides nutzen zu können.

Gar nicht.

Du hast bzw. kennst die Konfiguration in dem einen Fall.
Und du hast bzw. kennst die Konfiguration im anderen Fall.

Wenn dein Frequenzmesser umschaltet, dann konfiguriert er den Timer 
einfach um.

Ja, stimmt schon. Im Normalfall konfiguriert man die Hadware einmalig 
beim Programmstart. Aber das ist kein Gesetz. Wenn man es benötigt und 
wenn es sinnvoll ist, dann darf man durchaus auch im laufenden Betrieb 
die Konfiguration ändern. Einfach die Register komplett neu beschreiben 
und gut ists. Ok, die Interrupts sollt man vorher ausschalten und nach 
der Neukonfigration wieder einschalten. Auch wäre ein Löschen der in der 
Zwischenzeit möglicherweise aufgelaufenen Interrupt Flags eine gute 
Idee. Aber im Prinzip spricht nichts dagegen, dass im laufenden Betrieb 
zu machen. Der µC hat da mit Sicherheit nichts dagegen.

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

A. M. schrieb:
> Ich möchte die Genauigkeit in den unteren Frequenzen erhöhen, in dem ich
> zusätzlich das reziproke Verfahren nutze.
>
> Jedoch möchte ich es so gestalten, dass von 0 bis ca. 10kHz das
> reziproke Verfahren greift, und ab 10kHz die Flankenzählung.

Warum?

> Gleichzeitig können diese Verfahren ja nicht messen. Wie kann ich sie zu
> und abschalten?

Gar nicht. Miß einfach immer nach dem Reziprokverfahren. Das ist ja das 
schöne an diesem Verfahren, daß man damit den kompletten Meßbereich 
abdecken kann bei konstanter Auflösung.


XL

von A. M. (skugga87)


Lesenswert?

Axel Schwenke schrieb:
> A. M. schrieb:
>> Ich möchte die Genauigkeit in den unteren Frequenzen erhöhen, in dem ich
>> zusätzlich das reziproke Verfahren nutze.
>>
>> Jedoch möchte ich es so gestalten, dass von 0 bis ca. 10kHz das
>> reziproke Verfahren greift, und ab 10kHz die Flankenzählung.
>
> Warum?

Nun, um die Genauigkeit in hohen Bereichen zu haben, aber eben durch das 
reziproke auch in den unteren Bereichen.

>
>> Gleichzeitig können diese Verfahren ja nicht messen. Wie kann ich sie zu
>> und abschalten?
>
> Gar nicht. Miß einfach immer nach dem Reziprokverfahren. Das ist ja das
> schöne an diesem Verfahren, daß man damit den kompletten Meßbereich
> abdecken kann bei konstanter Auflösung.
>
>
> XL

Momentan kann ich bis 50MHz "relativ" genau messen. Also meine 
Abweichungen liegen bei den ~50ppm meines Quarzoszillators. Also alles 
ausreichend. Aber eben die unteren Bereiche sind miserabel, wegen 
falschem Messverfahren.

Auf Grund der guten Genauigkeit und der Tatsache nach, dass es 
hervorragend funktioniert, würde ich das gerne beibehalten.

von Ulrich (Gast)


Lesenswert?

Das Reziproke Verfahren geht auch bei den höheren Frequenzen - fast 
immer besser als das direkte Zählen. Erst wenn die Frequenz höher als 
der CPU-Takt ist und man einen externen, auslesbaren Zähler davor hat, 
geht es direkt etwas besser. Aber schon im Bereich 200 kHz - 16 MHz ist 
es reziprok besser - allerdings geht da nicht direkt sondern mit 
Vorteiler. Das wären dann schon 3 Verfahren je nach Frequenz. Wobei das 
direkte die kleinsten Bereich (etwa 16 MHz - 50 MHz) abdeckt, und dann 
auch noch mit nur minimalem Vorteil.

Bei der Umsetzung wie oben sind da aber wohl immer noch deutliche Fehler 
bei der Torzeit drin. Es ist also wirklich die Frage ob es sich lohnt 
das klassische Verfahren noch umzusetzen - die jetzige Form bringt noch 
keinen Vorteil. Man kann es umsetzen, der Mega32 hat reichlich Platz 
dafür - das direkte Zählen ist aber das eher unwichtigste Verfahren.

Eine passende Softwarevorlage findet man z.B. hier:
http://www.mino-elektronik.de/index.html

von W.S. (Gast)


Lesenswert?

Ulrich schrieb:
> Das Reziproke Verfahren geht auch bei den höheren Frequenzen - fast
> immer besser als das direkte Zählen.

Das ist Quatsch. Ob reziprok oder nicht reziprok ist eigentlich für die 
Durchführung völlig egal. Es unterscheiden sich die beiden Varianten ja 
nur dadurch, daß Input und Referenz gegeneinander ausgetauscht werden. 
Also beim einen wird das Meßtor vom Inputsignal geöffnet und geschlossen 
und beim anderen vom Referenzsignal. Für die eigentliche Zählerei der 
beiden Signale ist das völlig egal.

Richtig hingegen ist, daß das Reziprokverfahren genau dann mehr 
Auflösung bringt, wenn die Eingangsfrequenz geringer ist als die 
effektive Referenzfrequenz. Ist die Eingangsfrequenz jedoch höher als 
die Referenz, dann ist der Geradeauszähler dem Reziprokzähler überlegen.

Tja, viel heiße Luft - und das alles bloß, weil sich die grandiosen 
Erfinder scheuen, vor ihren µC einige wenige TTL-IC's zu setzen um das 
Ganze einfach und richtig zu machen: zwei Bustreiber, ein Doppel-Zähler, 
ein simples D-Flipflop.

Nochwas: Wo bleibt bei all den Programmier-Kunststücken eigentlich der 
Eingangsteil, also das nötige Stück Analogelektronik?

W.S.

von Axel S. (a-za-z0-9)


Lesenswert?

W.S. schrieb:
> Ulrich schrieb:
>> Das Reziproke Verfahren geht auch bei den höheren Frequenzen - fast
>> immer besser als das direkte Zählen.
>
> Das ist Quatsch. Ob reziprok oder nicht reziprok ist eigentlich für die
> Durchführung völlig egal. Es unterscheiden sich die beiden Varianten ja
> nur dadurch, daß Input und Referenz gegeneinander ausgetauscht werden.

Nein.

> Also beim einen wird das Meßtor vom Inputsignal geöffnet und geschlossen
> und beim anderen vom Referenzsignal.

Das wäre der Unterschied zwischen Frequenz- und Periodendauermessung.

Das Kennzeichen des Reziprokzählers ist, daß es zwei Zähler gibt. 
Einen für das Meßsignal und einen für die Referenzfrequenz. Beide Zähler 
werden mit dem gleichen Torsignal gesteuert und das Tor öffnet und 
schließt synchron mit dem Meßsignal. So lange die Meßfrequenz geringer 
ist als die Referenzfrequenz, ergibt sich so der kleinstmögliche 
systematische Fehler.

Wenn man möchte, kann man die Reziprokmessung als Messung der Dauer von 
N aufeinanderfolgenden Perioden der Meßfrequenz ansehen, wobei N 
automatisch passend zum Eingangssignal gewählt wird. [1]

Die Auflösung der Messung ist bei diesem Verfahren proportional zum 
Produkt aus Torzeit und Referenzfrequenz. Insbesondere ist sie 
unabhängig von der Meßfrequenz. Und weil man aus dem o.g. Grund die 
Referenzfrequenz möglichst hoch wählen wird, ist es auch OK wenn man 
annimmt daß fref > fx. Dazu kommt noch, daß man für sehr hohe 
Eingangsfrequenzen einen Vorteiler verwenden kann/darf. Spätestens nach 
dem Vorteiler ist die Frequenz dann typischerweise geringer als fref.


XL

[1] die Wahl von N ist ganz simpel und erfolgt indirekt. Nach dem Öffnen 
des Tores wartet man einfach, bis man genug [2] Impulse im Referenz- 
zähler hat und schließt dann mit der nächsten Flanke von fx das Tor.

[2] wieviel genug ist, hängt von der gewünschten Auflösung ab. Für M 
Stellen braucht man mindestens 10^M Impulse.

von Axel S. (a-za-z0-9)


Lesenswert?

Alle Unklarheiten bezüglich der Meßverfahren sollte dieser Artikel 
beseitigen: Frequenzzählermodul: Messverfahren

Ich wollte das schon ewig aufschreiben und hab es jetzt endlich getan :)


HTH, XL

von m.n. (Gast)


Lesenswert?

Axel Schwenke schrieb:
> Alle Unklarheiten bezüglich der Meßverfahren sollte dieser Artikel
> beseitigen: Frequenzzählermodul: Messverfahren

Leider wird hier ein veraltetes Verfahren beschrieben, welches schon vor 
über 30 Jahren angewendet wurde. Zum Beispiel: 
http://www.mino-elektronik.de/Archiv/Elektronik25_1984.pdf

Des Messen mit 'Toren' hat den Nachteil, dass die Messungen nicht 
kontinuierlich sondern lückend ausgeführt werden. Bei Eingangsfrequenzen 
von 1Hz wird nur jede 2. Periode gemessen, weshalb man jeweils 2 
Sekunden auf ein neues Ergebnis warten muß.
Schon eine einfache Schlagfrequenzmessung (EKG, Puls) kann damit nicht 
mehr durchgeführt werden.

Wenn man lückenlos messen will, dürfen keine 'Tore' verwendet werden, 
die auch immer wieder geschlossen werden.
Vielmehr läßt man die Zähler für Signal- und Referenzfrequenz frei 
durchlaufen und holt sich synchron zum Eingangssignal die aktuellen 
Zählerstände und berechnet daraus die eff. Frequenz des letzten 
Intervalls.

von Peter D. (peda)


Lesenswert?

m.n. schrieb:
> Vielmehr läßt man die Zähler für Signal- und Referenzfrequenz frei
> durchlaufen und holt sich synchron zum Eingangssignal die aktuellen
> Zählerstände und berechnet daraus die eff. Frequenz des letzten
> Intervalls.

So isses.
Und für höhere Frequenzen dimensioniert man den Vorteiler so, daß sich 
innerhalb einer Eingangsperiode beide Werte auslesen lassen.
Beim AVR sollten dafür 100 Takte reichen (in C), d.h. bei 20MHz F_CPU 
sollten es kleiner 200kHz sein.
Mit einem Vorteiler 1/4096 ergäbe das 800MHz, real schafft der 74VHC4040 
max 210MHz.

von W.S. (Gast)


Lesenswert?

m.n. schrieb:
> Wenn man lückenlos messen will, dürfen keine 'Tore' verwendet werden

Das hatten wir schon mal und es war und ist Quatsch und wird es ewig 
sein.
Ein Meßtor MUSS sein, egal, ob es nun hard- oder softwareseitig gebildet 
wird.

Ohne ein Tor zum Bilden der Torzeit oder falls dich das Wort stört, 
nennen wir es eben "Einrichtung zur Bildung eines zeitlichen 
Meßintervalls", kurz EZBEZM kann man keinen Frequenzmesser bauen. Punkt.

Der Grund dafür liegt in der Dimension des Ergebnisses:  Hz (von Hertz) 
ist mathematisch 1/s, also allgemein gesagt Ereignisse/Zeitintervall.

Also braucht man exakt zwei Dinge, um eine Frequenz überhaupt ausdrücken 
zu können: Eine Anzahl von Ereignissen und ein Meßintervall, innerhalb 
dessen selbige gezählt worden sind. Letzteres ist die ominöse Torzeit.

Ist dir (und dem Axel) das endlich klar geworden?
(irgendwann MUSS es ja mal in die Schädel hinein!)

Deine Einlassung, daß man bei einem Meßtor, das eine endliche Zeit für 
die Verarbeitung der angefallenen Zählwerte geschlossen bleiben muß, im 
Falle von Messungen an Pulsen, die so etwa im Sekundenrhythmus kommen, 
nur jede zweite Sekunde eine Messung hat, ist natürlich richtig. Aber 
dies am Beispiel von EKG oder Pulsschlag als Argument zu gebrauchen, 
finde ich schlichtweg albern. Die Frequenz des Pulsschlages braucht man 
nie und nimmer auf 6 Stellen oder mehr zu bestimmen. Bei den 1PPS 
Signalen aus nem GPS zum Zwecke des Nachführens eines lokalen 
Frequenznormals sieht das ganz anders aus. Da sind die 
Regelzeitkonstanten im Minuten- und Stundenbereich und es ist dabei 
völlig wurscht, ob nun alle 20 oder alle 21 Sekunden ein 
Phasendifferenz-Ergebnis vorliegt.

Und für den normalen Gebrauch auf dem Basteltisch ist es erst recht 
egal. Da zählt viel mehr die Universalität und die meßtechnische 
Zuverlässigkeit, also ob man ohne Verrenkungen sowohl 50 Hz als auch mal 
eben 50 MHz messen kann, ohne Gefahr zu laufen, mit Aliassen (Alii) in 
die Irre geführt zu werden. Diesen Punkt hat Axel bis heute noch nicht 
kapiert, ebenso daß ich weiter oben eben NICHT "Einzelperiodenmessung" 
geschrieben habe. Ich hab bei ihm vielmehr den Eindruck, daß er per 
gezieltem Mißverständnis nach Anlaß zum Besserwissen sucht, dabei aber 
leider Unfug erzählt.

Und Peter setzt voraus, daß man schon vor dem Messen weiß, was man erst 
noch messen will:
Peter Dannegger schrieb:
> So isses.
> Und für höhere Frequenzen dimensioniert man den Vorteiler so, daß..

Ah ja. Ein Vorteiler, den man aber mangels Hardwaretor nicht auslesen 
kann, weil er asynchron laufen muß und man ihn deshalb nicht on the fly 
auslesen kann. Der muß dann umgeschaltet werden, wozu man erstmal wissen 
muß, was denn überhaupt anliegt. Und wenn man ohne Vorteiler arbeitet 
und dank Alias einen netten 10 kHz sieht, der in Wirklichkeit 10 MHz 
ist, dann merkt man nicht einmal, daß man eigentlich hätte umschalten 
müssen. Ich sag dazu nur "Programmiererpfusch".

W.S.

von m.n. (Gast)


Lesenswert?

W.S. schrieb:
> Das hatten wir schon mal und es war und ist Quatsch und wird es ewig
> sein.

Gut, Du bleibst uneinsichtig. Das diskutieren wir am besten nach den 
Feiertagen.

W.S. schrieb:
> Falle von Messungen an Pulsen, die so etwa im Sekundenrhythmus kommen,
> nur jede zweite Sekunde eine Messung hat, ist natürlich richtig. Aber
> dies am Beispiel von EKG oder Pulsschlag als Argument zu gebrauchen,
> finde ich schlichtweg albern.

Sag das nicht. Es geht hier nicht um ppm. Bei Selbstversuchen hatte ich 
extrem schwankende Ergebnisse und dachte, meine Elektronik sei kaputt. 
Dabei war ich selber kaputt. Mehr verrate ich aber nicht.

Ich denke, Dein Fläschchen 'Rote Toscana' hat jetzt lange genug geatmet, 
und Du kannst ihn jetzt genießen :-)

von Ulrich (Gast)


Lesenswert?

Gerade mit dem AVR bietet sich die Lösung mit dem abschaltbaren 
Vorteiler an, weil sie wenig Hardware benötigt. Direkt ohne 
Zusatzhardware kann der AVR Frequenzen bis etwa 200 kHz über die ICP 
Funktion messen. Mit einem (festen z.B. 1:1000) asynchronen Vorteiler 
geht es dann auch für höher Frequenzen.

Die Erkennung ob mit oder ohne Vorteiler zu messen ist, ist relativ 
einfach: zum einen ist für einem relativ großen Bereich (z.B. 10 kHz - 
200 kHz) die Wahl unkritisch, weil beides geht. Zum anderen kann am 
Signal mit Vorteiler zuverlässig und relativ schnell (etwa 0,1-10 ms , 
je nach Teiler) entschieden werden ob man den Teiler braucht oder nicht 
- die Entscheidung über das Signal ohne Teiler ist tatsächlich nicht 
zuverlässig, auch wenn es meistens funktioniert.

Die in dem Artikel beschriebene Version mit externem Tor und Zähler 
(HC590) ist etwas Aufwändiger, und nutzt halt einen HW Zähler für Zahl 
der Perioden, statt Vorteiler und Software. Eine kleine Einschränkung 
gibt es durch die Geschwindigkeit beim HC590 und der Laufzeit durch das 
Torgatter (HC74) - da könnte schon bei 20-30 MHz das Limit (Setup beim 
HC590 plus Delay vom HC74) erreicht sein.

Im Normalfall ist der Unterschied gering: Es stört kaum, wenn die Zahl 
der Perioden (und damit die Torzeit) auf vielfache des Vorteilers 
eingeschränkt ist. Als kleinen Nachteil sehe ich einige Schwierigkeiten 
eine Kontinuierliche Messung zu machen - bei kleinen Frequenzen, wo man 
es ggf. braucht sollte das aber auch noch hinzubekommen sein - selbst 
die Auswertung mehrerer Flanken (Ohne Teiler) könnte ggf. noch gehen.

von Axel S. (a-za-z0-9)


Lesenswert?

W.S. schrieb:
> m.n. schrieb:
>> Wenn man lückenlos messen will, dürfen keine 'Tore' verwendet werden
>
> Das hatten wir schon mal und es war und ist Quatsch und wird es ewig
> sein.
> Ein Meßtor MUSS sein, egal, ob es nun hard- oder softwareseitig gebildet
> wird.

Ihr habt schon beide recht. Allerdings bedeutet meine Darstellung des 
Verfahrens nicht, daß man zwischen den Messungen zwangsläufig eine 
Totzeit haben muß. Ich habe es zwar mit Totzeit implementiert, aber 
das war meine Entscheidung. Sogar wenn ich mal 1Hz messen muß (was 
selten genug vorkommt) stört es mich nicht im geringsten, wenn ich nur 
noch alle 2 Sekunden ein neues Ergebnis bekomme.

Bei 1Hz oder gar noch darunter kann man auch fast immer einen Meßpunkt 
finden der mit dem Zielsignal fest verkoppelt ist. Die 1Hz für z.B. eine 
Uhr fallen ja nicht vom Himmel, sondern eher aus einer Teilerkette, die 
man fast immer auch weiter vorn anzapfen kann.

> Also braucht man exakt zwei Dinge, um eine Frequenz überhaupt ausdrücken
> zu können: Eine Anzahl von Ereignissen und ein Meßintervall, innerhalb
> dessen selbige gezählt worden sind. Letzteres ist die ominöse Torzeit.
>
> Ist dir (und dem Axel) das endlich klar geworden?

Du bellst den falschen Baum an, mein Lieber.

> dies am Beispiel von EKG oder Pulsschlag als Argument zu gebrauchen,
> finde ich schlichtweg albern.

Ack. Der Herzschlag ist auch gar nicht regelmäßig genug, um ihn anders 
als durch die Messung jeder einzelnen Periode zu messen.

> Und für den normalen Gebrauch auf dem Basteltisch ist es erst recht
> egal. Da zählt viel mehr die Universalität und die meßtechnische
> Zuverlässigkeit, also ob man ohne Verrenkungen sowohl 50 Hz als auch mal
> eben 50 MHz messen kann, ohne Gefahr zu laufen, mit Aliassen (Alii) in
> die Irre geführt zu werden. Diesen Punkt hat Axel bis heute noch nicht
> kapiert

Bahnhof. Wovon sprichst du?

> Ein Vorteiler, den man aber mangels Hardwaretor nicht auslesen
> kann, weil er asynchron laufen muß und man ihn deshalb nicht on the fly
> auslesen kann. Der muß dann umgeschaltet werden, wozu man erstmal wissen
> muß, was denn überhaupt anliegt.

Das ist viel weniger problematisch als du darstellst. Im Zweifel mißt 
man halt erst einmal mit Vorteiler und schaltet nur dann um, wenn die 
Frequenz sicher niedrig genug für eine Messung ohne Vorteiler ist. Im 
schlimmsten Fall verschenkt man so eine Messung.

Ich mag das trotzdem nicht. Der Hardwareaufwand ist mit meiner Lösung 
kaum höher als mit Vorteiler und die Software ist eher einfacher. 
Außerdem reicht mir ein Meßbereich von fast 0 bis ~60MHz. U.a. auch 
deswegen, weil ein Vorverstärker/Trigger für einen größeren Bereich 
ziemlich kniffelig ist. Wenn man das Modul irgendwo einbauen will, wo 
permanent höhere Frequenzen anliegen, kann man ja einen festen Vorteiler 
vorsehen.

Bedenkt bitte auch, daß es ein "no frills" Einbaumodul sein soll. Kein 
vollwertiger Frequenzzähler. Dann würde man nämlich eine Menge weiterer 
Funktionen haben wollen. Minimum Ereigniszähler und Impulslängenmessung.

Last not least: ich habe auch nach längerer Websuche nirgendwo eine 
ausführliche Beschreibung des Reziprokverfahrens gefunden (toter Baum 
und nicht von Google indizierte PDFs außen vor). Tatsächlich wurde ich 
vor einiger Zeit daraufhin angesprochen, daß eine Suche nach 
"Reziprokzähler" nur meinen Artikel findet und dort die Beschreibung des 
Meßverfahrens fehlt.

Wenn irgendwer glaubt, er wisse das alles viel besser, dann kann er 
gerne einen Artikel in diesem Wiki oder anderswo schreiben. Ich werde 
das dann auch gerne verlinken. Also: nicht meckern - machen!


Ulrich schrieb:
> Eine kleine Einschränkung
> gibt es durch die Geschwindigkeit beim HC590 und der Laufzeit durch das
> Torgatter (HC74) - da könnte schon bei 20-30 MHz das Limit (Setup beim
> HC590 plus Delay vom HC74) erreicht sein.

Das ist korrekt. Mit ~13ns  Laufzeit durch den '74 und 20ns Setupzeit 
für den '590 ist die Grenze bei ca. 30MHz. Allerdings ist der Fehler 
durch einen oder zwei verpaßte Impulse erst in der 8. Stelle und damit 
schon außerhalb der Auflösung. Außerdem wirkt zumindest die Verzögerung 
symmetrisch auf Start und Ende der Messung und cancelt sich so raus. Der 
ATmega hat am ICP auch eine Schaltung, die den Impuls um 2-3 Takte 
zerzögert. Da auch diese Verzögerung symmetrisch auf beide Torflanken 
wirkt, kürzt sie sich ebenfalls weg.


XL

von Uwe S. (de0508)


Lesenswert?

Hallo Axel,

für den Beitrag Wiki hatte ich Dir schon gedankt, aber
Matthias Hopf hatte 11.08.2010 auch schon so gemessen:

Beitrag "Reziproker Frequenzzähler+ Optimierte 64bit uint Routinen"

Ich habe nun mein C-Programm aus 2010 direkt nach LunaAVR konvertiert um 
die Performance zu beurteilen.
Ich bin erfreut über die gleiche Rechenleistung vergl. C mit LunaAVR 
(ISR Handoptimiert).

So liegt die Meßfrequenzgrenze mimt F_CPU=20MHz bei 9,65MHz.

Da ich einen festen Vorteiler mit 4:1 verwende, kann ich im KW 
(Amateurfunkbereich) bis 38,6MHz messen.

somit werden die 30MHz sicher erreicht.

von Peter D. (peda)


Lesenswert?

W.S. schrieb:
> Ah ja. Ein Vorteiler, den man aber mangels Hardwaretor nicht auslesen
> kann, weil er asynchron laufen muß und man ihn deshalb nicht on the fly
> auslesen kann. Der muß dann umgeschaltet werden, wozu man erstmal wissen
> muß, was denn überhaupt anliegt. Und wenn man ohne Vorteiler arbeitet
> und dank Alias einen netten 10 kHz sieht, der in Wirklichkeit 10 MHz
> ist, dann merkt man nicht einmal, daß man eigentlich hätte umschalten
> müssen. Ich sag dazu nur "Programmiererpfusch".

Ja, man kann sich auch die Hose mit der Kneifzange anziehen.

Den Vorteiler läßt man natürlich immer mitlaufen und gibt ihn auf einen 
Interrupt, wo man grob erstmal mitzählen kann, wie oft er überläuft.
Die Umschaltung des ICP von direkt auf Vorteiler und zurück kann dann 
der ADC-MUX intern machen.
Nach dem Umschalten muß man die Messung neu starten, d.h. sie ist 
ausnahmsweise einmal diskontinuierlich.

von Ulrich (Gast)


Lesenswert?

Ein verpasster Puls durch die Torschaltung kann schon mehr als nur in 
der 8. Stelle auftauchen: das ist halt eine Periode oder etwa 20-30 ns 
und damit nur knapp unter der etwa 50-100 ns (je nach µC Takt) Auflösung 
die der Timer 1 liefert. Der Fehler kann sich wohl auch tatsächlich bei 
Start/Stop teilweise kompensieren und tritt dann ggf. später nicht mehr 
auf - wirklich symmetrisch sind die beiden Fälle aber nicht unbedingt. 
Mehr als einen Puls sollte man wohl nicht verlieren - da liegt dann 
schon das Limit vom HC590.

Im Prinzip haben die beiden zuletzt disktuierten auch nur minimale 
Unterschiede - das grundlegende Verfahren ist fast gleich: Die Zeit für 
eine gewisse Zahl an Perioden wird per ICP gemessen. Einmal mit '74 und 
'590 und Zählen der Periodenzahl in Hardware. Alternativ werden die 
Perioden in Software gezählt und Falls nötig ein Vorteiler (etwa '4040, 
aber unkritisch) genutzt um die Frequenz zu reduzieren. Die Periodenzahl 
ist damit auf ein vielfaches des Teilers beschränkt.
Im 2. Fall braucht man eine unkritische Umschaltung ob man mit oder ohne 
Teiler misst, dafür geht die kontinuierliche Messung etwas besser.

Das Bild im Artikelbereich lässt die "Synchronisation" der Torschaltung 
auf das Signal außen vor. Gerade das ist aber die wesentliche Idee bei 
der Reziprokmessung.

von Axel S. (a-za-z0-9)


Lesenswert?

Ulrich schrieb:
> Ein verpasster Puls durch die Torschaltung kann schon mehr als nur in
> der 8. Stelle auftauchen: das ist halt eine Periode oder etwa 20-30 ns
> und damit nur knapp unter der etwa 50-100 ns (je nach µC Takt) Auflösung
> die der Timer 1 liefert.

Knapp daneben. Bei 7 Stellen sind 10MHz (bzw. exakt 9.999999MHz) das 
Limit. Jede höhere Frequenz wird mit lediglich 10Hz aufgegelöst. Ein 
verpaßter Impuls ändert also nur die 8. Stelle und ist damit innerhalb 
der Rundung.

> Der Fehler kann sich wohl auch tatsächlich bei
> Start/Stop teilweise kompensieren und tritt dann ggf. später nicht mehr
> auf - wirklich symmetrisch sind die beiden Fälle aber nicht unbedingt.

Das Datenblatt spezifiziert die beiden Fälle nicht getrennt, deswegen 
würde ich durchaus von Symmetrie ausgehen. Das Tor (CKEN des HC590) 
öffnet womöglich einen Taklt zu spät, schließt dann aber auch einen Takt 
zu spät.

Ist aber egal: von 30MHz, die auch im worst case noch gehen sollten zu 
den garantierten 40MHz oder den getesteten (funktionierenden) 64 MHz ist 
der Fehler ohnehin nicht größer als 1 Impuls.

> Im Prinzip haben die beiden zuletzt disktuierten auch nur minimale
> Unterschiede - das grundlegende Verfahren ist fast gleich: Die Zeit für
> eine gewisse Zahl an Perioden wird per ICP gemessen.

Jep. Ein Grund mehr, die Diskussion um Details müßig zu finden.

> Das Bild im Artikelbereich lässt die "Synchronisation" der Torschaltung
> auf das Signal außen vor.

Wirklich? Genau deswegen habe ich das Timingdiagramm für das Gatesignal 
aufgemalt: 
http://www.mikrocontroller.net/articles/Datei:XL_Reziprok2.png

Was genau ist daran mißverständlich?


XL

von Helmut S. (helmuts)


Lesenswert?

> double korrekturwert = 0.999985750203;

Falls das mit dem GCC kompiliert war/wird ist "double" das Gleiche wie 
"float" bei den AVRs. Der GCC kennt bei den 8bit Controllern nur 32bit 
float-Zahlen. Auch wenn im source code "double" akzeptiert wird, wird 
trotzdem nur mit "float" gerechnet. Das bedeutet, dass bei 6 bis 7 
Stellen Genauigkeit Schluss ist.

von Ulrich (Gast)


Lesenswert?

Im Artikeltext und mit dem 2. Bild wird die Synchronisation der Torzeit 
schon klar, zumindest für die Periodenzählung - nur im Bockdiagramm 
fehlt der Teil. Bei der Zeitmessung ist da noch nicht ganz klar - gerade 
hier ist der Start/Stop erst mit der Flanke vom Signal aber wichtig.

In welcher Stelle der kleine Timingfehler Auftreten kann, hängt von der 
Torzeit ab - bei 1 s wäre es die 8.Stelle - bei 10ms dagegen schon die 
6.Stelle. Es ist halt gerade so wenig das knapp nicht aufgelöst werden 
kann.

von eglo (Gast)


Lesenswert?

Nebenfrage:

wie genau ist eigentlich deine Frequenz-Referenz, mit der du den 
Frequenzzähler überprüfst?

von Axel S. (a-za-z0-9)


Lesenswert?

Ulrich schrieb:
> Im Artikeltext und mit dem 2. Bild wird die Synchronisation der Torzeit
> schon klar, zumindest für die Periodenzählung - nur im Bockdiagramm
> fehlt der Teil. Bei der Zeitmessung ist da noch nicht ganz klar - gerade
> hier ist der Start/Stop erst mit der Flanke vom Signal aber wichtig.

Ähhm. "Das zweite Bild" meint wohl 
http://www.mikrocontroller.net/articles/Datei:XL_Classic2.png - für das 
klassische Periodendauer-Meßverfahren. Hier habe ich in der Tat kein 
Timingdiagramm, weil ich das Verfahren ja auch nur zum Verleich erwähne.

> In welcher Stelle der kleine Timingfehler Auftreten kann, hängt von der
> Torzeit ab - bei 1 s wäre es die 8.Stelle - bei 10ms dagegen schon die
> 6.Stelle.

Ja. Abhänging von der Referenzfrequenz ergibt sich die Auflösung der 
Periodendauer als bestenfalls 1/f_ref.

Wie (dort) gesagt: die klassische Periodendauermessung genauso wie die 
klassische Frequenzzählung hat einen systematischen Fehler von 
durchschnittlich +/- 1/2 bezogen auf den Zählerstand (= Meßwert). Und 
deswegen wird der Fehler bei kleineren Meßwerten (<= 4 Stellen) so 
untragbar groß.

Beim Reziprokzähler ist der Fehler auch +/- 1/2, aber eben nicht vom 
Meßwert sondern vom Zählerstand des Referenzzählers. Und indem man den 
Referenzzähler weit genug zählen läßt, verringert man den Fehler relativ 
zum Meßwert.

Ist das nicht klar genug rübergekommen?


XL

von Axel S. (a-za-z0-9)


Lesenswert?

eglo schrieb:

> wie genau ist eigentlich deine Frequenz-Referenz, mit der du den
> Frequenzzähler überprüfst?

An wen war die Frage gerichtet?

Falls an mich: gar nicht;) In Ermangelung eines guten Frequenznormals 
nehme ich einfach die ca. 20 XOs die hier so herumfliegen und trimme das 
Modul so, daß sie ca. jeweils zur Hälfte darüber und darunter liegen. 
(OK, nicht wirklich: in Wahrheit habe ich alle Blechbüchsen einmal 
gemessen und in "unter Nennwert" und "über Nennwert" sortiert. Dann habe 
ich ca. aus der Mitte ein 33.33MHz Modul als meine persönliche Referenz 
gekürt.)

Ein Quarz (oder Quarzoszillator) vom Händler hat so wie er geliefert 
wird eine Grundgenauigkeit von ca. 30ppm (= bis 30 Digits bei 6 
Stellen!). Über den erlaubten Temperaturbereich von -25°C bis +70°C 
kommen noch 30-50ppm Temperaturfehler dazu. Die Alterung liegt nochmal 
bei ca. 10ppm/Jahr.

Selbst wenn man also seinen Quarz(oszillator) perfekt abgleichen würde, 
müßte man die Temperatur auf +/- 5K einhalten und jedes halbe Jahr 
kalibrieren, nur um zuverlässig 6 Stellen anzuzeigen. Deswegen weise ich 
im Artikeltext auch darauf hin, daß 7 Stellen zwar möglich sind, man 
dann aber einen TCXO oder gar OCXO (temperaturkompensiert bzw. 
temperaturstabilisiert) Oszillator als Referenz braucht.

Ein Meßverfahren mit einem systematischen Fehler kleiner 0.1ppm (=7 
Stellen) ist zwar schick, angesichts einer Referenz mit eher 10ppm 
Fehler aber für sich allein nur Augenwischerei.


XL

von m.n. (Gast)


Lesenswert?

Axel Schwenke schrieb:
>> dies am Beispiel von EKG oder Pulsschlag als Argument zu gebrauchen,
>> finde ich schlichtweg albern.
>
> Ack. Der Herzschlag ist auch gar nicht regelmäßig genug, um ihn anders
> als durch die Messung jeder einzelnen Periode zu messen.

Hier müßte ein NACK stehen, damit es sich nicht mit dem nachfolgendan 
Satz widerspricht. Die Einzelimpulsmessung ist gerade bei Unregelmäßigen 
Impulsen angesagt. Wenn Signale hochstabil sind, kann man ja ganz 
konventionell mit Torzeit >100s messen.

Axel Schwenke schrieb:
> Last not least: ich habe auch nach längerer Websuche nirgendwo eine
> ausführliche Beschreibung des Reziprokverfahrens gefunden

Ich hatte weiter oben einen Link gegeben. Die Veröffentlichung in der 
ELEKTRONIK stammt vom 14.12.1984: exakt vor 29 Jahren.

Axel Schwenke schrieb:
> Bedenkt bitte auch, daß es ein "no frills" Einbaumodul sein soll. Kein
> vollwertiger Frequenzzähler. Dann würde man nämlich eine Menge weiterer
> Funktionen haben wollen. Minimum Ereigniszähler und Impulslängenmessung.

Mit ein wenig Suche findet man auch die Messungen von Periodendauer, 
Drehzahl und Ereignismessung samt Datenausgabe per RS232 
http://www.mino-elektronik.de/fmeter/neue_versionen.htm oder wer LEDs 
mag http://www.mino-elektronik.de/7-Segment-Variationen/LCD.htm#led2. 
Als Eingangsstufe: Beitrag "Eingangsstufe für Frequenzzähler DC-50MHz, +5V"
Die Schaltungen/Programme für einen STM32F4 kann man selber in der 
Codesammlung suchen. Oder Programme für Impulsbreite, -abstand und 
Geschwindigkeit. Ist mir ja schon fast unangenehm, es hier wiederholen 
zu müssen.

eglo schrieb:
> wie genau ist eigentlich deine Frequenz-Referenz, mit der du den
> Frequenzzähler überprüfst?

Am besten gleicht man mit einem sehr stabilen 1pps Signal eines 
GPS-Empfängers ab, oder läßt den Abgleich permanent im Hintergrund 
stattfinden. Beitrag "reziproker Frequenzzähler, GPS-stabilisiert, ATmega162"
Wenn man ein paar € übrig hat, nimmt man am besten einen TCXO. Diese 
haben z.T. schon eine sehr hohe Grundgenauigkeit von <1ppm. Den Abgleich 
macht man am einfachsten, indem man einen Korrekturwert im EEPROM 
hinterlegt und diesem bei der Auswertung berücksichtigt.

von Peter D. (peda)


Lesenswert?

Auch wenn man unbedingt ein Tor benutzen will, ist das nicht trivial. 
Ein AND-Gatter reicht jedenfalls nicht. Ein Kollege hat das mal gemacht 
mit 74AC193 Zählern dahinter und prompt hatte er manchmal um 15 oder 255 
Counts falsche Ergebnisse.
Der Grund ist, daß das Torsignal immer asynchron zum Eingangssignal ist 
und dadurch zu kurze Impulse entstehen können, die dann einen 
Synchronzähler durcheinander bringen.
Auch können durch den zu kurzen Impuls metastabile Zustände auftreten, 
d.h. einzelne Zählstufen wieder zurück kippen.

Die richtige Lösung für ein Zähltor ist daher, daß das erste Zählbit ein 
JK-FF sein muß und getort wird, indem J+K high oder low sind. Damit hat 
man maximal 1 Count Fehler.

von Helmut L. (helmi1)


Lesenswert?

Hier mal ein Artikel zum Reziprok Zaehler.

http://www.spectracomcorp.com/Desktopmodules/Bring2Mind/DMX/Download.aspx?EntryId=446&PortalId=0

Das +-1 Problem am Anfang und am Ende kann man auch noch wegbekommen 
durch Analoginterpolation. So kann man die Aufloesung des Zaehler auf ns 
hinbekommen.

von m.n. (Gast)


Lesenswert?

Helmut Lenzen schrieb:
> Das +-1 Problem am Anfang und am Ende kann man auch noch wegbekommen
> durch Analoginterpolation. So kann man die Aufloesung des Zaehler auf ns
> hinbekommen.

Gute Idee! Da braucht man ja nur eine sample&hold-Stufe, die geht dann 
an den ADC des ATmega32, und mit dem 10Bit Ergebnis kann man gleich drei 
gültige Stellen mehr anzeigen.

Hätte der Autor des obigen Artikels besser recherchiert, dann hätte er 
die reziproken Frequenzzähler schon ab den 70ern sehen müssen.
Diese hatten seinerzeit allerdings einen schlechten Stand, da die 6- bis 
7-stellige Anzeige nur für teures Geld zu erhalten war. Hingegen waren 
Geräte mit ICM7216 viel billiger und hatten sogar eine 8-stellige 
Anzeige UND: man konnte eine Torzeit einstellen :-)

von W.S. (Gast)


Lesenswert?

Axel Schwenke schrieb:
> Bahnhof. Wovon sprichst du?

Vom Abtast-Theorem.

Bedenke mal, daß jeder (ja, JEDER!) Pin-Eingang eines µC mit dem 
Systemtakt 'gesamplet' wird. Damit reagiert jeder Timer/Counter eines 
jeden µC eben NICHT auf die Flanken des tatsächlichen Eingangssignals, 
sondern nur auf eine logische Bedingung: Wenn beim vorletzten Sampling 
der Zustand des Pins anders war als beim letzten Sampling, dann gilt das 
als Erkennung einer Flanke und nur bei einer derart erkannten Flanke (LH 
oder HL) schaltet der Timer/Counter eins weiter. Getaktet wird er 
selbstverständlich mit dem zutreffenden Systemtakt und nicht wirklich 
mit dem am Pin anliegenden Signal.

Nun ist es ja so, daß es dem µC völlig egal ist, was mit dem Pin 
zwischen zwei Abtastzeitpunkten passiert. Er kriegt es garnicht mit - 
und so kann ein Signal an einem Pin mit einer Frequenz kurz neben dem 
Systemtakt dem µC genauso erscheinen, als sei es ein gewöhnliches 
niederfrequentes Signal. Sowas nennt man Alias.

HF-technisch ist das grob vergleichbar mit einem Mischer: Jedes 
Eingangssignal wird mit dem Systemtakt gemischt und der µC kann nicht 
die Differenz von der Summe unterscheiden - mal ganz grob gesagt.

Genau deshalb gibt es die eherne Forderung, daß bei einem abtastenden 
System das Eingangsspektrum keine Frequenzen gleich oder größer als die 
halbe Abtastfrequenz enthalten darf, wenn man keine Aliasse (Alii), also 
Geistersignale im Ergebnis haben will.

So. Hast du bei deinem Zählerprojekt einen Tiefpaß drin, der alles ab 
halbem Systemtakt von deinem Counter-Input-Pin fernhält? Nee. Sowas 
macht keiner. Aber genau deshalb mußt du bei deinem Konstrukt eben immer 
damit rechnen, daß es gelegentlich Bockmist anzeigt. Nicht immer, 
sondern nur gelegentlich: wenn die Eingangsfrequenz zu hoch ist, wenn 
das Tastverhältnis zu unegal ist. Um dem Ergebnis deines Zählers zu 
vertrauen, müßtest du zusätzlich noch oszillografieren.

Besorg dir mal ein Buch über digitale Signalverarbeitung. Im Netz gibt 
es ne sehr gute Literatur: "The scientists and engineers guide to 
digital signal processing" (http://www.dspguide.com/). Das liest sich 
gut und behandelt auch die Vorbehandlung von analogen Signalen.

So, und nun nochwas zur Totzeit (nee nicht toRzeit, sondern toTzeit): 
Ein Meßtor muß nicht zwangsläufig zwischen den ToRzeiten eine ToTzeit 
einlegen, obwohl das für den Systemaufbau ausgesprochen günstig ist.

Wenn man partout die ToTzeit vermeiden will, könnte man an beide Zähler 
(In- und Ref-Zähler) ein Auffang-Register parallel anschließen, das mit 
jedem zugehörigen Takt (das Ref-Auffang-Register mit dem Ref-Takt und 
das In-Auffang-Register mit dem In-Takt) 'geupdatet' wird. Das wird 
verdammt schnell bei hohen Input-Frequenzen.

Wenn man dann zugleich das Updatesignal beider Auffang-Register sperrt, 
laufen die eigentlichen Zähler weiter und man hat dennoch den letzten 
Stand beider Zähler zur Weiterverarbeitung. Mal abgesehen davon, daß man 
das Sperren des Ref-Auffangregisters noch mit dem des In-Registers 
synchronisieren muß, gibt es noch eine weitere Einschränkung zu 
beachten: Beide Zähler müssen zwangsweise in Hardware und als synchrone 
Zähler ausgeführt sein, sonst klappt das Übernehmen eines Momentanwertes 
nicht, das ja innerhalb einer einzigen Periode des In-Signals erledigt 
werden muß - und das ist schon bei 10 MHz eben viel zu wenig für ne 
Softwarelösung.

Dabei reden wir von Zählern im 28..32 Bit-Bereich. Sowas in klassischer 
TTL machen zu wollen ist albern. Für sowas braucht man ein passendes 
CPLD (und kein FPGA), denn die CPLD's haben elend lange AND-Gates (36 x 
in bei manchen Typen) im Inputbereich ihrer Macrozellen und sind deshalb 
allererste Wahl bei großen und zugleich schnellen Zählern.

Wenn man hingegen eine ToTzeit in Kauf nimmt, dann vereinfacht sich die 
ganze Hardware erheblich: Man braucht nur ein Tor vor jedem der beiden 
Zähler, die allerersten Stufen der Zähler können ordinäre Ripplecounter 
sein und die nachfolgenden Stufen können auch in Software realisiert 
sein. Man hat ja nach dem Schließen des Tores genug Zeit zum 
"ausrippeln". Dazu kommt noch ein einzelnes D-FF zum wirklich 
signalsynchronen Öffnen und Schließen des Tores (Ich hab das alles 
bereits in diesem Forum gepostet)

Und nochwas: Wenn zumindest die allerersten Stufen als echter Counter 
(synchron oder Ripple) ausgeführt sind, erübrigt sich die ganze 
Abtast-Theorem-Geschichte, denn da wird nix abgetastet, sondern nur auf 
die LH-Flanken reagiert, was ja der ursprüngliche Sinn der Sache ist. 
Und wenn die Inputfrequenz zu hoch sein sollte, zählt das Ding einfach 
nicht weiter, anstatt einem ne Hausnummer zu suggerieren. Das nenne ich 
meßtechnische Sicherheit: lieber nix darstellen als dem Benutzer ne 
Hausnummer zu präsentieren.

Ist das dir nun etwas klarer geworden?


Axel Schwenke schrieb:
> Wenn irgendwer glaubt, er wisse das alles viel besser, dann kann er
> gerne einen Artikel in diesem Wiki oder anderswo schreiben.

Ich mach das anders: ich poste hier im Forum ne Bastelanleitung - 
üblicherweise sogar mit ner kleinen Doku als PDF, und wer sie nachbauen 
will, kann's halt tun. Ich mach sowieso einiges anders - eben weil ich 
es besser weiß.

Ansonsten halte ich von überzogenen Anforderungen an einen 
Frequenzzähler garnix. Drehzahl? Periodendauer? Einzelimplszählung? Was 
denn noch?

Bei kommerziellen Zählern mag sowas sicherlich im Standard-Repertoire 
sein, wird aber praktisch kaum bis überhapt nicht genutzt. Mit nem 
Frequenzzähler will man eigentlich IMMER irgend eine Signalfrequenz so 
exakt wie möglich messen und für alles Weitere ist der Logikanalysator 
oder der Oszi die bessere Wahl, weil man da sieht was auf der Strippe 
eigentlich abgeht.

W.S.

von Axel S. (a-za-z0-9)


Lesenswert?

W.S. schrieb:
> Axel Schwenke schrieb:
>> Bahnhof. Wovon sprichst du?
>
> Vom Abtast-Theorem.

Aha. Und inwiefern hängt das mit dem Thema zusammen?

> So. Hast du bei deinem Zählerprojekt einen Tiefpaß drin, der alles ab
> halbem Systemtakt von deinem Counter-Input-Pin fernhält? Nee. Sowas
> macht keiner. Aber genau deshalb mußt du bei deinem Konstrukt eben immer
> damit rechnen, daß es gelegentlich Bockmist anzeigt.

Nein, muß ich nicht. Das Torsignal an ICP macht überhaupt nie kurze 
Impulse, sondern immer nur einen Zustandswechsel (und den auch nur auf 
Zuruf). Und damit das Signal an T0 über die kritische Marke von sagen 
wir mal 4 MHz (wenn der AVR mit 8MHz läuft) kommen könnte, müßte der 
74HC590 eine Frequenz von 2GHz zählen können. Tut er ganz sicher nicht.

T0 sieht bestenfalls ca. 120kHz und ist damit weit von der Problemzone 
entfernt. Und dewegen war mir auch vollkommen schleierhaft worauf sich 
deine Bemerkungen beziehen sollten.

> Ein Meßtor muß nicht zwangsläufig zwischen den ToRzeiten eine ToTzeit
> einlegen, obwohl das für den Systemaufbau ausgesprochen günstig ist.

Meine Rede.

> Ist das dir nun etwas klarer geworden?

Kann es sein, daß deine Rede fehladressiert war?

> Axel Schwenke schrieb:
>> Wenn irgendwer glaubt, er wisse das alles viel besser, dann kann er
>> gerne einen Artikel in diesem Wiki oder anderswo schreiben.
>
> Ich mach das anders: ich poste hier im Forum ne Bastelanleitung -
> üblicherweise sogar mit ner kleinen Doku als PDF

Das ist zwar besser als nichts, aber immer noch nicht gut. Ein PDF ist 
zumindest mal ein Medienbruch. Ganz davon zu schweigen, daß die 
Indizierung von PDFs immer noch suboptimal zu sein scheint. Und was man 
nicht mit Google findet, existiert nun mal nicht. Das muß man nicht 
schön finden, aber man sollte es akzeptieren.


XL

von W.S. (Gast)


Lesenswert?

Axel Schwenke schrieb:
> Kann es sein, daß deine Rede fehladressiert war?

O ja, es ist ganz offensichtlich so, daß du partout nicht zuhören 
willst. Erklärungen haben nur dann einen Sinn, wenn derjenige, der sie 
eigentlich zu seinem Verständnis braucht, auch zuhören will. 
Eigentlich meine ich es gut mit dir, aber öfter als mir lieb ist führst 
du dich auf wie ein bockiges Kind: Ohren zuhalten und mit dem Fuß 
aufstampfen.

Also lassen wir das, es scheint fruchtlos zu sein und der Thread ist 
ohnehin entgleist. Aber man sieht an so einem Thread, wohin es führt, 
wenn jemand einfach so, ohne wirklich nachdenken zu wollen, etwas 
bastelt und sich anschließend darüber wundert, daß er nicht das kriegt, 
was er beabsichtigt hatte:

A. M. schrieb:
> Ich finde den Fehler einfach nicht. Könnte es eventuell auch an den
> Datentypen liegen?

Eben. Wenn das Meßprinzip im Argen liegt, sind es gewiß die 
Datentypen...
Kopfschüttel.

W.S.

von Axel S. (a-za-z0-9)


Lesenswert?

W.S. schrieb:
> Axel Schwenke schrieb:
>> Kann es sein, daß deine Rede fehladressiert war?
>
> O ja, es ist ganz offensichtlich so, daß du partout nicht zuhören
> willst.

Nein, ich glaube einfach daß du mich mit jemand anderem verwechselst. 
Ungefähr der Hälfte von dem was du sagst, stimme ich vollumfänglich zu 
und habe das auch immer schon getan. Und die andere Hälfte betrifft mich 
überhaupt nicht. Vielleicht liest du einfach die letzten ca. 25 Posts 
noch einmal und schaust auch wer die jeweils geschrieben hat.


XL

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.