Serwis Edukacyjny w I-LO w Tarnowie Materiały dla uczniów liceum |
Wyjście Spis treści Wstecz Dalej Autor artykułu: mgr Jerzy Wałaszek |
©2024 mgr Jerzy Wałaszek |
W tym artykule zaprojektujemy prosty czytnik klawiatury numerycznej (trochę mniej skomplikowanej od tej po lewej stronie). Nasz układ będzie odczytywał wciśnięcia pojedynczych klawiszy numerycznych 0,1,...,9 i zamieniał je na kod binarny 8421, który pojawi się na wyjściu urządzenia.
Kod 8421 jest naturalnym, czterobitowym kodem. Jeśli bity zapiszemy numerując je od ostatniego:
b 8 b 4 b 2 b 1 |
to bit o stanie 1 posiada wartość:
b 8 = 8, b 4 = 4, b 2 = 2 i b 1 = 1 |
stąd nazwa kodu 8421. Bit o stanie 0 ma wartość 0. Na przykład zapis:
0110 |
oznacza liczbę 6, ponieważ:
b 8 = 0, b 4 = 4, b 2 = 2 i b 1 = 0 |
Gdy zsumujemy poszczególne wagi, otrzymamy 6. Poniższa tabelka podaje wartości kolejnych cyfr dziesiętnych w kodzie 8421.
Kod 8421 | 0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
Cyfra | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
Umówimy się, iż nasz czytnik będzie dawał na wyjściu kod 1111, gdy żaden klawisz nie jest naciśnięty. Łatwo zauważyć, iż kod 1111 nie reprezentuje w kodzie 8421 żadnej cyfry dziesiętnej - jest to zatem "bezpieczna" wartość. Każdy klawisz będzie zwykłym przyciskiem, który, w przypadku naciśnięcia, zewrze linię klawisza do masy, czyli wymusi poziom logiczny 0. Gdy klawisz nie jest naciśnięty, włącznik jest rozwarty i dzięki opornikowi podciągającemu (ang. pull-up resistor) 1k na linii klawisza utrzymuje się poziom logiczny 1:
Przycisk zwolniony | Przycisk wciśnięty |
Najpierw wytłumaczmy, czym jest logika ujemna (ang. negative logic). W normalnej logice stosujemy następujące przypisania:
false → 0 true → 1 |
Na tej umowie opierają się wszystkie funkcje logiczne:
|
|
|
Zapiszmy wartości funkcji oznaczając wartość true przez T, a wartość false przez F:
|
|
|
Teraz umówmy się, że wartości funkcji będziemy interpretować odwrotnie, tzn.:
false → 1 true → 0 |
Otrzymamy:
|
|
|
Teraz to samo zróbmy z argumentami:
|
|
|
Zwróć uwagę, iż przy takiej interpretacji 0 i 1 funkcja negacji się nie zmienia, lecz funkcje alternatywy i koniunkcji zamieniły się ze sobą, tzn. z alternatywy otrzymujemy koniunkcję, a z koniunkcji alternatywę. Otrzymaliśmy logikę ujemną. Nie jest ona czymś zupełnie innym. Po prostu czasem wygodniej jest interpretować stan niski jako stan aktywny, a stan wysoki, jako nieaktywny. Tak jest w przypadku naszej klawiatury: wciśnięcie przycisku będzie dawało stan niski, a zwolnienie stan wysoki.
Klawiatura będzie zbudowana z 10 przycisków. Schemat jest następujący:
Naszym zadaniem będzie zbudowanie kodera, który przetworzy naciśnięcia klawiszy w kod 8421. Na wejściu kod będzie otrzymywał informację z klawiatury, na wyjściu mamy otrzymać numer naciśniętego klawisza w kodzie 8421, przy czym brak naciśnięcia klawisza powinien dawać kod 1111 (dziesiętnie 15 – nie jest wartością żadnej cyfry, zatem jest bezpieczny).
Ułóżmy tabelkę stanów wejściowych oraz wyjściowych naszego kodera:
Wejścia | Wyjścia | ||||||||||||
K0 | K1 | K2 | K3 | K4 | K5 | K6 | K7 | K8 | K9 | Y8 | Y4 | Y2 | Y1 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 |
Zwróć uwagę, iż tabelka ta jest niepełna, ponieważ nie uwzględnia sytuacji, gdy zostały naciśnięte dwa lub więcej klawiszy. Aby nie komplikować projektu, umówmy się, że do takich sytuacji nie będzie dochodziło. W naszym koderze będziemy reagować na stany niskie wejść. Ponieważ zawsze tylko jedno wejście może być w stanie niskim, to rozpiszmy wg podanej wyżej tabelki, kiedy poszczególne wyjścia przyjmują stan niski 0:
Wyjście w stanie 0 | Dla stanu 0 na wejściach |
Y1 | K0,K2,K4,K6,K8 |
Y2 | K0,K1,K4,K5,K8,K9 |
Y4 | K0,K1,K2,K3,K8,K9 |
Y8 | K0,K1,K2,K3,K4,K5,K6,K7 |
Możemy teraz zapisać funkcję wyjść:
Stosujemy prawa De Morgana i otrzymujemy:
We wzorach otrzymaliśmy koniunkcje. Będą potrzebne 4 ośmiowejściowe bramki AND (nieużywane wejścia podłączamy do napięcia zasilającego poprzez opornik 1k). Ponieważ bramki NAND są bardziej dostępne, przeprojektujemy funkcje, tak aby otrzymać zaprzeczone koniunkcje (czyli NAND):
Na podstawie otrzymanych wzorów funkcji budujemy sieć logiczną z bramek NAND. Rozpoczynamy od sygnałów wejściowych. Linie sygnałowe umieścimy pionowo, gdyż tak będzie wygodniej podłączać je do wejść bramek:
Teraz dołączamy bramki NAND realizujące kolejne funkcje. Wyjścia bramek NAND muszą być zanegowane, aby otrzymać koniunkcję. Nieużywane wejścia podłączamy poprzez opornik 1k do napięcia zasilającego:
Sieć logiczna kodera 1 z 10 na 8421 jest gotowa.
Numerujemy bramki.
Określamy sieć połączeń:
Na wejścia sieci K0...K9 podajemy sygnały zgodnie z poniższą tabelką. Na wyjściach powinniśmy otrzymać kody 8421 wciśniętych klawiszy.
Wejścia | Wyjścia | ||||||||||||
K0 | K1 | K2 | K3 | K4 | K5 | K6 | K7 | K8 | K9 | Y8 | Y4 | Y2 | Y1 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 |
1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 1 |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 0 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 1 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 1 |
C++// Symulacja sieci logicznej kodera 1 z 10 na 8421 // (C)2020 mgr Jerzy Wałaszek // I LO w Tarnowie #include <iostream> using namespace std; // Funkcje bramek int NAND2(int a, int b) { return !(a && b); } int NAND8(int a,int b,int c,int d,int e,int f,int g,int h) { return !(a && b && c && d && e && f && g && h); } int main( ) { // Stany wejściowe oraz stany wyjściowe int K0,K1,K2,K3,K4,K5,K6,K7,K8,K9,Y1,Y2,Y4,Y8; // Stany wyjściowe bramek int YB1,YB2,YB3,YB4,YB5,YB6,YB7,YB8; // Zmienne pomocnicze int m,i; m = 0x3ff; // Ustawiamy maskę, m = 1111111111 (binarnie) cout << "K0 K1 K2 K3 K4 K5 K6 K7 K8 K9 | Y8 Y4 Y2 Y1\n" "------------------------------+------------\n"; // Wykonujemy 11 obiegów pętli for(i = 0; i < 11; i++) { // Z maski pobieramy kolejne bity i wstawiamy je do K0...K9 K0 = (m & 0x200) > 0; K1 = (m & 0x100) > 0; K2 = (m & 0x080) > 0; K3 = (m & 0x040) > 0; K4 = (m & 0x020) > 0; K5 = (m & 0x010) > 0; K6 = (m & 0x008) > 0; K7 = (m & 0x004) > 0; K8 = (m & 0x002) > 0; K9 = (m & 0x001) > 0; // Maskę przesuwamy o 1 bit w prawo m >>= 1; // Ustawiamy na 1 bit nr 10 m |= 0x400; // m = 101111111111 // m = 110111111111 // m = 111011111111 ... // Symulujemy sieć YB1 = NAND8(1,1,1,K0,K2,K4,K6,K8); YB2 = NAND8(1,1,K0,K1,K4,K5,K8,K9); YB3 = NAND8(1,1,K0,K1,K2,K3,K8,K9); YB4 = NAND8(K0,K1,K2,K3,K4,K5,K6,K7); YB5 = NAND2(YB1,YB1); YB6 = NAND2(YB2,YB2); YB7 = NAND2(YB3,YB3); YB8 = NAND2(YB4,YB4); Y1 = YB5; Y2 = YB6; Y4 = YB7; Y8 = YB8; // Wyświetlamy wyniki cout << " " << K0 << " " << K1 << " " << K2 << " " << K3 << " " << K4 << " " << K5 << " " << K6 << " " << K7 << " " << K8 << " " << K9 << " | " << Y8 << " " << Y4 << " " << Y2 << " " << Y1 << endl; } cout << endl; return 0; } |
Wynik: |
K0 K1 K2 K3 K4 K5 K6 K7 K8 K9 | Y8 Y4 Y2 Y1 ------------------------------+------------ 1 1 1 1 1 1 1 1 1 1 | 1 1 1 1 0 1 1 1 1 1 1 1 1 1 | 0 0 0 0 1 0 1 1 1 1 1 1 1 1 | 0 0 0 1 1 1 0 1 1 1 1 1 1 1 | 0 0 1 0 1 1 1 0 1 1 1 1 1 1 | 0 0 1 1 1 1 1 1 0 1 1 1 1 1 | 0 1 0 0 1 1 1 1 1 0 1 1 1 1 | 0 1 0 1 1 1 1 1 1 1 0 1 1 1 | 0 1 1 0 1 1 1 1 1 1 1 0 1 1 | 0 1 1 1 1 1 1 1 1 1 1 1 0 1 | 1 0 0 0 1 1 1 1 1 1 1 1 1 0 | 1 0 0 1 |
W symulatorze pominięta jest sekcja klawiatury. Przyciski sterują bezpośrednio wejściami transkodera. Początkowo wszystkie przyciski ustawione są w stan wysoki, co odpowiada nieaktywnemu stanowi przycisków klawiatury. Kliknięcie przycisku zmienia jego stan na przeciwny. Pamiętaj, iż nasza sieć działa poprawnie tylko z jednym stanem wejściowym 0 (czarny kolor przycisku) i pozostałymi stanami 1 (kolor czerwony).
Symulator |
Obciążenia wnoszone przez poszczególne wejścia sieci są następujące:
K0 = 4
K1 = 3
K2 = 3
K3 = 2
K4 = 3
K5 = 2
K6 = 2
K7 = 1
K8 = 3
K9 = 2
Sieć wykorzystuje 1 opornik 1kΩ oraz 8 bramek: 4 bramki NAND 8 wejściowe oraz 4 bramki NAND 2 wejściowe:
Jeśli klawiatura wyposażona jest tylko w 9 klawiszy (od 1 do 9), to zamiast bramek można zastosować scalony konwerter 1 z 9 na kod 8421. Układ ten ma symbol SN74147 i pracuje w logice ujemnej (aktywny jest stan 0).
SN74147
- transkoder 1 z 9 na kod 8421 |
Układ osiada 9 wejść ponumerowanych od 1 do 9. Do wejść tych podłączamy linie klawiszy w identyczny sposób, jak w naszym rozwiązaniu. Na 4 wyjściach D, C, B i A pojawia się zanegowany kod 8421 naciśniętego klawisza. Tabelka stanów dla układu SN74147 jest następująca:
Wejścia | Wyjścia | |||||||||||
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | D | C | B | A |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
X | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
X | X | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
X | X | X | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 |
X | X | X | X | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 |
X | X | X | X | X | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 1 |
X | X | X | X | X | X | 0 | 1 | 1 | 1 | 0 | 0 | 0 |
X | X | X | X | X | X | X | 0 | 1 | 0 | 1 | 1 | 1 |
X | X | X | X | X | X | X | X | 0 | 0 | 1 | 1 | 0 |
Stan X oznacza 0 lub 1, czyli stan wejść poprzedzających dany klawisz jest bez znaczenia. W przypadku jednoczesnego naciśnięcia dwóch lub więcej klawiszy układ SN74147 zwraca kod najstarszego klawisza (zatem układ ten działa lepiej od naszej sieci).
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2024 mgr Jerzy Wałaszek |
Materiały tylko do użytku dydaktycznego. Ich kopiowanie i powielanie jest dozwolone
pod warunkiem podania źródła oraz niepobierania za to pieniędzy.
Pytania proszę przesyłać na adres email:
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.