Suche Befehl eine einzelne Flanke

Gast #640397
Lesenswert?

Hallo

Ich brauche eine Pinabfrage die nur dann eine if-Schleife aktiviert wenn 
der Port gerade auf 1 springt (Steigende Flanke oder Fallende das ist 
egal)

Dann soll die If-Schleife genau 1 Mal durchlanfen werden.

wenn  ich

process (PWM_Phase)
  begin
    if rising_edge(Plus_Taster)            then
      if PWM_Phase < PWM_Phase_MAX
      then
      PWM_Phase <= PWM_Phase + 7;
      end if;
    end if;

    if rising_edge(Minus_Taster  )
            then
      if PWM_Phase > 0
      then
      PWM_Phase <= PWM_Phase - 7;
      end if;
    end if;
  end process;


wenn ich das compeliere kommt die Fehlermeldung:

Error (10821): HDL error at testpwm.vhd(52): can't infer register for 
"PWM_Phase[0]" because its behavior does not match any supported 
register model

Von welchem Typ müssen die Variablen sein?

Oder was ist sonst der Fehler?


Vielleicht hat jemand ander Lösungsvorschläge wie ich eine Variable um 1 
erhöhen kann (Wenn ich einen Taster drücke und eventuell sogar halte).

Danke für die Hilfe
Gast #640405
Lesenswert?

Die sensitivity list passt nicht zum Rest. Abgesehen davon ist das sehr 
schlechter Stil, weil du die Taster als Takt verwenden würdest. Falls 
die nicht entprellt sind, geht das katastrophal nach hinten los.

Besser: Taster evtl. entprellen und dann mit einer state machine (die 
mit dem Systemtakt arbeitet) auswerten.
Gast #640408
Lesenswert?

Ich weiß nicht wie ich das realisieren soll.

Mein Ziel ist es die Variable NUR um einen bestimmten Wert zu erhöhen. 
Wenn ich das Ganze mit dem CLOCK (66 MHz) laufen lasse kann ich ich den 
Taster gar nicht so schlell loslassen.

Hat jemand eine Idee?
#640413
Lesenswert?

In Hardware ausgedrückt nimmt man dafür zwei D-Flipflops am Systemtakt , 
die als 2-Bit-Schieberegister hintereinandergeschaltet sind, man kann 
das auch eine state-machine nennen mit 4 möglichen Zuständen.
Eine steigende Flanke wird mit UND-Verknüpfung der beiden Register 
erkannt. Genau dann wenn das erste schon umgeschaltet hat und das zweite 
noch nicht ist der Ausgang des UND high.
Gast #640422
Lesenswert?

Das Problem löst man, indem man verzögerte Signale für die 
Taster-signale erzeugt, und diese dann in einem geclockten Prozess 
abfragt. Zum Beispiel so (ohne Gewähr):
1
architecture rtl of ... is
2

3
signal plus_taster_delay : std_logic;
4
signal minus_taster_delay : std_logic;
5

6
begin
7

8
process (clk, reset)
9
  begin
10
    if(reset = '0') then
11
      plus_taster_delay  <= '0';
12
      minus_taster_delay <= '0';
13
    elsif(rising_edge(clk)) then
14
      plus_tasterr_delay <= plus_taster;
15
      minus_taster_delay <= minus_taster;
16
      if(plus_taster = '1' and plus_taster_delay = '0') then
17
        if PWM_Phase < PWM_Phase_MAX
18
        then
19
        PWM_Phase <= PWM_Phase + 7;
20
        end if;
21
      end if;
22
      if(minus_taster = '1' and minus_taster_delay = '0') then
23
        if PWM_Phase > 0 then
24
          PWM_Phase <= PWM_Phase - 7;
25
        end if;
26
      end if;
27
    end if;
28
end process;
29

30
end architecture rtl;
Gast #640448
Lesenswert?

ZUM BEITRAG VON     T.M. Gast:

ist in deinem Beispiel plus_taster_delay nicht immer '1' wenn 
plus_taster = '1'

das würde bedeuten (da Prozesse ja sequentiell ablaufen) dass die 
Abfrage:


IF (plus_taster ='1' and plus_taster_delay ='0')

nie erfüllt wäre


Oder täusche ich mich?
Admin Persönliche Seite #640579
Lesenswert?

Eine einfache Flankenerkennung reicht oft nicht, da die Signale von 
mechanischen Tastern prellen und keine sauberen Flanken liefern. Ich hab 
mal schnell ein Beispiel für 8 Taster zusammengehackt (gekürzt, 
Testbench im Anhang):
1
  -- Register
2
  signal state0, state1, state2: std_logic_vector(7 downto 0) := (others => '0');
3
  signal key_pressed_old: std_logic_vector(7 downto 0) := (others => '0');
4
  signal key_pressed: std_logic_vector(7 downto 0) := (others => '0');
5

6
  -- Taster mit langsamem Takt einlesen (3-Bit-Schieberegister je Taste)
7
  -- ce: clock enable mit ca. 1 kHz
8
  process(clk)
9
  begin
10
    if rising_edge(clk) and ce = '1' then
11
      state0 <= key_in;
12
      state1 <= state0;
13
      state2 <= state1;
14
    end if;
15
  end process;
16

17
  -- Mehrheitsentscheidung:
18
  -- 2x '1' => Taste geht in den Zustand "gedrückt"
19
  -- 2x '0' => Taste geht in den Zustand "nicht gedrückt"
20
  -- Vorteil: einzelne Pulse haben keine Auswirkung
21
  process(clk)
22
    variable state: std_logic_vector(2 downto 0);
23
  begin
24
    if rising_edge(clk) then
25
      for i in state0'range loop
26
        state := state2(i) & state1(i) & state0(i);
27
        case state is
28
          when "000" => key_pressed(i) <= '0';
29
          when "001" => key_pressed(i) <= '0';
30
          when "010" => key_pressed(i) <= '0';
31
          when "100" => key_pressed(i) <= '0';
32
          when others => key_pressed(i) <= '1';
33
        end case;
34
      end loop;
35

36
      key_pressed_old <= key_pressed;
37
    end if;
38
  end process;
39

40
  -- Ausgangssignale erzeugen:
41
  -- key_pressed_out: aktueller Zustand der Taste
42
  -- key_down_out: geht für 1 Takt auf '1' wenn Taste gedrückt
43
  -- key_up_out: geht für 1 Takt auf '1' wenn Taste losgelassen
44
  process(key_pressed, key_pressed_old)
45
  begin
46
    key_down_out <= key_pressed and (not key_pressed_old);
47
    key_up_out <= (not key_pressed) and key_pressed_old;
48
    key_pressed_out <= key_pressed;
49
  end process;
Angehängte Dateien:
Gast #640699
Lesenswert?

Auszug aus dem VHDL-Code von Andreas

  process(clk)
  begin
    if rising_edge(clk) and ce = '1' then


Dies ist meiner Meinung nach ein "gated Clock" welches man verhindern
sollte.
Besser wäre:

if rising_edge(clk) then
  if ce = '1' then
   ... Code hier
  end if;
end if;

So gibts nämlich in der Synthese ein getaktetes FF (synchrones Design).

Gruß Volker

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