Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

sterowanie silnikiem krokowym w VHDL-u

Masster 19 Sty 2005 21:35 2466 4
  • #1 19 Sty 2005 21:35
    Masster
    Poziom 32  

    Witam!

    Muszę na jeden z projektów oddać model sterowania silnikiem krokowym w VHDL-u. Zrobiłem płytkę według schematu (w załączniku) płytka będzie wtykana w złącze na zestawie dydaktycznym ze SPARTAN-em. Napisałem do tego program narazie prosty, po naciśnięciu jednego przycisku silnik ma wykonać pełen obrót w lewo a po naciśnięciu drugiego to samo tylko, że w prawo. Nie mogę sprawdzić go fizycznie w laboratorium z niezależnych odemnie przyczyn :( Proszę o sprawdzenie i wytknięcie ewentualnych błędów. Szczególnie niepokoi mnie konstrukcja pętli FOR i czy aby nie zamknąć tego wszystkiego w process?
    Kod programu:

    Code:
    entity SK is
    
       generic (delay : delay_lenght := 10 ms);
       port (x,y : in bit;
             wyjscie : out std_ulogic_vector(3 downto 0));
    end entity SK;

    arhchitecture A of SK is
    variable z : std_ulogic_vector (47 downto 0);
    begin
       if x='1' then
          for z in 0 to 47 loop
             wyjscie <= "1010";
             wyjscie <= "0110" after delay;
             wyjscie <= "0101" after delay;
             wyjscie <= "1001" after delay;
             wyjscie <= "1010" after delay;
          end loop;
       end if

       if y='1' then
          for z in 0 to 47 loop
             wyjscie <= "1010";
             wyjscie <= "1001" after delay;
             wyjscie <= "0101" after delay;
             wyjscie <= "0110" after delay;
             wyjscie <= "1010" after delay;
          end loop;
       end if
    end architecture A;


    Jest to moje pierwsze "dziecko" w VHDL-u proszę więc o wyrozumiałość ;)
    Na schemacie układ IC1 to ULN2803 a IC2 to 7812 silnik podłączany do złącza CON3 odpowiednio od pierwszego uzwojenia A1,A2,B1,B2,Vcc,Vcc.
    Ewentualnie może ktoś ma pomysł na przeróbkę programu aby robił po np. trzy krotnym przyciśnięciu przycisku trzy kroki w jedną bądź drugą stronę?

    Za wszelkie sugestje dziękuję.

    0 4
  • #2 23 Sty 2005 00:46
    Zbych_
    Poziom 24  

    Nie jestem specem od VHDL, ale na pierwszy rzut oka widać, że traktujesz ten język jak język do pisania programów, a nie język opisu sprzętu. Po pierwsze, żeby wygenerować kolejne stany na wyjściu to trzeba zbudować automat synchroniczny (w twoim przypadku taktowany 100Hz). Wyzwalanie tego automatu możesz zrobić przy pomocy linii do której masz podpięty przycisk. Po drugie instrukcji delay można używać tylko w symulacji. W rzeczywistych układach nie określasz czasu propagacji, jest on skutkiem takiej a nie innej budowy układu.
    Pętla for może ci pomów w wygeneraowaniu tablicy stanów automatu, ale na pewno w taki, jak w twoim kodzie, sposób nie zbudujesz układu sekwencyjnego.

    0
  • #3 23 Sty 2005 18:43
    Masster
    Poziom 32  

    Jak już pisałem wcześniej to mój pierwszy program i zdaję sobie sprawę z tego, że nie jest doskonały i prawdopodobnie nie będzie działał. W międzyczasie znalazłem program do sterowania silnika krokowego na www.opencores.org.. Pojawił się cień nadzieji na przetestowanie tego w akcji na laboratorium ale to nic pewnego...

    0
  • #4 24 Sty 2005 09:25
    strdaniel
    Poziom 20  

    przykro mi ale ukłąd nie będzie działał za chiny !!

    przede wszystkim wszystkie układy fpga mają zegar i muszą działać na clk .. zegar podawany jest z zewnątrz za pomocą kawrca na przykład..
    no i opóźnienie musi być odliczane na tym zegarze.
    Nie można sobie odliczać opóźnienia na podstawie wartości bo niby skąd układ ma wiedzieć jak to odliczyć (trzeba sobie zaprojektowac timer)
    to po pierwsze

    po drugie modele w vhdl-u projektuje się na podstawie procesów lub gotowych elementów np. bramek, liczników, muxów itd.
    musisz napisac process .. teraz nie mam za bardzo czasu ale postaram się na jutro sklecić jakiś układ ktory będzie działał poprawnie oczywiście jeśli chcesz
    pozdrawiam

    0
  • #5 24 Sty 2005 14:39
    Masster
    Poziom 32  

    Mam działający, dziś przetestowany program. Po naciśnięciu przycisku robi jeden krok w jedną bądź w drugą stronę i o to chodzi. Teraz muszę dorobić coś takiego, że mam 8 przełączników (8 bitów) i dwa przyciski astabilne no i jak wcisnę jeden przycisk to silnik zrobi mi tyle kroków ile jest nastawione na przełącznikach w jedną sronę a jak wcisnę drugi to to samo tylko w drugą.
    Jakbyś mógł coś takiego sklecić to bym był dozgonnie wdzięczny.

    Kod programu:

    Code:
    library IEEE;
    
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    entity StepperMotorPorts is
        Port (   
          StepDrive : out std_logic_vector(3 downto 0);
           clock : in std_logic;            
           Direction : in std_logic;         
           StepEnable : in std_logic;         
           ProvideStaticHolding : in std_logic      
          );
    end StepperMotorPorts;

    architecture StepDrive of StepperMotorPorts is

       signal state : std_logic_vector(1 downto 0);         
       signal StepCounter : std_logic_vector(31 downto 0);         
       constant StepLockOut : std_logic_vector(31 downto 0) := "00000000000000110000110101000000";
       
       signal InternalStepEnable : std_logic;            

    begin

    process(clock)
    begin
       if ( (clock'Event) and (clock = '1') ) then   

          StepCounter <= StepCounter + "0000000000000000000000000000001";

          if (StepEnable = '1') then

             InternalStepEnable <= '1';    

          end if;

          if (StepCounter >= StepLockOut) then

             StepCounter <= "00000000000000000000000000000000";      

             if (ProvideStaticHolding = '1') then

                StepDrive <= "0000";

             else

                StepDrive <= "1111";

             end if;




                
             if (InternalStepEnable = '1') then

                InternalStepEnable <= StepEnable;                            
                                                                
                   if (Direction = '1') then state <= state + "01"; end if;
                   if (Direction = '0') then state <= state - "01"; end if;
                                                    case state is

                   when "00" =>

                      StepDrive <= "1100";         
                         
                   when "01" =>
          
                      StepDrive <= "1001";
                         
                   when "10" =>
          
                      StepDrive <= "0011";         
                         
                   when "11" =>
          
                      StepDrive <= "0110";
                         
                   when others =>

                end case;
       
             end if;
       
          end if;

       end if;

    end process;

    end StepDrive;

    0