Forum: FPGA, VHDL & Co. VHDL counter


von sensor (Gast)


Lesenswert?

Hallo Leute,
ich will die Anzahl von positive Signalwerte eines Sensor hochzählen.
Aber ich will immer jedes mal ab 0 zählen wenn sich die richtung ändern.

Also mein System ist ein Schrittmotor an dem ich ein Inkremental 
Drehgeber auf den Rotor befestig habe. Ich will dass, wenn sich das Moto 
Rechts oder links dreht , dass das signal von dem Inkremental ab dem 
Zeitpunk wo sich die Richtung gewechsel hat gezählt wird.
wenn das counter  200  erreicht soll der Ausgang, das für mich das 
Erreichen von 200 des Counter bedeutet signalisiert ( von 0 auf 1 gehen)

Der Sensor_ink ist mein sensorsignal und der ist in andere Process schon 
deklariert und difiniert wann er 1 oder 0 ist. Also der ist genau ein 
pegelsignal das mit der schrittfrequenz des Motors läuft.


hier ist das Process dafür, aber mein counter zählt nicht hoch.
Auch wie kann ich machen, dass bein Änderung der Richtung, der Zählstand 
genau bei 0 anfängt


Danke.



PROCESS (inkr_A,Richtung)

    BEGIN

    Ausgang <='0';

    IF Richtung ='1'  then

          if Sensor_inkr = '1' then

                      --inkr_count <= inkr_count + 1;

                             IF inkr_count = "11001000" THEN

                                  inkr_count <= (others => '0');

                                  Ausgang <= not Ausgang ;
                            ELSE
                                 inkr_count <= inkr_count + 1;

                                     End IF;
           ELSE

                       inkr_count <= inkr_count ;


                            END IF;


     ELSIF Richtung ='0'  then

                        if Sensor_inkr = '1' then

                             IF inkr_count = "11001000" THEN

                                  inkr_count <= (others => '0');

                                  Ausgang <= not Ausgang ;

                             ELSE

                                 inkr_count <= inkr_count + 1;

                             End IF;

                        ELSE
                                 inkr_count <= inkr_count;

                        End IF;

    End IF;


 END PROCESS;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

> aber mein counter zählt nicht hoch.
Wie hast du das festgestellt?

> hier ist das Process dafür, aber mein counter zählt nicht hoch.
Das ist kein Zähler, sondern nur eine kombinatorische Schleife.

Zähler können in FPGAs nur aus Flipflops gebaut werden. Und Flipflops 
brauchen einen TAKT, um Daten zu übernehmen und damit den Zähler 
weiterzuschalten. Hast du dir mal angesehen, wie Andere einen Zähler 
programmieren? Hast du verstanden, warum sie das so geamcht haben?

In VHDL sieht ein Zähler immer etwa so aus:
1
    process (clk) begin
2
        if rising_edge(clk) then 
3
            if (dies und das...) then
4
                counter <= counter+1;
5
            end if;
6
            if (counter>1000) then
7
                counter <= 0;
8
            end if;
9
        end if;
10
    end process;

von Alexis S. (seraptin)


Lesenswert?

Ich haette hier einen 4/8Bit Zaehler mit Clear fuer dich.

http://paste.frubar.net/12545

Der Reset 'rb' und der Clear 'clr' sind low-activ. Der Reset ist 
asynchron Immer wenn der Enable auf high ist und ein Clocksignal kommt 
wird der Counter um eins hochgezaehlt.

Du muesstest jetzt nurnoch den clr immer zum richtigen Zeitpunkt 
bringen, also bei Richtungsaenderung oder erreichen von 200.

von sensor (Gast)


Lesenswert?

Schon danke Miller,
ich habe in andere Process schon definiert wann mein Signal auf 1 oder 0 
geht und zwar mit dem Tak und einem Zähler genauso wie du hier 
beschrieben hast.
aber mein Problem ist ich will nur hochzählen wenn Sensor_inkr auf eins 
geht und von vorne an anfangen zu zählen wenn sich die Richtung ändern
das heisst der sensor_ink ist hier wie mein neue CLock.

oder nehmen wir an dass der TAK genau der Clcok ist.
wie zählen ich wider von vorne an wenn Richtung sich ändern??


1
PROCESS (clk)
2
3
    BEGIN
4
5
    Ausgang <='0';
6
7
    IF Richtung ='1'  then
8
9
          if rising_edge(clk) then
10
11
                      --inkr_count <= inkr_count + 1;
12
13
                             IF inkr_count = "11001000" THEN
14
15
                                  inkr_count <= (others => '0');
16
17
                                  Ausgang <= not Ausgang ;
18
                            ELSE
19
                                 inkr_count <= inkr_count + 1;
20
21
                                     End IF;
22
           ELSE
23
24
                       inkr_count <= inkr_count ;
25
26
27
                            END IF;
28
29
30
     ELSIF Richtung ='0'  then
31
32
                        if rising_edge(clk) then
33
34
                             IF inkr_count = "11001000" THEN
35
36
                                  inkr_count <= (others => '0');
37
38
                                  Ausgang <= not Ausgang ;
39
40
                             ELSE
41
42
                                 inkr_count <= inkr_count + 1;
43
44
                             End IF;
45
46
                        ELSE
47
                                 inkr_count <= inkr_count;
48
49
                        End IF;
50
51
    End IF;
52
53
54
 END PROCESS;

von Alexis S. (seraptin)


Lesenswert?

Hier nochmal mit richtigem Code-Highlighting. Das musste auf der Seite 
erst nachgeruestet werden ;)

http://paste.frubar.net/12548

von sensor (Gast)


Lesenswert?

Danke Alexis,
ich schaue mir das gerade.

von Alexis S. (seraptin)


Lesenswert?

1
 ELSE
2
3
                       inkr_count <= inkr_count ;
4
5
6
                            END IF;

Was soll denn das bezwecken ??

Paste doch mal das relevante Design incl. Signaldeklaration etc. in den 
Pastebin. Mit nur dem Ausschnitt fehlen einem einige Informationen.

Wenn z.B. Richtung immer auf '1' oder auf '0' ist muesste dein Signal 
mit jedem Clock hochgezaehlt werden. Das ist ja auch nicht das was du 
willst, oder?


Btw. Meine Counter sind natuerlich etwas aufwendiger zu schreiben, 
dafuer weiss ich aber auch genau was passiert und muss mich nicht auf 
das Synthesetool verlassen :)

von sensor (Gast)


Lesenswert?

Hallo Alex ,
hier das comlpete code.

http://paste.frubar.net/12550

mit
1
ELSE
2
    inkr_count <= inkr_count ;
3
          END IF;
meinte ich ,dass es nicht hochzählt wenn die Bediegung nicht erfüllt 
ist.

mein Sensor_ink bekomme ich von der Ausgang meines Inkrementalgebers 
wenn der Motor sich dreht. der ist ein 0 - 3.5V Signal, dass ich am 
Eingangspin meines FPGA angelegt habe, das heisst mein system erkennt 
dann automatisch wenn er 0 ( für 0)oder 1 (für 3,5V) ist und bedingt 
dann meine Zählung für die drehzahlt. Also bein erreichen von 200 
hochzählen ist de sensor_out auf 1 gesetzt, dass heisst eine volle 
umdrehung des Rotor.

ich hoffe ich hätte so weit mein Sytem geklärt.

von sensor (Gast)


Lesenswert?

Noch mal Alex,
 mein FPGA- Board hat 48MHz, also sehr sehr schnell
 mit:
1
IF rising_edge(clk) THEN
2
3
                  IF enable_in ='0' THEN
4
                       IF counter ="00001000000000011111" THEN
5
                            counter <= (others => '0');          
6
                              schritt_freq <= not schritt_freq;
7
                          counter1 <= counter1 + '1';                        
8
                                ELSE
9
                           counter <= counter + '1';
10
11
                        END IF;

teile ich mein clock  durch 32799 und habe dann eine neue frequenze mit 
der ich meine Motoschritte ansteurn kann. und der Schritt ist hier duch 
counter1 gesteuert. Also bei
1
"00"
 erste Schritt  bei
1
"01"
 zweite Schritt und so weiter...

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
Noch kein Account? Hier anmelden.