www.mikrocontroller.net

Forum: FPGA, VHDL & Co. Frequenzteiler funktioniert nicht -> Anfängerfrage


Important announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Funkandsoda (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hallo,

ich beschäftige mich erst seit 2 Tagen mit VHDL und einem Digilent 
Basys2 Board
Ich benötige für ein Projekt einen 1kHZ Ton, den ich über einen Pin 
ausgeben möchte, um damit einen kleinen Lautsprecher zu treiben, so dass 
er leise piept.

Der Frequenzteiler funktioniert auch, wenn ich einen Bitvector 
hochzählen lasse und dann ein einzelnes Bit abgreife, das halt immer hin 
und her toggelt.
Damit erreiche ich aber leider eben keine genauen 1 kHZ.

Nun versuche ich den Frequenteiler auf andere Art zu realisieren aber 
das funktioniert einfach nicht. Der Lautsprecher bleibt stumm obwohl die 
Pins korrekt zugewiesen sind (eben genauso wie in der Version oben).

Kann mir jemand einen Tipp geben wo mein Denkfehler liegt?

Bin sehr dankbar für jede Hilfe.
entity main is
  port (
    CLK: in std_logic;
    TON: out std_logic;
    RESET: in std_logic
    );
end main;

architecture Behavioral of main is
  signal COUNTER: std_logic_vector(15 downto 0);
  signal KHZ: std_logic;
begin

  CounterProcess: process(RESET, CLK)
  begin
    if (RESET='1') then
      COUNTER <= (others =>'0');
      KHZ <= '0';
    elsif rising_edge(CLK) then
      if COUNTER = "1100001101010000" then -- Zähler bis 50000
        KHZ <= '1';
        COUNTER <= (others => '0');
      else
        COUNTER <= COUNTER + 1;
        KHZ <= '0';
      end if;
    end if;    
    
  end process;
    
  TON <= KHZ;
  
end Behavioral;

Autor: voodoofrei (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
schon mal vorneweg: nur wenn der Zählerstand seinen Wert erreicht hat( 
in deinem Kommentar 50000) wird eine 1 ausgegeben, sonst 0

Ich geh jetzt mal von einer 50 MHz clk aus => da kommt dann natürlich 
nichts mehr (hörbares ;) ) aus dem LS.

quick & dirty Vorschlag:

signal COUNTER: integer range 0 to 50000;

   if (RESET='1') then
      COUNTER <= 0;
      KHZ <= '0';

 elsif rising_edge(CLK) then
      COUNTER <= COUNTER + 1;
      if COUNTER = 50000 then -- Zähler bis 50000
        KHZ <= '0';
        COUNTER <= 0;
      elsif COUNTER = 25000 then
        KHZ <= '1';
      end if;
    end if;    


Füge das mal in deinen Code ein

Autor: Christoph F. (funkandsoda)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Ich danke Dir vielmals für die schnelle Hilfe!
Klappt jetzt und ich habe nun auch verstanden wieso es vorher nur mit 
der anderen Version ging ;-).

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite Flattr this
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Funkandsoda schrieb:
> RESET: in std_logic
Lern nicht gleich so einen Käse: Reset... :-/ und dazu noch asynchron...
Siehe dazu den Beitrag "Detailfrage Reset"

Autor: Duke Scarring (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Lothar Miller schrieb:
> Lern nicht gleich so einen Käse:

Und wenn wir schon mal dabei sind:

Funkandsoda schrieb:
> signal COUNTER: std_logic_vector(15 downto 0);
[...]
>         COUNTER <= COUNTER + 1;

Verwende die aktuellen Bibliotheken zum Rechnen:
Beitrag "IEEE.STD_LOGIC_ARITH.ALL obsolete"

Duke

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite Flattr this
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Duke Scarring schrieb:
> Und wenn wir schon mal dabei sind:
Da fällt mir noch ein:
>>> signal COUNTER: integer range 0 to 50000;
Das sind 50001 Schritte!
>>> if COUNTER = 50000 then -- Zähler bis 50000
>>>      COUNTER <= 0;
Der Zähler zählt also 50001 Takte. Ja, klar: halb so schlimm. Aber 
probier das mal mit dem Zählerwert "10", da sind es dann schon 10% 
Fehler... :-o

Autor: voodoofrei (Gast)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Hast recht - hab gepfuscht (nicht umsonst quick & dirty geschrieben).

Mach ich normalerweise so:
constant cval: integer := 50000

signal COUNTER: integer range 0 to cval-1;

if COUNTER = cval-1 then -- Zähler bis 50000


Autor: Christoph F. (funkandsoda)
Datum:

Diesen Beitrag bewerten:
lesenswert
nicht lesenswert
Vielen Dank für die vielen Tipps. Hab noch eine kleine Frage: hat jemand 
spontan eine Idee wieso mir mein Multimeter bei der berichtigten Version 
keine Frequenz anzeigt? Bei meinem ersten Versuch mit dem Auslesen des 
einen kippenden Bits klappt das problemlos,trotz der krummen Frequenzen 
und ich suche gerade nach dem Grund dafür...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel




Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder GIF-Format hochladen.
Siehe Bildformate
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken erkennst du die Nutzungsbedingungen an.

webmaster@mikrocontroller.netImpressumNutzungsbedingungenWerbung auf Mikrocontroller.net