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 |
©2023 mgr Jerzy Wałaszek |
Układy kombinacyjne projektuje się za pomocą metod, które opisaliśmy w poprzednim rozdziale – szczególnie polecana jest tutaj metoda Karnaugha. W rozdziale omówimy podstawowe układy kombinacyjne, z którymi możesz się spotkać w technice cyfrowej. Wiele z nich produkowane jest w postaci gotowych do zastosowania układów scalonych.
Bramka będzie posiadała dwa wejścia danych A, B, dwa wejścia programujące funkcję F1, F0 oraz jedno wyjście Y:
W zależności od stanów na wejściach F1 i F0 bramka realizuje następujące funkcje logiczne:
F1 | F0 | Y |
0 | 0 | A AND B |
0 | 1 | A OR B |
1 | 0 | A NAND B |
1 | 1 | A NOR B |
Układamy tabelkę stanów:
F1 | F0 | A | B | Y |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 0 |
0 | 0 | 1 | 0 | 0 |
0 | 0 | 1 | 1 | 1 |
0 | 1 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
0 | 1 | 1 | 0 | 1 |
0 | 1 | 1 | 1 | 1 |
1 | 0 | 0 | 0 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 0 | 1 | 0 | 1 |
1 | 0 | 1 | 1 | 0 |
1 | 1 | 0 | 0 | 1 |
1 | 1 | 0 | 1 | 0 |
1 | 1 | 1 | 0 | 0 |
1 | 1 | 1 | 1 | 0 |
Układamy mapę Karnaugha:
Na podstawie mapy wyprowadzamy funkcję:
Funkcję upraszczamy:
Na podstawie funkcji tworzymy sieć logiczną:
Testujemy się za pomocą programu w języku C:
![]() |
|
/* ** SYMULACJA SIECI LOGICZNEJ ** (C)2018 mgr Jerzy Wałaszek */ #include <stdio.h> #include <stdlib.h> int main() { // Sygnały wejściowe sieci int F1,F0,A,B; // Sygnał wyjściowy sieci int Y; // Bramki int b1,b2,b3,b4,b5,b6,b7,b8,b9,b10, b11,b12,b13,b14,b15; printf("Symulacja bramki programowanej\n"); printf("------------------------------\n"); printf("\n\n"); printf("F1 F0 A B Y\n"); printf("--------------\n"); // Tworzymy środowisko pracy sieci for(F1 = 0; F1 < 2; F1++) // Sygnał F1 0,1 for(F0 = 0; F0 < 2; F0++) // Sygnał F0 0,1 for(A = 0; A < 2; A++) // Sygnał A 0,1 for(B = 0; B < 2; B++) // Sygnał B 0,1 { // Wyświetlamy sygnały wejściowe printf(" %d %d %d %d ",F1,F0,A,B); // Wyznaczamy wartości na wyjściach bramek sieci b1 = !F1; b2 = !F0; b3 = !A; b4 = !B; b5 = A|B; b6 = A&B; b7 = b5&F0; b8 = b7|b6; b9 = b8&b1; b10 = b4|b3; b11 = b4&b3; b12 = b10&b2; b13 = b12|b11; b14 = b13&F1; Y = b15 = b9|b14; // Wyświetlamy sygnał wyjściowy printf("%d\n",Y); } printf("\n--- KONIEC SYMULACJI ---\n\n"); return 0; } |
Tego typu układy znajdują się w mikrokontrolerach. Dzięki nim mikrokontroler potrafi wykonywać różne operacje nad danymi. Jeśli cię to zainteresowało, przeczytaj opis układu SN74181.
Kodów binarnych jest bardzo dużo. Podstawowym jest naturalny
kod binarny, NBC (ang. Natural Binary
Code). Koduje on za pomocą bitów wartości liczbowe. Realizuje
się to przypisując bitom wagi będące kolejnymi potęgami liczby 2.
Dlatego często oznacza się ten kod symbolem 8421
Wagi | 23=8 | 22=4 | 21=2 | 20=1 |
Bity | b3 | b2 | b1 | b0 |
Pozycje | 3 | 2 | 1 | 0 |
Bity mogą znajdować się w dwóch stanach: 0 lub 1. Wartość kodowanej liczby obliczamy jako sumę wag pozycji pomnożonych przez wartość bitów, które znajdują się na tych pozycjach:
Na przykład, mamy bity kolejno: 0111.
Zatem kod 0111 reprezentuje w naszym systemie dziesiętnym liczbę 7.
Ponieważ kod NBC pojawia się bardzo często, warto nauczyć się na pamięć wartości kodów 4-bitowych NBC lub zapamiętać sposób obliczania wartości tych kodów:
b3 | b2 | b1 | b0 | SUMA | W |
23=8 | 22=4 | 21=2 | 20=1 | ||
0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 1 | 1 |
0 | 0 | 1 | 0 | 2 | 2 |
0 | 0 | 1 | 1 | 2 + 1 | 3 |
0 | 1 | 0 | 0 | 4 | 4 |
0 | 1 | 0 | 1 | 4 + 1 | 5 |
0 | 1 | 1 | 0 | 4 + 2 | 6 |
0 | 1 | 1 | 1 | 4 + 2 + 1 | 7 |
1 | 0 | 0 | 0 | 8 | 8 |
1 | 0 | 0 | 1 | 8 + 1 | 9 |
1 | 0 | 1 | 0 | 8 + 2 | 10 |
1 | 0 | 1 | 1 | 8 + 2 + 1 | 11 |
1 | 1 | 0 | 0 | 8 + 4 | 12 |
1 | 1 | 0 | 1 | 8 + 4 + 1 | 13 |
1 | 1 | 1 | 0 | 8 + 4 + 2 | 14 |
1 | 1 | 1 | 1 | 8 + 4 + 1 | 15 |
Zwróć uwagę na budowę kodu NBC w tabelce. Jest to schemat rekurencyjny, który łatwo da się zapamiętać.
Jeśli kod NBC jest jednobitowy, to otrzymujemy tylko dwa słowa kodowe:
b0 | SUMA | W |
20=1 | ||
0 | 0 | 0 |
1 | 1 | 1 |
Jeśli dodamy kolejny bit, to dopisujemy go ze stanem 0 do wszystkich słów kodowych poprzedniego kodu i dopisujemy go ze stanem 1 do wszystkich słów kodowych poprzedniego kodu:
b1 | b0 | SUMA | W |
21=2 | 20=1 | ||
0 | 0 | 0 | 0 |
0 | 1 | 1 | 1 |
1 | 0 | 2 | 2 |
1 | 1 | 2 + 1 | 3 |
Dla kolejnego bitu postępujemy podobnie:
b2 | b1 | b0 | SUMA | W |
22=4 | 21=2 | 20=1 | ||
0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 | 1 |
0 | 1 | 0 | 2 | 2 |
0 | 1 | 1 | 2 + 1 | 3 |
1 | 0 | 0 | 4 | 4 |
1 | 0 | 1 | 4 + 1 | 5 |
1 | 1 | 0 | 4 + 2 | 6 |
1 | 1 | 1 | 4 + 2 + 1 | 7 |
Kod NBC można rozszerzyć na dowolną liczbę bitów. Zapamiętaj jedynie, że wagi kolejnych pozycji są kolejnymi potęgami liczby 2 (wykładnik potęgi jest równy numerowi pozycji):
Wagi | 24=16 | 23=8 | 22=4 | 21=2 | 20=1 |
Bity | b4 | b3 | b2 | b1 | b0 |
Pozycje | 4 | 3 | 2 | 1 | 0 |
Wagi | 25=32 | 24=16 | 23=8 | 22=4 | 21=2 | 20=1 |
Bity | b5 | b4 | b3 | b2 | b1 | b0 |
Pozycje | 5 | 4 | 3 | 2 | 1 | 0 |
Wagi | 27=128 | 26=64 | 25=32 | 24=16 | 23=8 | 22=4 | 21=2 | 20=1 |
Bity | b7 | b6 | b5 | b4 | b3 | b2 | b1 | b0 |
Pozycje | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
Przy obliczaniu wartości sumujemy tylko wagi pozycji, dla których bit ma wartość 1.
Na przykład kod 11110111 reprezentuje liczbę:
128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 | ||
1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | = 128 + 64 + 32 + 16 + 4 + 2 + 1 | = 247 |
Drugim popularnym kodem jest kod BCD (ang. Binary Coded Decimal = kod dziesiętny kodowany dwójkowo).
W kodzie BCD kodowane są cyfry dziesiętne liczby za pomocą 4-bitowych słówek w kodzie NBC. Brzmi zawile, lecz sprawa jest bardzo prosta. Zakodujmy w NBC liczbę dziesiętną 628. Każda cyfra dziesiętna potrzebuje 4 bitów, które przedstawiają jej wartość:
6 = 0110 2 = 0010 9 = 1001 |
I ostatecznie:
629(10) = 011000101001(NBC) |
W drugą stronę jest również prosto. Na przykład kod BCD 100001110101 oznacza liczbę:
1000 0111 0101 1000 = 8 0111 = 7 0101 = 5 100001110101(NBC) = 875(10) |
4-bitowe kody NBC mają wartości od 0 (0000) do 15 (1111). Kod BCD używa tylko wartości od 0 (0000) do 9 (1001). Pozostałe słówka kodu NBC (1010, 1011, 1100, 1101, 1110 i 1111) nie są używane (ponieważ nie reprezentują żadnej cyfry dziesiętnej).
Są to kody n-bitowe. W słowie kodowym tylko jeden bit może przyjąć wartość 1. Pozostałe bity mają wartość 0. Położenie bitu 1 określa wartość słowa kodowego. Na przykład dla kodu 1 z 10 mamy:
1 z 10 | |||||||||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 |
Kody Gray'a stosowane są przy pomiarach położenia lub kąta obrotu. Zaletą ich jest to, iż kolejne wyrazy różnią się od siebie tylko jednym bitem. Minimalizuje to ewentualne przekłamania pomiaru. Aby pokazać ci, o co tutaj chodzi, wyobraź sobie, iż masz układ pomiarowy, który zwraca wynik w postaci kodu NBC. Kolejne położenia są kodowane 3 bitami:
000 | 001 | 010 | 011 | 100 | 101 | 110 | 111 |
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
Jednakże z powodu niedokładności czujnika bity kodu nie zmieniają się jednocześnie, tylko mają pewne "luzy". Położenie przechodzi z 3 (011) na 4 (100). Jeśli zmiana bitów nie będzie jednoczesna, to na wyjściu czujnika chwilowo mogą w zasadzie pojawić się wszystkie pozostałe kody, np. kod 111 (pierwszy bit zmienił się na 1, lecz dwa pozostałe wciąż mają starą wartość). Otrzymamy przekłamanie położenia. Oczywiście można temu zapobiec za pomocą odpowiedniego oprogramowania, niemniej problem pozostaje. Kod Gray'a eliminuje tę niedogodność, sprowadzając ewentualne przekłamanie do 1 bitu, czyli położenia sąsiedniego.
Kodów Gray'a jest wiele. Podam tutaj kod Gray'a odzwierciedlony binarnie, zwany również kodem refleksyjnym.
Bity w kodzie Gray'a nie posiadają wag jak w kodzie NBC. Należy skonstruować słowa kodu. Robimy to rekurencyjnie, poczynając od słówek jednobitowych i dodając kolejne bity, aż otrzymamy kod Gray'a o założonej liczbie bitów.
b0 | W |
0 | 0 |
1 | 1 |
Aby utworzyć kod o zwiększonej o 1 liczbie bitów, do słówek kodu dopisujemy na początku nowy bit o stanie 1, po czym odwracamy kolejność słówek i dopisujemy do nich bit o stanie 1:
b1 | b0 | W |
0 | 0 | 0 |
0 | 1 | 1 |
1 | 1 | 2 |
1 | 0 | 3 |
Dalej postępujemy podobnie:
b2 | b1 | b0 | W |
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 1 | 2 |
0 | 1 | 0 | 3 |
1 | 1 | 0 | 4 |
1 | 1 | 1 | 5 |
1 | 0 | 1 | 6 |
1 | 0 | 0 | 7 |
b3 | b2 | b1 | b0 | W |
0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 1 | 1 |
0 | 0 | 1 | 1 | 2 |
0 | 0 | 1 | 0 | 3 |
0 | 1 | 1 | 0 | 4 |
0 | 1 | 1 | 1 | 5 |
0 | 1 | 0 | 1 | 6 |
0 | 1 | 0 | 0 | 7 |
1 | 1 | 0 | 0 | 8 |
1 | 1 | 0 | 1 | 9 |
1 | 1 | 1 | 1 | 10 |
1 | 1 | 1 | 0 | 11 |
1 | 0 | 1 | 0 | 12 |
1 | 0 | 1 | 1 | 13 |
1 | 0 | 0 | 1 | 14 |
1 | 0 | 0 | 0 | 15 |
Zwróć uwagę na jedną z cech kodu Gray'a: pierwszy wyraz (0,00,000,0000...) i ostatni (1,10,100,1000...) również różnią się jednym bitem. Z tego powodu kod ten jest cykliczny.
Do wyświetlania cyfr w technice cyfrowej używa się powszechnie wyświetlaczy 7-segmentowych (ang. 7-segment display).
Segmenty wyświetlacza są diodami LED lub ciekłymi kryształami. Numeracja segmentów jest następująca:
![]() |
Wyświetlacze te umożliwiają wyświetlanie cyfr 0...9 oraz kilku liter alfabetu:
Kod wyświetlacza dla cyfr jest następujący (1 oznacza zapalony segment, 0 oznacza zgaszony segment):
Segmenty | Cyfra | ||||||
a | b | c | d | e | f | g | |
1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 |
0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 |
1 | 1 | 0 | 1 | 1 | 0 | 1 | 2 |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 3 |
0 | 1 | 1 | 0 | 0 | 1 | 1 | 4 |
1 | 0 | 1 | 1 | 0 | 1 | 1 | 5 |
1 | 0 | 1 | 1 | 1 | 1 | 1 | 6 |
1 | 1 | 1 | 0 | 0 | 1 | 0 | 7 |
1 | 1 | 1 | 1 | 1 | 1 | 1 | 8 |
1 | 1 | 1 | 1 | 0 | 1 | 1 | 9 |
W ramach ćwiczeń przedstawimy teraz sposób projektowania dwóch transkoderów.
Transkoder posiada 3 wejścia D4, D2, D1 oraz 8 wyjść 0, 1, 2, 3, 4, 5, 6, 7 i 8. Na wejścia podajemy 3-bitowy kod NBC. Na wyjściach otrzymujemy 8-bitowy kod 1 z 8.
![]() |
|
Tą sieć rozwiążemy metodą algebraiczną. Wyznaczamy funkcje logiczne poszczególnych wyjść:
Budujemy sieć logiczną:
Symulacja sieci w języku C:
![]() |
|
/* ** SYMULACJA SIECI LOGICZNEJ ** (C)2018 mgr Jerzy Wałaszek */ #include <stdio.h> #include <stdlib.h> int main() { // Sygnały wejściowe sieci int D1,D2,D4; // Sygnały wyjściowe sieci int O0,O1,O2,O3,O4,O5,O6,O7; // Bramki int b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11; printf("Symulacja transkodera 421 na 1 z 8\n"); printf("----------------------------------\n"); printf("\n\n"); printf("D4 D2 D1 0 1 2 3 4 5 6 7\n"); printf("-------------------------\n"); // Tworzymy środowisko pracy sieci for(D4 = 0; D4 < 2; D4++) // sygnał D4 0,1 for(D2 = 0; D2 < 2; D2++) // sygnał D2 0,1 for(D1 = 0; D1 < 2; D1++) // sygnał D1 0,1 { // Wyświetlamy sygnały wejściowe D4, D2 i D1 printf(" %d %d %d ",D4,D2,D1); // Wyznaczamy wartości na wyjściach bramek sieci b1 = !D4; b2 = !D2; b3 = !D1; O0 = b4 = b1&b2&b3; O1 = b5 = b1&b2&D1; O2 = b6 = b1&D2&b3; O3 = b7 = b1&D2&D1; O4 = b8 = D4&b2&b3; O5 = b9 = D4&b2&D1; O6 = b10 = D4&D2&b3; O7 = b11 = D4&D2&D1; // Wyświetlamy sygnały wyjściowe printf("%d %d %d %d %d %d %d %d\n",O0,O1,O2,O3,O4,O5,O6,O7); } printf("\n--- KONIEC SYMULACJI ---\n\n"); return 0; } |
Transkoder posiada 4 wejścia danych D8, D4, D2, D1 oraz 7 wyjść a,b,c,d,e,f,g. Na wejście podajemy cyfrę dziesiętną w kodzie BCD, na wyjściu otrzymujemy kod sterujący świeceniem segmentów we wskaźniku.
![]() |
![]() |
|
Zadanie rozwiążemy za pomocą map Karnaugha, wyznaczając funkcje logiczne dla każdego sygnału wyjściowego.
a:![]() ![]() |
b:![]() ![]() |
c:![]() ![]() |
d:![]() ![]() |
e:![]() ![]() |
f:![]() ![]() |
g:![]() ![]() |
Tworzymy sieć logiczną:
Testujemy sieć za pomocą programu w języku C:
![]() |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
/* ** SYMULACJA SIECI LOGICZNEJ ** (C)2018 mgr Jerzy Wałaszek */ #include <stdio.h> #include <stdlib.h> #include <locale.h> int main() { // Sygnały wejściowe sieci int D1,D2,D4,D8; // Sygnały wyjściowe sieci int a,b,c,d,e,f,g; // Bramki int b1,b2,b3,b4,b5,b6,b7,b8,b9,b10, b11,b12,b13,b14,b15,b16,b17,b18, b19,b20,b21,b22; setlocale(LC_ALL,""); printf("Symulacja transkodera BCD na kod wskaźnika 7-segmentowego\n"); printf("---------------------------------------------------------\n"); printf("\n\n"); printf("D8 D4 D2 D1 a b c d e f g\n"); printf("--------------------------\n"); // Tworzymy środowisko pracy sieci for(D8 = 0; D8 < 2; D8++) // Sygnał D8 0,1 for(D4 = 0; D4 < 2; D4++) // Sygnał D4 0,1 for(D2 = 0; D2 < 2; D2++) // Sygnał D2 0,1 for(D1 = 0; D1 < 2; D1++) // Sygnał D1 0,1 { // Wyświetlamy sygnały wejściowe D7, D4, D2 i D1 printf(" %d %d %d %d ",D8,D4,D2,D1); // Wyznaczamy wartości na wyjściach bramek sieci b1 = !D8; b2 = !D4; b3 = !D2; b4 = !D1; b5 = b1&b2&b4; b6 = D4&D1; a = b7 = b5|D2|D8|b6; b8 = b3&b4; b9 = D2&D1; b = b10 = b8|b2|b9; c = b11 = b3|D1|D4; b12 = b4|D2; b13 = D2&b4; b14 = D4&b3&D1; b15 = b12&b2; d = b16 = b15|b13|b14|D8; b17 = b2&b4; e = b18 = b13|b17; f = b19 = b8|D4|D8; b20 = b2&D2; b21 = D4&b3; g = b22 = b20|b13|b21|D8; // Wyświetlamy sygnały wyjściowe printf("%d %d %d %d %d %d %d\n",a,b,c,d,e,f,g); } printf("\n--- KONIEC SYMULACJI ---\n\n"); return 0; } |
Tego typu transkodery są produkowane w postaci pojedynczych układów scalonych:
Działanie układu jest bardzo proste:
Na wejścia wybierające A podajemy adres dwójkowy jednego z wejść D. Wtedy na wyjściu Y pojawia się stan wybranego wejścia.Dla przykładu zaprojektujmy multiplekser dwuwejściowy:
![]() |
|
Jeśli na wejściu wybierającym S panuje stan niski 0, to na wyjściu Y mamy stan wejścia A. Jeśli zmienimy stan wejścia wybierającego S na wysoki 1, to na wyjściu Y pojawi się stan wejścia B.
Układamy mapę Karnaugha dla wyjścia Y:
Funkcja logiczna:
Sieć logiczna:
Jako ćwiczenie sprawdź działanie tej sieci programem w języku C.
Multipleksery są produkowane w postaci gotowych układów scalonych:
Multipleksery stosuje się często do odczytu stanu wielu linii wejścia, np. z klawiatury. Pozwalają one zaoszczędzić wiele portów mikrokontrolera. Np. układ SN74150 jest multiplekserem 16 kanałowym:
Do wejść E podłączasz sygnały, które chcesz odczytywać, następnie na wejściach A...D (D zawiera najstarszy bit adresu) umieszczasz adres wejścia E i stan wejścia odczytujesz z wyjścia W, tutaj będzie zanegowany. Wejście G należy połączyć z masą, aby układ był uaktywniony. W sumie potrzebujesz tylko 5 portów do sterowania tym układem, a bez niego potrzebowałbyś 16 portów. Widzisz zysk?
Zasada działania jest następująca:
Zaprojektujmy 2-kanałowy demultiplekser:
![]() |
|
Jeśli na wejściu wybierającym S panuje stan niski 0, to na wyjściu Y0 jest stan wejścia D. Jeśli S przyjmuje stan wysoki 1, to na wyjściu Y1 pojawi się stan wejścia D. Na wyjściu niewybranym panuje stan nieaktywny 0.
Tworzymy mapy Karnaugha dla obu wyjść:
Y0:![]() |
Y1:![]() |
|
![]() |
![]() |
Sieć logiczna:
Sprawdź działanie tej sieci za pomocą programu w języku C.
Przemysł elektroniczny produkuje scalone demultipleksery w różnych konfiguracjach, np.:
Działanie jest następujące:
Na wyjściu A < B otrzymujemy stan 1, jeśli liczba A jest mniejsza od liczby B. W przeciwnym razie na wyjściu tym jest stan 0.
Na wyjściu A = B otrzymujemy stan 1, jeśli liczba A jest równa liczbie B. W przeciwnym razie na wyjściu tym jest stan 0.
Na wyjściu A > B otrzymujemy stan 1, jeśli liczba A jest większa od liczby B. W przeciwnym razie na wyjściu tym jest stan 0.
Dla przykładu zaprojektujmy komparator 2-bitowy:
![]() |
|
Układamy mapy Karnaugha dla poszczególnych wyjść komparatora:
A<B![]() ![]() |
A=B![]() ![]() |
A>B![]() ![]() |
Sieć logiczna komparatora:
Test sieci za pomocą programu w języku C:
![]() |
|
/* ** SYMULACJA SIECI LOGICZNEJ ** (C)2018 mgr Jerzy Wałaszek */ #include <stdio.h> #include <stdlib.h> int main() { // Sygnały wejściowe sieci int A1,A0,B1,B0; // Sygnał wyjściowy sieci int ALB,AEB,AGB; // Bramki int b1,b2,b3,b4,b5,b6,b7,b8,b9,b10, b11,b12,b13,b14,b15,b16,b17,b18,b19; printf("Symulacja komparatora 2-bitowego\n"); printf("--------------------------------\n"); printf("\n\n"); printf("A1 A0 B1 B0 A<B A=B A>B\n"); printf("-----------------------\n"); // Tworzymy środowisko pracy sieci for(A1 = 0; A1 < 2; A1++) // Sygnał A1 0,1 for(A0 = 0; A0 < 2; A0++) // Sygnał A0 0,1 for(B1 = 0; B1 < 2; B1++) // Sygnał B1 0,1 for(B0 = 0; B0 < 2; B0++) // Sygnał B0 0,1 { // Wyświetlamy sygnały wejściowe printf(" %d %d %d %d ",A1,A0,B1,B0); // Wyznaczamy wartości na wyjściach bramek sieci b1 = !A1; b2 = !A0; b3 = !B1; b4 = !B0; b5 = b1|B1; b6 = b1&B1; b7 = b5&b2&B0; ALB = b8 = b7|b6; b9 = b2&b4; b10 = A0&B0; b11 = b1&b3; b12 = A1&B1; b13 = b9|b10; b14 = b11|b12; AEB = b15 = b13&b14; b16 = b3|A1; b17 = A1&b3; b18 = b16&A0&b4; AGB = b19 = b18|b17; // Wyświetlamy sygnały wyjściowe printf("%d %d %d\n",ALB,AEB,AGB); } printf("\n--- KONIEC SYMULACJI ---\n\n"); return 0; } |
Produkowany jest układ SN7485, który zawiera komparator 4-bitowy:
Oprócz wejść A i B komparator posiada również wejścia wyników porównania z poprzedniej kaskady. Umożliwia to tworzenie komparatorów liczb binarnych o większej niż 4 ilości bitów:
0 | + | 0 | = | 0 |
0 | + | 1 | = | 1 |
1 | + | 0 | = | 1 |
1 | + | 1 | = | 10 |
Zasady dodawania są identyczne jak w naszym systemie dziesiętnym. Dla przykładu dodajmy dwie liczby dwójkowe 1101 i 1011. Zapisujemy je słupku i ostatnią podkreślamy:
1 | 1 | 0 | 1 | |
+ | 1 | 0 | 1 | 1 |
Dodawanie rozpoczynamy od ostatnich cyfr obu liczb i posuwamy się w lewą stronę, dodając do siebie kolejne cyfry. Jeśli wynik jest dwucyfrowy (1 + 1 = 10), to pod kreską zapisujemy ostatnią cyfrę, a pierwszą cyfrę zapisujemy ponad kolejną cyfra pierwszej liczby. Jest to tzw. przeniesienie (ang. carry), które musi zostać dodane do wyniku sumowania cyfr następnej kolumny.
Sumujemy ostatnie dwie cyfry:
1 | ||||
1 | 1 | 0 | 1 | |
+ | 1 | 0 | 1 | 1 |
0 |
Sumujemy kolejne cyfry:
1 | 1 | |||
1 | 1 | 0 | 1 | |
+ | 1 | 0 | 1 | 1 |
0 | 0 |
Sumujemy kolejne cyfry:
1 | 1 | 1 | ||
1 | 1 | 0 | 1 | |
+ | 1 | 0 | 1 | 1 |
0 | 0 | 0 |
Sumujemy kolejne cyfry:
1 | 1 | 1 | 1 | |
1 | 1 | 0 | 1 | |
+ | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 0 |
Cyfry obu liczb skończyły się, ale pozostało nam przeniesienie równe 1. Przepisujemy je do wyniku (możemy potraktować tę kolumnę tak, jakby obie liczby miały tu cyfry zero):
1 | 1 | 1 | 1 | ||
0 | 1 | 1 | 0 | 1 | |
+ | 0 | 1 | 0 | 1 | 1 |
1 | 1 | 0 | 0 | 0 |
Dostajemy wynik:
1101 = 8 + 4 + 1 = 13 1011 = 8 + 2 + 1 = 11 11000 = 16 + 8 = 24 |
Nie może być inaczej – wynik dodawania nie zależy od systemu liczbowego, w którym wykonujemy dodawanie, lecz od wartości dodawanych liczb.
Dla przykładu zaprojektujemy sumator jednobitowy:
![]() |
|
Ci jest przeniesieniem z poprzedniej kaskady sumującej. Pozwala to łączyć sumatory w szereg i wykonywać sumowanie dla liczb wielobitowych.
A i B to sumowane bity. Y jest wynikiem sumowania. Co jest wyjściem przeniesienia. |
Układamy mapy Karnaugha dla Y i Co:
Y![]() ![]() |
Co![]() ![]() |
Budujemy sieć:
Testujemy sieć za pomocą programu w języku C:
![]() |
|
/* ** SYMULACJA SIECI LOGICZNEJ ** (C)2018 mgr Jerzy Wałaszek */ #include <stdio.h> #include <stdlib.h> int main() { // Sygnały wejściowe sieci int A,B,Ci; // Sygnały wyjściowe sieci int Co,Y; // Bramki int b1,b2,b3,b4,b5,b6,b7,b8,b9,b10, b11,b12,b13,b14,b15; printf("Symulacja sumatora 1-bitowego\n"); printf("-----------------------------\n"); printf("\n\n"); printf("Ci A B Y Co\n"); printf("-----------------------\n"); // Tworzymy środowisko pracy sieci for(Ci = 0; Ci < 2; Ci++) // Sygnał Ci 0,1 for(A = 0; A < 2; A++) // Sygnał A 0,1 for(B = 0; B < 2; B++) // Sygnał B 0,1 { // Wyświetlamy sygnały wejściowe printf(" %d %d %d ",Ci,A,B); // Wyznaczamy wartości na wyjściach bramek sieci b1 = !Ci; b2 = !A; b3 = !B; b4 = b2&B; b5 = A&b3; b6 = b4|b5; b7 = b6&b1; b8 = b2&b3; b9 = A&B; b10 = b8|b9; b11 = b10&Ci; Y = b12 = b7|b11; b13 = B|A; b14 = b13&Ci; Co = b15 = b9|b14; // Wyświetlamy sygnały wyjściowe printf("%d %d\n",Y,Co); } printf("\n--- KONIEC SYMULACJI ---\n\n"); return 0; } |
W handlu można spotkać następujące sumatory scalone:
Więcej na ten temat znajdziesz w osobnym artykule "Bit w zastosowaniach".
![]() |
Zespół Przedmiotowy Chemii-Fizyki-Informatyki w I Liceum Ogólnokształcącym im. Kazimierza Brodzińskiego w Tarnowie ul. Piłsudskiego 4 ©2023 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: i-lo@eduinf.waw.pl
Serwis wykorzystuje pliki cookies. Jeśli nie chcesz ich otrzymywać, zablokuj je w swojej przeglądarce.
Informacje dodatkowe.