Datum:
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; |
Datum:
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
Datum:
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 ;-).
Datum:
Funkandsoda schrieb: > RESET: in std_logic Lern nicht gleich so einen Käse: Reset... :-/ und dazu noch asynchron... Siehe dazu den Beitrag "Detailfrage Reset"
Datum:
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
Datum:
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
Datum:
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 |
Datum:
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...
