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 pin3pin1pin5
sekwencyjnie "001"
, "010"
a "100"
.
Podczas skanowania pin3pin1pin5
jak "001"
i wtedy pin4pin6pin7pin2
jest "0100"
po prostu wciśnięte „9”. Deklaruję w VHDL pin4pin6pin7pin2
jako pin3pin1pin5
porty wejściowe i wyjściowe. Kiedy naciskam 6 i 9 w tym samym czasie pin6
i pin7
są high
. 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 pin2
i tak pin4
jest high
.
Oto trudna część. Kiedy naciskam 4 i 6 w tym samym czasie, oczekuję, że pin7
tak będzie, high
ale staje się low
i 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ć!
Poniżej nie przesyłam mojego kodu do tablicy, żaden kod nie jest uruchomiony. Po Pin5
podłączeniu do uziemienia, pojedyncze naciśnięcie przycisku 1,2,4,5,7,8, *, 0 nie włącza Pin3
diody LED, ale jeśli naciśniesz 6, a następnie 4 w tym samym czasie, Pin3
dioda LED jest włączona, a Pin7
dioda nadal świeci, ale gdy mój kod działa, tak się nie dzieje. Może połączyłem coś źle i na szczęście Pin7
jest włączone, nie wiem ...
Poniżej znajdują się schematy płytki klawiatury:
źródło
Odpowiedzi:
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
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 :
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.
źródło
pin4pin6pin7pin2 = "0000"
żadne naciśnięcie klawisza nie jest w rzeczywistości1111
. W moim pytaniu 1s powinno być 0, 0s powinno być 1s, próbowałem trochęout <= 'pin3' when din='1' else '0';
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:
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:
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.
źródło
async_in
jest opóźniony o 3 cykle zegara, ale jego wartość i wszystko jest takie samo?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:
źródło