Periodendauer bzw Frequenz von einem Takt bestimmen

Gast #666213
Lesenswert?

Hallo zusammen,
ich hab ein kleines vielleicht auch simples Problem. Ich programmiere 
seit kurzem VHDL.
Ich möchte ein Takt einlesen und daraus, mit Hilfe von VHDL, die 
Periodendauer bzw. Frequenz bestimmen. Ich habe die Quartus Software von 
Altera und dazu einen Cyclone II FPGA.

Hat von euch jemand eine Idee, wie ich von einem bestehenden Takt, der 
sich bei Gelegenheit auch ändert, die Frequenz bzw. die Periodendauer 
bestimmen kann?

Besten Dank für ihre Anregungen.

Gruß BK
Gast #666237
Lesenswert?

Hallo Falk,
ich möchte am Ende der Programmierung den Frequenzwert des Takts. Diesen 
Wert möchte ich dann in VHDL weiter verarbeiten. Geht das mit einem 
Frequenzzähler?
Wenn ja, wie sieht dieser in VHDL aus? Kannst du mir da ein wenig 
helfen?

Danke.
#666249
Lesenswert?

@ BK (Gast)

>Wert möchte ich dann in VHDL weiter verarbeiten. Geht das mit einem
>Frequenzzähler?

Sicher.

>Wenn ja, wie sieht dieser in VHDL aus? Kannst du mir da ein wenig
>helfen?

Helfen ja, aber vorkauen nicht.

Mach doch mal einen prinzipiellen Vorschlag, wie das Ganze aussehen 
müsste. Über die Umsetzung in VHDL reden wir später.

MFG
Falk
Gast #666259
Lesenswert?

Ich hab mir da mal ne eigene Lösung überlegt. Ich hab doch einen 
Systemtakt. Diesen verwende ich als den Referenztakt. Sprich, von diesem 
Takt weiß ich ja schon meine Periodendauer bzw. meine Frequenz. Den 
Systemtakt erhalte ich von meinem FPGA. Diesen Referenztakt vergleiche 
ich nun mit meinem Externen Takt, von dem ich meine Frequenz wissen 
möchte. Bei jedem Positiven Event meines Referenztakts zählt ein Zähler 
(Zähler 1) hoch. Ein zweiter Zähler (Zähler 2) zählt meine positiven 
Flanken meines externen Takts.

1. positive Flanke von ext. Takt ---> Zähler 1 startet
2. positive Flanke von ext. Takt ---> Zähler 2 stoppt

Dann Werte ich aus wie weit mein 1. Zähler gezählt hat und rechne dies 
dann auf die Frequenz um.

Bsp.: Referenztakt : 50MHz, Periodendauer = 20ns

Zähler1 zählt  bis 1000000 wenn das externe Signal eine Frequenz von 
50Hz hat.

Somit habe ich den Frequenzwert binär in meinem System, oder?

Das wäre eine Idee von mir!

Was meinst du dazu????

MfG BK
#666268
Lesenswert?

@ BK (Gast)

>Das wäre eine Idee von mir!
>Was meinst du dazu????

Schon mal guter Ansatz, wenn gleich noch einige kleine Fehler drin sind.

Richtig ist, dass du zwei Zähler brauchst. Einen Referenzzähler, welcher 
die sog. Torzeit (Messzeit) generiert. Dein zweiter Zähler ist der 
eigentliche Frequenzzähler, welcher die unbekannte Frequenz misst.

Gestartet werden beide Zähler gleichzeitig, gestoppt wird dein zweiter 
Zähler, wenn der Referenzzähler den Maximalstand erreicht hat.

Ein kleine Stolperfalle besteht dabei in der Asynchronität der beiden 
Takte. Das muss durch RICHTIGES (tm) Synchronisieren berücksichtigt 
werden.

Zwei Zähler in VHDL zu beschreiben ist ja kein Thema. Der Rest ist auch 
nicht so schwer, oder?

MFG
Falk
Gast #666317
Lesenswert?

Hallo nochmal,

> Gestartet werden beide Zähler gleichzeitig, gestoppt wird dein zweiter
> Zähler, wenn der Referenzzähler den Maximalstand erreicht hat.

Wieso benötige ich einen Maximalstand? Genügt es nicht, wenn ich den 
Referenzzähler solange laufen lass, bis eine Periode vom zweiten Zähler, 
mit der zu messenden Frequenz, abgelaufen ist - sprich nach zwei 
positiven Clock'events? Dann weiß ich doch, wieviele Perioden von meinem 
Referenzsignal in der Periode meines zu messenden Signals abgelaufen 
sind.

Bsp.: Mein erster Zähler (Takt mit 50MHz) hat bis 1000000 gezählt bis 
eine Periode der zu messenden Frequenz abgelaufen ist (Zähler2: Abfrage 
auf die zweite pos. Flanke entspricht doch einer Periode). Daraus lässt 
sich dann über 20ns (50MHz) * 1000000 (Wert des 1.Zählers) = 20ms die 
Frequenz von 50Hz des Eingangstakts errechnen.

Oder?

MfG BK
#666332
Lesenswert?

@  BK (Gast)

>Wieso benötige ich einen Maximalstand? Genügt es nicht, wenn ich den
>Referenzzähler solange laufen lass, bis eine Periode vom zweiten Zähler,
>mit der zu messenden Frequenz, abgelaufen ist - sprich nach zwei

Im Prinzip schon. Das wäre eine Periodendauermessung. Die ist nur 
sinnvoll, wenn die zu messende Frequenz sehr vie niedriger als die 
Referenzfrequenz ist, in deinem Beispiel 50 Hz zu 50 MHz.

MFG
Falk
Gast #666354
Lesenswert?

Hallo Falk,
du machst mich neugierig. Wie funktioniert das dann mit einem Zähler? 
Ich brauch doch eigentlich zwei (für Referenz und ext. Takt), oder?

Aber wie funktioniert das mit einem Zähler? Könntest du mir das kurz 
beschreiben?

Besten Dank.
Gast #666360
Lesenswert?

> Lies mal deine Postings.

Ja, ich kenne meine Postings.
Da hab ich aber von zwei Zählern gesprochen und nicht von einem.
Ein Zähler für das Referenzsignal. Ein weiterer zweiter Zähler für den 
externen Takt (der zu messenden Frequenz).

Aber wieso nur ein Zähler?
#666366
Lesenswert?

@  BK (Gast)

>Ja, ich kenne meine Postings.

Wirklich? Und was ist damit?

"Wieso benötige ich einen Maximalstand? Genügt es nicht, wenn ich den
Referenzzähler solange laufen lass, bis eine Periode vom zweiten Zähler,
mit der zu messenden Frequenz, abgelaufen ist - sprich nach zwei
positiven Clock'events? Dann weiß ich doch, wieviele Perioden von 
meinem"

Du musst nur die Flanken des Messignals synchronisieren und als 
START/STOP für deinen Zähler verwenden.

MFG
Falk
Gast #666375
Lesenswert?

@ Falk

Ok. entschuldige du hast recht.

> Du musst nur die Flanken des Messignals synchronisieren und als
> START/STOP für deinen Zähler verwenden.

Wie synchronisiere ich die Flanken des Messsignals? Blöde frage, hab ich 
aber noch nie gemacht. Wie funktioniert das?

MfG
BK
#666380
Lesenswert?

@ BK (Gast)

>Wie synchronisiere ich die Flanken des Messsignals? Blöde frage, hab ich
>aber noch nie gemacht. Wie funktioniert das?

Etwa so.
1
--
2

3
signal sig_sync: std_logic;
4
signal sig_int: std_logic;
5
signal sig_delay: std_logic;
6
signal sig_edge: std_logic;
7

8
-- Signal synchroisieren
9

10
process(clk50M)
11
begin
12
  if risig_edge(clk50M) then
13
    sig_sync <= messignal;
14
    sig_int <= sig_sync;    --nur das Signal darf intern verwednet werden
15
  end if;
16
end process;
17

18
-- steigende Flanke erkennen
19

20
process(clk50M)
21
begin
22
  if risig_edge(clk50M) then
23
    sig_delay <= sig_int;
24
    if sig_int='1' and sig_delay='0' then
25
      sig_edge <='1';
26
    else
27
      sig_edge <='0';
28
    end if;
29
  end if;
30
end process;

MfG
Falk
Gast #666385
Lesenswert?

> process(clk50M)
> begin
>  if risig_edge(clk50M) then
>    sig_delay <= sig_int;
>    if sig_int='1' and sig_delay='0' then
>      sig_edge <='1';
>    else
>      sig_edge <='0';
>    end if;
>  end if;
> end process;

Das sig_delay hat doch dann immer den gleichen wert wie sig_int?!
Somit bekomm ich doch gar nie sig_edge <= '1'. Oder täusche ich mich da?
#666395
Lesenswert?

@  BK (Gast)

>Das sig_delay hat doch dann immer den gleichen wert wie sig_int?!

Nöö.

>Somit bekomm ich doch gar nie sig_edge <= '1'. Oder täusche ich mich da?

Ja. Wir sind hier bei VHDL, nicht bei einer normalen Programmiersprache.

sig_delay und sig_int sid zwei verschiedene Signale. sig_delay ist um 
einen Takt gegenüber sig_int verzögert.

MFG
Falk

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren