Maciej
G.
Projektant /
Programista, Famor
S.A.
Temat: Maszyna stanów - sterownik rolet
Witam wszystkich,Zaprojektowałem (moją pierwszą w VHDL) maszynę stanów dla prostego sterownika rolet opartego o układ FPGA i mostek MOSFET do sterowania silniczkiem prądu stałego 12V.
Mostek MOSFET ma piny wejściowe:
pwm : wejście sygnału PWM (do sterowania prędkością silnika)
DIRPIN : kierunek obrotów silnika - gdy 0 to kierunek "do przodu"
SLPPIN : blokada mostka (silnika) - gdy 0 to mostek zablokowany
Mamy teraz rolety na oknie balkonowym sterowane silniczkiem 12V.
Są dwa przyciski (aktywowane sygnałem LOW - 0 logiczne)
bt1 - do zamykania rolet
bt2 - do otwierania rolet
oraz dwa wyłączniki krańcowe
kranc END: 0 -gdy rolety dotrą do końca okna (czyli stan 1 gdy koniec nie został osiągniety)
kranPOC : 0 - gdy rolety są w pełni otwarte (pozycja początkowa)
Mamy 4 stany maszyny:
1) S0 - otwarte
2) S1 - zamykanie (trwa jakiś czas - generowany jest sygnał PWM podawany na mostek)
3) S2 - zamkniete
4) S3 - otwieranie (też trwa jakiś czas - generowany jest sygnał PWM podawany na mostek, tylko kierunek jest odwrotny)
Przejścia:
1) z S0 do S1 gdy ((bt1 = '0') and (krancPOC = '0'))
2) z S1 do S2 gdy ((krancEND = '0') and (krancPOC = '1'))
(tzn. gdy roleta dotrze do końca zakresu - okna)
3) z S2 do S3 gdy ((bt2 = '0') and (krancEND = '0'))
4) z S3 do S0 gdy ((krancPOC = '0') and (krancEND = '1'))
A tak wygląda implementacja maszyny stanów w VHDL:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity DMASM is
Port ( CLK : in STD_LOGIC;
RST : in STD_LOGIC;
bt1 : in STD_LOGIC;--btn zamykanie
bt2 : in STD_LOGIC;--btn otwieranie
krancEND : in STD_LOGIC;--active 0
krancPOC : in STD_LOGIC;--active 0
DIRPIN : out STD_LOGIC;--Direction Motor
SLPPIN : out STD_LOGIC;--SLEEP PIN Mostek
pb1_Zam : out STD_LOGIC;--gdy 0 zamykanie
pb2_Otw : out STD_LOGIC);--gdy 0 otwieranie
end DMASM;
architecture BEHAVE of DMASM is
type STATE is (S0Otwarte, S1Zamykanie, S2Zamkniete, S3Otwieranie);
signal CURRENT_STATE, NEXT_STATE: STATE;
begin
SEQ: process (RST, CLK)
begin
if (RST = '0') then
CURRENT_STATE <= S0Otwarte;
elsif (CLK' event and CLK = '1' ) then
CURRENT_STATE <= NEXT_STATE;
end if;
end process;
COMB: process (CURRENT_STATE, bt1, bt2, krancEND, KrancPOC)
begin
DIRPin <= '0'; --Kierunek: FORWARD
SLPPin <= '0'; --Blokada mostka
pb1_Zam <= '1'; --klawisz nieaktywny
pb2_Otw <= '1'; --klawisz nieaktywny
case CURRENT_STATE is
when S0Otwarte => DIRPin <= '0';SLPPin <= '1';pb1_Zam <= '1';pb2_Otw <= '1';--blokada ALL
if ((bt1 = '0') and (krancPOC = '0')) then
NEXT_STATE <= S1Zamykanie;
else
NEXT_STATE <= S0Otwarte;
end if;
when S1Zamykanie => DIRPin <= '0';SLPPin <= '1';pb1_Zam <= '0';pb2_Otw <= '1';--FORWARD,MOSTEK OTWARTY
if ((krancEND = '0') and (krancPOC = '1')) then
NEXT_STATE <= S2Zamkniete;
else
NEXT_STATE <= S1Zamykanie;
end if;
when S2Zamkniete => DIRPin <= '1';SLPPin <= '0';pb1_Zam <= '1';pb2_Otw <= '1';--blokada ALL
if ((bt2 = '0') and (krancEND = '0'))then
NEXT_STATE <= S3Otwieranie;
else
NEXT_STATE <= S2Zamkniete;
end if;
when S3Otwieranie => DIRPin <= '1';SLPPin <= '1';pb1_Zam <= '1';pb2_Otw <= '0';--BACKWARD,MOSTEK OTWARTY
if ((krancPOC = '0') and (krancEND = '1')) then
NEXT_STATE <= S0Otwarte;
else
NEXT_STATE <= S3Otwieranie;
end if;
end case;
end process;
end BEHAVE;
Czy tak zaprojektowana maszyna stanów jest poprawna?
(Syntetyzuje się bez błędów, czy ostrzeżeń w "ISE WabPack Xilinx).
Gdyby ktoś miał jakieś uwagi dot. ulepszenia kodu byłbym wdzięczny.
Ta maszyna stanów jest częścią większego projektu sterownika rolet na CPLD/FPGA (który zamierzam praktycznie użyć)
PozdrawiamTen post został edytowany przez Autora dnia 13.09.17 o godzinie 16:03