Naciśnięcie tego samego wiersza klucza w tym samym czasie

9

Projektuję klawiaturę w VHDL. Wszystko działa dobrze po naciśnięciu tylko jednego klawisza. Skanuję każdą kolumnę w poszukiwaniu naciśnięcia klawisza w maszynie stanów i kiedy żaden klawisz nie jest wciśnięty, co jest warunkiem, pin4pin6pin7pin2 = "0000"że przełączam się do następnego stanu w celu skanowania następnej kolumny. W ten sposób mogę ustawić kolumny pin3pin1pin5sekwencyjnie "001", "010"a "100".

Podczas skanowania pin3pin1pin5jak "001"i wtedy pin4pin6pin7pin2jest "0100"po prostu wciśnięte „9”. Deklaruję w VHDL pin4pin6pin7pin2jako pin3pin1pin5porty wejściowe i wyjściowe. Kiedy naciskam 6 i 9 w tym samym czasie pin6i pin7high. Pierwszy naciśnięty klawisz jest czytany, drugi jest ignorowany. Kiedy naciskam 3 i 7 w tym samym czasie, pierwszy naciśnięty z kilkoma ms przed wygraną i pierwszy klawisz jest czytany, drugi klawisz jest ignorowany pin2i tak pin4jest high.

Oto trudna część. Kiedy naciskam 4 i 6 w tym samym czasie, oczekuję, że pin7tak będzie, highale staje się lowi pin4pin6pin7pin2 = "0000", czego nie rozumiem, jak i dlaczego. Ponieważ "0000"jest wykrywany jako brak naciśnięcia klawisza, automat stanowy przeskakuje ze stanu do stanu. Przytrzymując 4 i 6, jeśli ktoś popycha i opuszcza 4 kilka razy, jest wykrywany jako 6 wciśnięty kilka razy, co jest dużym błędem . Byłbym zadowolony, jeśli możesz mi pomóc w debugowaniu tego!

To samo dzieje się z „1” i „2”, to samo z „7” i „8” tylko dla klawiszy w tym samym rzędzie. Ponieważ jest to projekt ciągły, nie mogę umieścić mojego kodu VHDL online :( Byłbym szczęśliwy, gdybyś mógł dać mi wskazówki, jak to rozwiązać!

wprowadź opis zdjęcia tutaj

Poniżej nie przesyłam mojego kodu do tablicy, żaden kod nie jest uruchomiony. Po Pin5podłączeniu do uziemienia, pojedyncze naciśnięcie przycisku 1,2,4,5,7,8, *, 0 nie włącza Pin3diody LED, ale jeśli naciśniesz 6, a następnie 4 w tym samym czasie, Pin3dioda LED jest włączona, a Pin7dioda nadal świeci, ale gdy mój kod działa, tak się nie dzieje. Może połączyłem coś źle i na szczęście Pin7jest włączone, nie wiem ...

wprowadź opis zdjęcia tutaj

Poniżej znajdują się schematy płytki klawiatury:

Schematy

Anarkie
źródło
W jaki sposób upewniasz się, że jednoczesne naciśnięcie 4 i 6 nie powoduje zwarcia pinów 3 i 5 razem?
fru1tbat
@ fru1tbat Czy możesz opracować krótką chwilę więcej? Bez przesyłania kodu, gdy płyta nie ma nic, podłączam pin 5 do uziemienia, następnie dioda LED pin5 świeci, a następnie wciskam „6” dioda LED pin7 świeci się później naciskam „4” i „6” w tym samym czasie pin3 Dioda LED świeci, a dioda LED pin7 nadal świeci.
Anarkie
@Masz na myśli, że powinienem używać pull-up dla wierszy i pull-up dla kolumn? Nie mogę zmodyfikować obwodu. Również nie rozumiem wiele z twojego komentarza :(
Anarkie
Aby być bardziej kompletnym, udzielę odpowiedzi. Przydałoby się przedstawienie schematu pokazującego rezystory, diody LED, sterowniki kolumn oraz wszelkie falowniki lub tranzystory, które mogą znajdować się w obwodzie. Czy 4 rzędy i 3 kolumny są podłączone bezpośrednio do CPLD lub FPGA?
Tut
@Tut Klawiatura nie jest bezpośrednio podłączona do FPGA, pomiędzy nimi jest inna płytka, do podłączenia różnych płyt do FPGA i dodałem schematy.
Anarkie

Odpowiedzi:

4

Krótka odpowiedź:

Odwróć swoją logikę. Kieruj liniami wyboru kolumny z logiką open-drain (lub open-collector), w której wybrana kolumna jest wciągana nisko, a niewybrane kolumny są pływające. Gdy spojrzysz na wiersz, naciśnięcie klawisza zostanie wykryte przez „0”. Niewciśnięte klawisze zostaną wykryte przez „1”.

Teraz szczegóły:

Jak wskazuje EEIngenuity, naciśnięcie 2 przycisków w tym samym rzędzie powoduje zwarcie między odpowiadającymi im kolumnami. Ten (i inne problemy związane z wieloma naciśnięciami klawiszy) zwykle rozwiązuje się w matrycy klawiatury, dodając diodę szeregowo do każdego przełącznika.

Ponieważ dodawanie diod nie jest dla ciebie opcją, będziesz musiał przesunąć wyjścia nieaktywnych zaznaczeń kolumn, aby uniknąć próby doprowadzenia ich do przeciwnej biegunowości, jak w przypadku wyboru kolumny aktywnej. Odbywa się to za pomocą logiki open-drain. Jeśli wybrane kolumny są powiązane bezpośrednio z CPLD lub FPGA, powinno być to możliwe w kodzie VHDL.

Zdjęcie w twoim pytaniu pokazuje, że masz rezystor podciągający na każdej kolumnie i każdym rzędzie. Podciągnięcia na kolumnach są niepotrzebne, ale niczego nie skrzywdzą. Podciągnięcia w każdym rzędzie zapewnią wysoki stan, chyba że zostanie pociągnięty nisko przez sterownik otwartego spustu w kolumnie (poprzez zamknięty przełącznik).

Musiałem poczynić pewne założenia dotyczące twojego obwodu, ponieważ nie dostarczyłeś kompletnego schematu ani kodu VHDL. Mówisz

gdy nie zostanie naciśnięty żaden klawisz, co jest warunkiem pin4pin6pin7pin2 = „0000”

jeszcze z dostarczonego zdjęcia pokazano rezystory podciągające. Oznacza to, że masz już gdzieś inwersję logiki, być może w kodzie VHDL lub (mniej prawdopodobne) falowniki między wierszami a urządzeniem logicznym (CPLD lub FPGA).

Edytować:

Zgodnie z komentarzem w opisach używasz logiki ujemnej: „0000” oznacza, że ​​wszystkie cztery piny są wysokie itp. W takim przypadku, zakładając, że kolumny wybierają i sygnały rzędu przechodzą bezpośrednio ze złącza 2 na schemacie do FPGA, po prostu postępuj zgodnie z moimi wskazówkami powyżej, używając logiki open-drain dla wyjść wyboru kolumny w FPGA.

Nie jestem ekspertem od VHDL, ale znalazłem to w Xilinx :

Odnieś bufor bufora otwartego przy użyciu następującego kodu:

VHDL:

dout <= „Z” when din = „1” else „0”;

Zwróć również uwagę na schemacie, że wszystkie diody LED są pokazane okablowane do tyłu. Anody idą do oporników ograniczających prąd, a katody do linii sygnałowych. Diody LED zapalają się, gdy linie sygnałowe są nisko wyciągnięte.

Akord
źródło
Zaraz zeskanuję schematy instalacji sterownika skanera
Anarkie
Masz rację, że pin4pin6pin7pin2 = "0000"żadne naciśnięcie klawisza nie jest w rzeczywistości 1111. W moim pytaniu 1s powinno być 0, 0s powinno być 1s, próbowałem trochę
zaszyfrować
Dodałem schematy.
Anarkie
dziękuję bardzo za wyjaśnienia, po przeczytaniu twojej odpowiedzi mam kilka pomysłów, ale najpierw co masz na myśli mówiąc „kolumny są zmienne”, „trzeba przenieść dane wyjściowe”, przez słowo zmienne masz na myśli: 110, 101, 011? Robię to już, właściwie w moim kodzie po naciśnięciu klawisza, wszystkie inne klawisze powinny zostać zignorowane. Po prostu nie rozumiem, jak dioda LED gaśnie, a pin7 staje się wysoki (1), podczas gdy kod jest uruchomiony. Zresztą gdybym zrozumiał prawidłowe jest rozwiązanie sugeruje natomiast Im skanowania Pin5, porty wyjściowe „110”, powinien mieć out <= 'pin3' when din='1' else '0';
Anarkie
1
Spójrz na link, który podałem: open-drain (lub open-collector) . Aktywną kolumnę wybiera się, napędzając 0 V w tej linii kolumny. Nieaktywne kolumny NIE powinny być zasilane napięciem 3,3 V na tej linii, ale muszą być pływające (wprowadzone w stan wysokiej impedancji), który skutecznie odłączy te linie od obwodu. Jeśli spróbujesz doprowadzić je do 3,3 V, zwarcie powstałe przez naciśnięcie 2 przycisków w tym samym rzędzie w tym samym czasie spowoduje konflikt między jednym, który próbuje jechać nisko, a innymi, które próbują jechać wysoko.
Tut
2

Ponieważ używasz VHDL i masz asynchroniczne dane wejściowe, piszę tę odpowiedź, aby upewnić się, że podjąłeś środki ostrożności. Nie jestem pewien, czy to jest twój problem, ale tak może być.

Zobacz pytanie, które zadałem jakiś czas temu: VHDL: moduł odbiorczy losowo kończy się niepowodzeniem podczas zliczania bitów

Teraz mówicie, że:

Ponieważ „0000” jest wykrywane jako brak naciśnięcia klawisza, automat stanowy przeskakuje ze stanu do stanu. Przytrzymując 4 i 6, jeśli ktoś popycha i opuszcza 4 kilka razy, jest wykrywany jako 6 wciśnięty kilka razy, co jest dużym błędem.

Co jest nieco podobne do tego, z czym miałem do czynienia. Miałem problem z tym, że moja maszyna stanowa pomijała stany, co wydawało się niemożliwe.

Jeśli przeczytasz odpowiedzi na powyższe pytanie, zobaczysz, że zaleca się dodanie synchronizatora do linii wejściowej przed wprowadzeniem go do maszyny stanu. Zazwyczaj osiąga się to za pomocą dwóch klap D w serii:

wprowadź opis zdjęcia tutaj

Brak synchronizacji wprowadzania przycisków z twoim sprzętem powoduje bardzo dziwne problemy, których doświadczyłem w moim projekcie N64. Dodanie tej odrobiny HW było prawie jak magia.

Sprawdź najpierw, czy dane wejściowe są synchronizowane.

Nick Williams
źródło
Wdrożenie Synchronizatora w odpowiedzi nie wydaje się trudne, ale kiedy czytam ten proces, rozumiem, że async_injest opóźniony o 3 cykle zegara, ale jego wartość i wszystko jest takie samo?
Anarkie
Duża różnica polega na tym, że sygnał zostanie przekonwertowany z asynchronicznego na synchroniczny. To, co dzieje się w HW czasami z sygnałami asynchronicznymi (jak twoje przyciski), polega na tym, że bity są w „meta-stabilności”, co powoduje bardzo dziwne błędy w HW. Używając klapek D upewnij się, że meta-stabilność nie występuje w twoim projekcie. Byłem również sceptyczny co do skuteczności tego, ale to doskonale rozwiązało mój problem.
Nick Williams
Próbowałem, warto spróbować, ale nie
pomogłem
1

To interesujące pytanie! Powód, dla którego widzisz niski poziom na pin7 po naciśnięciu klawisza 4 i key6, to z powodu pin3 i pin5.

Aby wyjaśnić dalej, pin3 i pin5 nigdy nie będą jednocześnie wysokie - jedna z nich zawsze będzie ścieżką do ziemi (zgodnie z twoim projektem). Tak więc, kiedy naciśniesz klawisz 4 i klawisz 6, tworzysz ścieżkę do uziemienia dla pin7.

Zobacz zdjęcie:

Pin 7 widzi ścieżkę do ziemi.  Masz zwarcie.

Miron V.
źródło
Dodałem zdjęcie do mojego pytania, a pin7 wygląda nadal wysoko po naciśnięciu obu klawiszy.
Anarkie
OP wyjaśnił, że nie podnosi jednocześnie pinów 3, 1 ani 5 HIGH. Sekwencjonuje kolumny następującymi słowami: „001”, „010” i „100. Piny 3 i 5 nigdy nie są WYSOKIE jednocześnie.
Nick Williams
1
Taki właśnie jest punkt @EEIngenuity - istnieje widoczna ścieżka między pinami 3 i 5, która nigdy nie będzie miała takiej samej wartości ”, dlatego kiedy naciśniesz klawisz 4 i klawisz 6, tworzysz ścieżkę do uziemienia dla pin7. „
fru1tbat
1
@Anarkie Na zdjęciu Pin3 nie jest podłączony do GND ani VDD. Jest to pływający węzeł. To nie tworzy scenariusza zwarcia, który masz w pierwotnej wersji próbnej. Spróbuj podłączyć styk 3 do VDD i styk 5 do GND i powtórz ten test.
Miron V
1
@EEIngenuity Masz absolutną rację !!! Tak, tak, kiedy podłączę pin 3 do VDD, pin7 staje się niski !!! Więc pomóż mi, jak mogę rozwiązać ten problem i sprawić, by działał :( Używam VHDL, a także inny kolega, który pracuje w tym samym projekcie w innym zespole, nie ma tego problemu, więc jakoś go rozwiązał, ale nie nie wiem jak, ta sama klawiatura, ta sama tablica!
Anarkie