Hallo zusammen. Ich habe einige VHDL-Templates zur Tastenentprellung (u.a. debounce circuit von ISE) getestet und festgestellt, dass sie alle leider nicht viel taugen. Daher möchte ich eine Zeitschleife einbauen, so dass nach Tastendruck 500 Millisekunden lang nichts passiert. Weiss jemand wie sowas in VHDL geht oder hat vielleicht jemand ein besseres Programm zur Tastenentprellung? Danke im voraus. P.S. Hier sind 2 Ausschnitte PROG1: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; -- Uncomment the following lines to use the declarations that are -- provided for instantiating Xilinx primitive components. --library UNISIM; --use UNISIM.VComponents.all; entity entprell is Port ( D_IN : in std_logic; RESET : in std_logic; CLK : in std_logic; Q_OUT : out std_logic); end entprell; architecture Behavioral of entprell is signal Q1, Q2, Q3 : std_logic; begin -- Provides a one-shot pulse from a non-clock input, with reset process(CLK, RESET) begin if (RESET = '1') then Q1 <= '0'; Q2 <= '0'; Q3 <= '0'; elsif (CLK'event and CLK = '1') then Q1 <= D_IN; Q2 <= Q1; Q3 <= Q2; end if; end process; Q_OUT <= Q1 and Q2 and (not Q3); end Behavioral; PROG2: LIBRARY IEEE; USE IEEE.std_logic_1164.ALL; USE IEEE.std_logic_unsigned.ALL; ENTITY entprell IS PORT( clkint: IN std_logic; rst: IN std_logic; button: IN std_logic; hit: OUT std_logic ); END entprell; ARCHITECTURE myentprell OF entprell IS SIGNAL count: integer range 0 to 250000; SIGNAL buttonclk: std_logic; SIGNAL state: std_logic_vector(3 downto 0); BEGIN PROCESS(clkint, rst, count) BEGIN IF(rst='0') THEN count<=0; buttonclk <= '0'; ELSIF(count=250000) THEN count<=0; ELSIF(clkint'event AND clkint='1') THEN if(count=0) THEN buttonclk <= not buttonclk; END IF; count<=count+1; END IF; END PROCESS; PROCESS(button, buttonclk, rst) BEGIN IF(rst='0') THEN state<="1111"; ELSIF(buttonclk'event AND buttonclk='1') THEN state(3 downto 1) <= state(2 downto 0); state(0) <= button; IF( state = "0000") THEN hit <= '1'; ELSE hit <= '0'; END IF; END IF; END PROCESS; END myentprell;
ich würde es so probieren: Mit dem ersten low/high oder high/low Übergang starte ich einen Zähler. Ist der Abgelaufen übernehme ich den Zustand der Taste und verarbeite sie weiter.
Hallo Jörn. Genau das war meine Idee. Sobald die erste Flanke des Tasters erkannt wird, wird der Zähler gestartet. Ist der abgelaufen, wird der Zusatnd der Taste (vor dem Zählerstart) übernommen und am Ausgang soll ein Impuls gegeben werden. Ich werde es mal versuchen in VHDL umzusetzen. Danke Jörn Gruss Hilel
> Mit dem ersten low/high oder high/low Übergang starte ich einen > Zähler. Ist der Abgelaufen übernehme ich den Zustand der Taste und > verarbeite sie weiter. Macht es eigentlich einen Unterschied, ob ich den Zähler zuerst starte und dann den Wert übernehme oder erst den Wert übernehme und dann den Zähler starte? Im ersten Fall besteht doch die Gefahr, das der übernommene Wert noch vom Prellen kommt, oder? Thorsten
Guten Morgen. Ich habe den folgenden Code entdeckt und der ist prima. Allerdings habe ich ein anderes Problem, wenn ich 2 unabhängige Taster entprellen will (Schaltung s. Bild). Jeder Taster versorgt einen BCD-Zähler mit Takten. Diese Takte werden gezählt und erscheinen als BCD Zahl an der 7Seg.Anzeige. Soweit so gut. Wird nur ein Taster entprellt, dann zählt der entsprechende Zähler richtig (1,2,3...99 und nach 99 zurückgesetzt). Der andere Zähler überspringt einige Zahlen, was selbstverständlich ist (keine Entprellung). Werden nun beide Taster entprellt, dann zählt der eine richtig und der andere im Zweierschritt (2,4,8,...98,0,2 usw.). Kann es jemand nachvollziehen? Mit bestem Dank Nun zum Code: LIBRARY ieee; USE ieee.STD_LOGIC_1164.all; USE ieee.STD_LOGIC_UNSIGNED.all; -- Short Name: Debc ENTITY deb2 IS PORT ( Clk : IN STD_LOGIC; Key : IN STD_LOGIC; -- active low input pulse : OUT STD_LOGIC); END deb2; ARCHITECTURE Clean_pulse OF deb2 IS SIGNAL cnt : STD_LOGIC_VECTOR (17 DOWNTO 0); BEGIN PROCESS (Clk) BEGIN IF Key = '1' THEN cnt <= "000000000000000000"; ELSIF (clk'EVENT AND Clk = '1') THEN IF (cnt /= "111111111111111111") THEN cnt <= cnt + 1; END IF; END IF; IF (cnt = "111111111111111110") AND (Key = '0') THEN pulse <= '1'; ELSE pulse <= '0'; END IF; END PROCESS; END Clean_pulse;
@ Thorsten: Ich würde behaupte, dass das von der verwendeten Taktfrequenz abhängt mit der das System betrieben wird. Mit 50 Mhz ist der Wert des Tasters vor und der Wert nach Ablauf des Zählers identisch. Ich bezweifle, dass ein mechanischer Taster mit 50 Mhz prellt ;) Dessen Prellen wird sich im Hz Bereich abspielen. Läuft die Schaltung aber auch nur mit ein paar Hertz, kann es durch aus sein, dass der Wert vom Prellen stammt. Ich benutzt meistens den den Wert nach Ablauf der Zeit.
Mit 50MHz kann man auf keinen Fall entprellen ! Etwa 100Hz sind o.k. Dann baut man mit 2 FFs einen Zähler 0..3 auf und noch ein FF zum Speichern des entprellten Signals, fertig. Nun noch einen 4. FF zur Flankenerkennung und schon ist man bei meinem Beispielcode: http://www.mikrocontroller.net/attachment.php/20758/Get8key4.c51 Sollte einfach für einen CPLD umzuschreiben sein. Allerdings ist für so langsame Sachen ein Mikrokontroller wesentlich effektiver und leistungsfähiger. CPLDs haben nur dort einen Vorteil, wo man sehr sauschnell sein muß. Ich nehme CPLDs daher nur als Zuarbeiter für Mikrokontroller, z.B. Adreßdekodierung und Peripherie (GPIB-Controller). Peter
Wieso funktionniert es bei einem Taster einwandfrei und beim anderen überhaupt nicht. Es handelt sich um dieselbe Entprellung. Und wieso zählt der Zähler im Zweierschritt? Er zählt nur die geraden Zahlen 0,2,4,6,8...bis 98 und geht wieder auf 0. Er hat keine einzige ungerade Zahl gezeigt. Es ist schon merkwürdig. Hat jemand von Euch eine Idee oder einen besseren Vorschlag? Es sollen 2 Taster unabhängig voneinander entprellt werden. Vielen Dank
Wieso fährt einer bei rot über die Kreuzung und überlebt aber ein anderer ist tot ? Einfach bei grün fahren, dann überlebt jeder. Einfach richtig entprellen, dann geht jede Taste. Es liegt in der Natur von Störeinflüssen, daß sie auftreten können, aber nicht müssen. Peter
Hallo Peter.
Ich finde den Vergleich gar nicht angebracht.
Ich habe es nun so gelöst, dass die 50MHz runtergeteilt werden auf
100Hz. Dies reicht dann für eine Entprellung.
>>Es liegt in der Natur von Störeinflüssen, daß sie auftreten können,
aber nicht müssen.
Hier treten sie aber regelmässig auf. Das deutet auf einen Fehler hin.
Mir ging es einfach um diesen Fehler.
Gruss Hilel
In Deinem Schaltplan gehen ja die 50MHz direkt auf die Entprellung. Wie Du die ~100Hz erzeugst, ist egal, Hauptsache sie sind da (dürfte bei 50MHz aber 19 FFs verbraten). Wenn es trotzdem nicht geht, dann ist also Deine Entprellroutine falsch. Die 2-er Zählung könnte darauf hindeuten, daß Du das Entprellen beim Loslassen "vergessen" hast. Meine Routine entprellt beides, indem bei 4 aufeinanderfolgenden Takten der gleiche Pegel erkannt werden muß, damit er übernommen wird, also für mindestens 30..40ms. Ich kenn mich mit VHDL nicht aus, sondern nur mit AND,OR,EXOR,NOT, daher ist auch mein C-Programm so geschrieben (&,|,^,!). Ich könnts Dir bei Interesse in Abel auf den GAL16V8 umschreiben. Peter
Hallo Peter. Ich habe es schon hingekriegt. Ich habe die 50 MHz auf 1MHz, dann auf 1KHz und am Schluss noch auf 100Hz runtergeteilt. Die Entprellung habe ich mit 3 FFs wie folgt realisiert: Q1 = D1 (D1: zu entprellende Taste) Q2 = Q1 Q3 = Q2 Q_OUT = Q1 AND Q2 AND (NOT Q3) <<Ich könnts Dir bei Interesse in Abel auf den GAL16V8 umschreiben. Danke für Dein Angebot. Ich habe den Spartan3 Starter Kit von Digilent und damit übe ich jetzt. Schon lange her, dass ich was mit FPGA gemacht habe. Ausserdem hat die damalige (es sind schon 11 Jahre her) Software (Workview) nur die Schaltplaneingabe unterstützt. Solche Aufgaben lassen sich natürlich mit uC viel einfacher lösen. Mir geht es weniger um die Auswahl uC oder FPGA. Ich möchte einfach in die Welt der VHDL-Sprache einsteigen und einige Programme mit dem Spartan3 Starter Kit testen. Gruss Hilel
@Hilel, "Q_OUT = Q1 AND Q2 AND (NOT Q3)" Gut ist diese Entprellung nicht. Beim Drücken entprellt sie 2-fach (2 High-Pegel nötig) und beim Loslassen garnicht. Anbei meine 4-fach-Entprellung in Abel. Da ja ein Mikrokontroller sequenziell arbeitet, ein CPLD aber parallel, habe ich einfach einige Zwischensignale definiert (*_TEMP), damits gleich aussieht. Die werden aber alle sofort wieder rausoptimiert, belegen also keine Ressourcen. Peter
Also mit dem zu entprellenden Eingang auf den Clock zu gehen ist absoluter Murks!!! Einfach Lösung: 2 Stufiges Schieberegister ( Zwei FF hintereinander) Der CLK wird mit dem Sampleclock (Sinnvoller Weise um die =< 100HZ) bedient. Die beiden Ausgänge der Flipflops werden zusammen mit dem Ausgang eines 3. FF (Auch der selbe CLK) Mehrheits überprüft. Das heisst, der Zustand der 2 mal vorhanden ist, wird ins 3 FF übernommen. Gleichung des 3. FF: FF3.D = FF1.Q & FF2.Q # FF2.Q & FF3.Q # FF1.Q & FF3.Q Der Ausgang des 3 FF ist entprellt. Das ganze ist Synchron. Metastabile Zustande können nur im ersten FF vorkommen. Und auch noch Resourcen sparend, da kein Zähler zur konfimierung benötigt wird. Beide Richtungen sind entprellt. Ein Glitch führt nicht zum umschalten. Gruß Max
@Max, "Also mit dem zu entprellenden Eingang auf den Clock zu gehen ist absoluter Murks!!!" wenn Du jetzt noch sagst, auf wen und was sich das beziehen soll ? Ich sehe nämlich nirgends, daß jemand sowas gemacht hätte. Peter
Stimmt! Ich hab den ersten Eintrag nur schnell überflogen und bin bei "ButtonCLK'event" davon ausgegangen, das das der Button selber ist. Zumal im process darüber ein andere "CLK" für den Counter benützt wurde . Somit 2 Clocks und das ist asynchrones Design. Ich denke nicht, das du das in deiner Branche so machen würdest. Nützt du eigentlich TMR umd die SEU Problematik in euren Geräten zu umgehen, oder setzt ihr nichts RAM basierendes an PLD und FPGA's ein. Gruß Max
Danke Peter, danke Max Müller für die Infos. Ich habe beide Varianten getestet und in eine Schaltung mit 2 BCD-Zählern eingesetzt. Beide Entprellungen funktionieren. @Peter. Deine Entprellung in Abel habe ich mit einem Mealy-Automat (4 Zustände) realisiert. Ich habe sie erstmal mit einem asynchr. Reset versehen und getestet, ging leider nicht. Mit einem synch. Reset hat es dann geklappt. Ich bin noch dabei herauszufinden, woran es liegt. Jetzt habe ich insgesamt 3 unterschiedliche Methoden, um einen Taster zu entprellen. Alle 3 Methoden wurden mit dem Spartan-Board erfolgreich getestet. Ich werde sie alle drei mit den unterschiedlichsten Tastern testen und mich in Zukunft für eine entscheiden. Ich danke Euch nochmal.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.