Setzen Sie ein konstant hohes Signal auf niedrig

Ich habe eine Tastaturschaltung, wenn ich eine Taste drücke und halte, ist das Signal "key_pressed" immer hoch, solange ich die Taste gedrückt halte, was normal ist, wenn ich es lasse, wird es wieder niedrig. Aber ich möchte nicht, dass dieses Signal konstant hoch ist, egal wie lange ich die Taste drücke, ich möchte als einzelnes kurzes Drücken erkannt werden. Auf andere Weise sollte ich einen Weg finden, dieses key_pressed nach sagen wir 10 ms auf niedrig zu setzen. Ich mache alles in VHDL, keine Widerstände, Kondensatoren ... Ich kann auch nicht auf eine fallende Flanke warten, dann macht es keinen Sinn, auf dem LCD wird keine Taste angezeigt, bis die Taste losgelassen wird, was keinen Sinn macht.

Klingt so, als bräuchten Sie einen Kantendetektor. Angenommen, die Entprellung ist bereits erledigt ...
Ich kann eine fallende Kante kaum erwarten ...
Siehe Spehros Antwort. Ich bin mir nicht sicher, wo ich irgendetwas angedeutet habe, das mit der fallenden Flanke zu tun hat ...

Antworten (3)

Sie benötigen einen Anstiegsflankendetektor . Dies erfolgt durch Generieren einer verzögerten Eingabe, die 1 Taktzyklus später als die tatsächliche Eingabe ist.

Zum Beispiel:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 

                 ^ You want to detect this point, where the signals are not the
                   same. Input has gone high, but because Input_z is delayed, it 
                   isn't high yet 

Der verzögerte Eingang wird wie folgt generiert:

gen_input_z : process(clk,rst) 
begin
    if (rst = '1') then
        Input_z <= '0';
    elsif (rising_edge(clk)) then
        Input_z <= Input;
    end if;
end process

Jetzt möchten Sie Ihre steigende Flanke erkennen:

gen_edge_det : process(clk,rst) 
begin
    if (rst = '1') then
        Edge_detect <= '0';
    elsif (rising_edge(clk)) then
        if (Input = '1' and Input_z = '0') then
            Edge_detect <= '1';
        else 
            Edge_detect <= '0';
        end if;
    end if;
end process

Aber jetzt ist unsere Flankenerkennung nur ein Taktzyklus:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 
                        ________
Edge_det   ____________/        \__________________________________________________

Um dies zu ändern, fügen Sie einen Zähler hinzu, der die Flankenerkennung erst nach einer bestimmten Anzahl von Taktzyklen fallen lässt:

-- Port Declarations
signal clk         : in std_logic;
signal rst         : in std_logic;
signal input       : in std_logic;

-- Signal declarations
signal input_z     : std_logic;
signal edge_detect : std_logic;
signal counter     : unsigned(31 downto 0); -- include numeric_std for this


gen_edge_det : process(clk,rst) 
begin
    if (rst = '1') then
        Edge_detect <= '0';
        counter     <= '0';
        input_z     <= '0';
    elsif (rising_edge(clk)) then
        input_z <= input;
        if (Input = '1' and Input_z = '0') then
            Edge_detect <= '1';
            counter     <= (others => '0');
        elsif (counter < 2) then          -- we want an edge detect of 2 clock cycles 
            Edge_detect <= '1';
            counter     <= counter + "1"; -- declare counter as unsigned.
        else
            Edge_detect <= '0';
        end if;
    end if;
end process

Jetzt tut es, was wir wollen:

               ____     ____     ____     ____     ____     ____     ____     ____      
CLock      ___/    \___/    \___/    \___/    \___/    \___/    \___/    \___/    \

               _______________________________
Input      ___/                               \____________________________________
                        _______________________________
Input_z    ____________/                               \___________________________ 
                        _____________
Edge_det   ____________/             \_____________________________________________
vielen Dank für die Antwort, es gibt 3 Prozesse mit demselben Namen, ich denke, es wird 1 Prozess mit einer Kombination aus 1 und 3 geben, oder? Und schließlich Edge_detwird das Ausgangssignal sein, das ich will, oder?
Die drei gleichen Namen waren nur ein Tippfehler, sie sollen unterschiedlich sein. Ja, 1 + 3 wird den Trick tun. Edge_det ist das, was Sie wollen.
Ich habe ein Aktivierungssignal in der Zustandsmaschine, das 100 Hz beträgt. Ich wechsle alle 100 Hz zwischen den Zuständen, also werde ich versuchen, dieses Aktivierungssignal in meinem zu verwenden, aber gen_edge_detwenn ich scheitere, werde ich versuchen zu kontern. Wie haben Sie den Zähler deklariert? signalisieren counter : integer range 0 to 2 := 0;?
Ich erhalte diesen Fehler "rising_edge kann solche Operanden in diesem Kontext nicht haben."
Meine Uhr ist als Bit deklariert, vielleicht deshalb.
Signaldeklarationen zum 3. Prozess hinzugefügt, input_delay in den 3. Prozess aufgenommen. Das sollte die Sache etwas klären.

Die Art und Weise, wie ich dies in der Firmware mache, besteht darin, eine Änderung in der Eingabe zu erkennen (nach dem Zurückweisen von Rauschen und Prellen) und dann ein Ereignis basierend auf dem Tastendruck oder sogar basierend auf dem Loslassen der Taste für jede Taste zu generieren.

Sie können dann die Tastendruck- und -loslassen-Ereignisse in Verbindung mit Timern verwenden, um alle üblichen Funktionen auszuführen, die Sie mit Tasten auf moderner Elektronik verbinden. Halten Sie die Taste 3 Sekunden lang gedrückt, um in einen speziellen Modus zu gelangen. Halten Sie die Taste gedrückt und lassen Sie sie dann los, um eine Encoder-Einstellung oder was auch immer zu sperren.

Bearbeiten: Basierend auf Ihren Änderungen kann dies bei Verwendung von VHDL (Hardware) mit einer Uhr und Flip-Flops erreicht werden. Vergleichen Sie einfach die Eingabe X mit einer verzögerten Version der Eingabe X'. Dadurch erhalten Sie einen Ein-Takt-Impuls für die steigende Eingangsflanke (und, wenn Sie möchten, einen Ein-Takt-Impuls für die fallende Eingangsflanke). Es funktioniert in einem HDL genauso wie im sequentiellen Code.

Die Eingabe ändert sich nicht immer mit High und dem gleichen Schlüsselwert. Ich habe meine Frage ein wenig bearbeitet.

Ich würde sagen, Sie suchen einen monostabilen Multivibrator. Sie können sie aus einem 555-Timer erstellen oder einen dedizierten Chip verwenden. Für TTL ist es als 74xx123-Komponente verfügbar. Sie arbeiten, indem sie eine Flanke erkennen und einen Impuls mit programmierbarer Dauer ausgeben. Die Pulsparameter kann man mit externen Widerständen und Kappen einstellen, wenn ich mich recht erinnere. Rufen Sie ein Datenblatt auf. Sie sollten Beispielschaltungen enthalten, an denen Sie sich die Zähne ausbeißen können.

74ls121 funktioniert auch. Wenn Sie so etwas nicht haben, können Sie meines Erachtens eines mit zwei Wechselrichtern und einer RC-Schaltung herstellen.
Vergaß zu erwähnen. Da dieser kantensensitiv ist, ist keine Entprellung notwendig. Tatsächlich arbeitet dieses Gerät als eigenständige Entprellschaltung.