Skocz do zawartości

Maszyna stanów z dwoma przyciskami


kaper93

Pomocna odpowiedź

Potrzebuję pomocy ze stworzeniem maszyny stanów reagującą na zbocza z dwóch przycisków. W zależności od aktualnego stanu i nacisnietego przysicku przechodzimy w inny stan. pb1 i pb2 są sygnałami z debouncera przycisków SW1, SW2. Dla uproszczenia załóżmy ze SW1 przechodzi w krok następny, a SW2 w poprzedni. Napisałem kod na jeden przycisk i działa ładnie.

process(pb1)
begin
if (rising_edge(pb1)) then 

case sb is
	when ST0 => 
		if pb1 = '1' then sn<=ST1;
		else sn<=ST0;
		end if;

	when ST1 => 
		if pb1 = '1' then sn<=ST2;
		else sn<=ST1;
		end if;

	when ST2 => 
		if pb1 = '1' then sn<=ST3;
		else sn<=ST2;
		end if;

	when ST3 => 
		if pb1 = '1' then sn<=ST4;
		else sn<=ST3;
		end if;


	when ST4 =>
		if pb1 = '1' then sn<=ST5;
		else sn<=ST4;
		end if;

	when ST5 => 
		if pb1 = '1' then sn<=ST0;
		else sn<=ST5;
		end if;
	when others => sn<=ST0;

end case;
end if;

end process;

process(sn,CLK)

variable dif : std_logic_vector (24 downto 0);

begin
if rising_edge (CLK) then
	dif := dif + 1;
	if (dif = 250000) then sb <= sn;
		dif := (others => '0');
	end if;
end if;
end process;

process(sb)
   begin
case sb is
when ST0 => D <= "000001";
when ST1 => D <= "000010";
when ST2 => D <= "000100";
when ST3 => D <= "001000";
when ST4 => D <= "011000";
when ST5 => D <= "100000";
end case;
end process;	
Link do komentarza
Share on other sites

Piękny kod, ale po co to?

Lepiej napisać tak (kod w C, a ty chyba piszesz w Bascomie, ale powinieneś widzieć o co chodzi)

//definicje ile mamy stanów
#define MAX_STATE (10) //w praktyce zmienna aktStan będzie w przedziale od 0 do MAX_STATE-1 czyli tutaj od 0 do 9
//zmienna informująca o aktualnym stanie
int aktStan = 0;

...

//kod funkcji do sprawdzania stanu klawiszy
void sprKlawisze()
{
 if (rising(pb1)) aktStan++;
 if (rising(pb2)) aktStan--;
 if (aktStan==MAX_STATE) aktStan = 0; //sprawdź czy nie wyszliśmy w górę
 if (aktStan<0) aktStan = MAX_STATE-1; //sprawdź czy nie wyszliśmy w dół
 wykonaj_cokolwiek_chcesz_dla_stanu(aktStan); // wykonanie odpowiedniej funkcji dla aktStan;
}

...

Do tego możesz zrobić enumerację stanów, żeby nie używać liczb tylko nazw typu STAN_PAUZA, STAN_START, STAN_KONIEC itp.

Mam nadzieję, że to da Tobie pomysł jak dużo łatwiej to rozwiązać.

Link do komentarza
Share on other sites

Piszę w VHDL'u na Atlerze Cyclone I. Do zrealizowania mam maszynę stanów jak na zdjęciu. Ogółem jest to projekt stopera liczącego do 99,99s, który już działa, muszę jeszcze uwzględnić jego działanie od konkretnego stanu (np. zatrzymanie pomiaru, start pomiaru, pomiar w pętli)

Siedzę nad tym od rana, i już zaczyna brakować mi pomysłów... Jeżeli ktoś wie jak to rozwiązać proszę o pomoc.

EDIT:

Ten kod realizuje to co chcę, jednak nie ma obsługi zboczy. Problemem jest to żę nie mogę umieścić dwóch rising_edge w jednym procesie, tak aby badać oba przyciski.

process(pb1,pb2)
begin
	--if rising_edge(pb1) then 
	case sb is
	when ST0 =>
		if pb1 = '1' then sn<=ST1;
		else sn<=ST0;
		end if;

	when ST1 => 
		if pb1 = '1' then sn<=ST2;
		elsif pb2 = '1' then sn<=ST3;
		else sn<=ST1;
		end if;

	when ST2 => 
		if pb1 = '1' then sn<=ST1;
		elsif pb2 = '1' then sn<=ST0;
		else sn<=ST2;
		end if;

	when ST3 =>
		if pb1 = '1' then sn<=ST4;
		elsif pb2 = '1' then sn<=ST1;
		else sn<=ST3;
		end if;


	when ST4 =>
		if pb2 = '1' then sn<=ST5;
		else sn<=ST4;
		end if;

	when ST5 => 
		if pb2 = '1' then sn<=ST0;
		else sn<=ST5;
		end if;

	when others => sn<=ST0;

	end case;
--end if;
end process;
Link do komentarza
Share on other sites

Nie znam na tyle VHDL-a żeby napisać kod, ale o ile pamiętam można to rozwiązać następująco:

Wprowadzasz 2 nowe sygnały: old_pb1, old_pb2. Nowym sygnałom przypisujesz wartość z poprzedniego odczytu. Razem masz 4 sygnały, możesz je po prostu traktować jako kombinacje (pb1, old_pb1, pb2, old_pb2) np.

0000 -> nic się nie zmieniło

0100 -> zbocze opadające na pb1

itd.

  • Lubię! 1
Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Dla Elvis'a leci piwo oraz wielkie podziekowania za pomoc 🙂 Siedziałem w zasadzie cały świateczny dzień nad tym jednym problemem i udało się 😃

kaper93, jaki związek z forum na "stoper"?

Szukałem pomocy z FPGA, znalazłem tu dział im poświęcony, więc opisałem swój problem. Sądziłem ze znajdę tu osoby chętne do pomocy (w przeciwieństwie m.in do elektrody), jeżeli uważasz że moje pytanie to zaśmiecanie, ok sorry, usuń temat i po sprawie... 🙄

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.