Vstupně/výstupní porty

Vstupně/výstupní porty nám umožňují připojit k mikroprocesoru cokoli dalšího (tranzistory, LED, tlačítka,...), co pracuje s logickými signály (tj.dvoustavovými - log.0 a log.1). V/v porty jsou slučitelné s TTL/CMOS logikou, což nám tak udává napěťové úrovně pro log.0 a 1. Pro představu, co všechno lze k 8051 připojit, můžete se podívat na tento krátký přehled.
U standardní verze 8051 máme k dispozici 4 v/v porty, z nichž každý má po 8 pinech. Tyto čtyři porty jsou označovány P0, P1, P2 a P3. Pokud chceme označit konkrétní pin určitého portu, pak označení vypadá celkem logicky takto - např. P1.4 , kde 1 před des.tečkou určuje port a 4 za tečkou je číslo konkrétního pinu příslušejícího k portu 1. Místo slova port se někdy můžete setkat s označením brána. Já osobně používám slovo port - čímž míním celý port, tedy všech 8 pinů jemu příslušejících. Pokud chci označit jeden konkrétní pin určitého portu, používám označení pin, příp. v/v pin. Jelikož se jednotlivé piny adresují jako bity, můžete se setkat s označením bit, např. bit P1.5.

Z toho, že se bavíme o vstupně/výstupních portech vyplývá, že tyto porty (všechny čtyři) jsou obousměrné - můžeme tedy jednotlivé piny všech portů v rámci jednoho programu používat jako vstupní i jako výstupní (viz dále). Porty hardwarově sestávají ze vstupních vyrovnávacích pamětí, klopných obvodů typu D (namapovány v SFR) a výstupních budičů. Vnitřní (funkční) zapojení portů P0 až P3 ukazují obr. 1 až 4.
Vnitřní zapojení jednoho pinu portu P0
Obr.1  Vnitřní zapojení jednoho pinu portu P0

Vnitřní zapojení jednoho pinu portu P0
Obr.2  Vnitřní zapojení jednoho pinu portu P1

Vnitřní zapojení jednoho pinu portu P2
Obr.3  Vnitřní zapojení jednoho pinu portu P2

Vnitřní zapojení jednoho pinu portu P3
Obr.4  Vnitřní zapojení jednoho pinu portu P3

Jak je vidět z obr.1 až 4, vnitřní zapojení vstupně/výstupního obvodu jednotlivých portů se liší.

Stručná charakteristika portů
Port 0 jako jediný nemá ve výstupním budiči zvyšovací odpor - jde tedy o obvod s otevřeným kolektorem. Pokud jej chceme použít jako obecné vstupy/výstupy, musíme k pinům připojit externí odpory, jejichž druhý konec připojíme na +Ucc. Port 0 se také může využívat při styku s vnější pamětí - popis najdete v odstavci věnovaném portu 2.
Port 1 nemá žádnou alternativní funkci, díky tomu jej můžeme bez nějakého omezení libovolně používat.
Port 2 se kromě své normální funkce může využívat spolu s portem 0 ke komunikaci s externí pamětí. K tomuto účelu se využívají jen části obou portů - výstupní budiče portu 0 a 2 a vstupní vyrovnávací paměť portu 0. Na portu 0 je časově přepínán výstup nižšího bytu adresy pro externí paměť s datovým bytem, který je zapisován nebo čten z paměti. Port 2 pak vysílá vyšší byte adresy. Tato adresa je tedy 16-bitová, abychom mohli adresovat až 64kB paměti. Port 2 jinak pracuje jako normální port. Podrobnější popis přístupu do vnější paměti najdete zde.
Port 3 - všechny piny portu 3 jsou vícefunkční. Kromě standardní funkce navíc tento port poskytuje své piny pro potřeby jiným vnitřním obvodům mikroprocesoru, seznam pinů a jim příslušné alternativní funkce zobrazuje následující tabulka:

Pin Alternativní funkce
P3.O RXD (serial input)
P3.1 TXD (serial output)
P3.2 INTO (external interrupt)
P3.3 INT1 (external interrupt)
P3.4 TO (Timer/Counter O external input)
P3.5 T1 (Timer/Counter 1 external input)
P3.6 WR (external Data Memory write strobe)
P3.7 RD (external Data Memory read strobe)

Alternativní funkce pinů portu 3 může být aktivována pouze, pokud bit v SFR příslušný danému pinu obsahuje log.1. Jinak pin zůstává v log.0.

Popis vnitřního zapojení a funkce jednotlivých portů
Obrázky 1 až 4 ukazují funkční zapojení jednoho pinu každého ze 4 portů. V/V pin tedy tvoří synchronní KO typu D (což je jeden bit v oblasti portů v SFR). Ten načte log.hodnotu z vnitřní sběrnice po příchodu log.1 na vstupu C (z vnitřního signálu CPU - Zápis do KO). Výstup Q klopného obvodu je poslán na vnitřní sběrnici, pokud je aktivní (v log.1) vnitřní signál z CPU - Čtení obsahu KO. Skutečný logický stav pinu samotného je poslán na vnitřní sběrnici, pokud je aktivní vnitřní signál CPU - Čtení stavu pinu. Některé instrukce, které čtou z portu, aktivují signál Čtení obsahu KO, některé instrukce aktivují signál Čtení stavu pinu. Podrobnější informace o těchto instrukcích se dočtete v odstavci věnovaném instrukcím typu "čtení-modifikace-zápis".

Jak je vidět z obr.1 a 3, výstupní budiče portu 0 a 2 jsou přepínatelné na vnitřní sběrnici Adresa a Adresa/Data vnitřním signálem CPU - Řízení (v případě, že využíváme přístup k externí paměti). Během přístupu k externí paměti zůstává stav portu 2 (tedy obsah SFR - oblast P2) nezměněn, naopak do odpovídající oblasti SFR portu 0 jsou zapsány jedničky.

Jak ukazuje obr.4, pokud KO pinu z portu 3 obsahuje jedničku, výstupní log. úroveň pinu je dána stavem vnitřního signálu Alternativní výstupní funkce. Skutečný log.stav pinu je vždy dostupný na vnitřním signálu CPU - Alternativní vstupní funkce.

Porty 1,2 a 3 mají ve výstupních budičích vnitřní zvyšovací odpory (angl. pull-up). Port 0 má naproti tomu výstupy s otevřeným kolektorem (nemá tedy vnitřní zvyšovací odpory). Každý pin kteréhokoliv portu může být nezávisle používán jako vstupní nebo jako výstupní.

POZN: Porty 0 a 2 nemohou být používány jako všeobecné v/v piny, pokud jsou používány jako adresově-datová sběrnice při přístupu do externí paměti.
Pokud tedy chceme piny použít jako vstupní, KO příslušného pinu musí obsahovat jedničku, což způsobí zavření FET tranzistoru ve výstupním budiči (FET je připojený přes negovaný výstup KO). Potom pro porty 1,2,3 platí, že pin je v úrovní log.1 díky zvyšovacímu odporu, ale může být přestaven do log.0 vnějším zdrojem připojeným k pinu (viz tento odstavec).

Port 0 se od ostatních portů liší tím, že nemá ve výstupních budičích vnitřní zvyšovací odpory. Místo odporu je zde druhý FET tranzistor (na obr.1 je to ten horní), který se ale využívá jen když port vysílá jedničky během přístupu k externí paměti (na GATE tranzistoru je log.1). V ostatních případech je FET tranzistor zavřený (na GATE je log.0). Proto piny portu 0, používané jako výstupní, se chovají jako obvod s otevřeným kolektorem. Zápisem log.1 do KO zůstávají oba FET tranzistory zavřeny a pin se tak dostává do stavu vysoké impedance.

Protože porty 1,2 a 3 mají integrované zvyšovací odpory, jsou někdy nazývány jako "pseudoobousměrné". Když jsou nastaveny jako vstupní, jsou ve stavu log.1 a pokud je externě přizemníme, stanou se tak zdrojem proudu. Naproti tomu port 0 se považuje za "skutečně" obousměrný, protože když je nastaven jako vstupní, chová se jako vysokoimpedanční.

POZN: Po resetu mikroprocesoru jsou do KO všech portů zapsány jedničky (všechny porty jsou tedy nastaveny jako vstupní). Jsou-li do KO následně během programu zapsány log.0, mohou být porty znovu přenastaveny jako vstupní zapsáním jedniček od jejich KO.

Zápis do portu
Při vykonávání instrukce, která mění hodnotu KO portu, nová data přijdou do KO během fáze S6P2 posledního cyklu instrukce. Nicméně, KO portu jsou ve skutečnosti vzorkovány jejich výstupními budiči pouze během fáze 1 kteréhokoliv hod.cyklu. Během fáze 2 drží výstupní budiči hodnotu, která byla získána ve fázi 1. Z toho důvodu, nová data v KO portu nepřijdou na výstupní pin portu až do doby následující fáze 1. Další fáze 1 v tomto případě bude až fáze S1P1 dalšího strojového cyklu. Blíže je vše vidět na obr.5.
Zápis dat (stavů pinů) do portu - časový průběh
Obr.5 Zápis dat do portu - časový průběh

Jestliže změna stavu portu vyžaduje přechod z 0 do 1 u portu 1,2 a 3, zvyšovací odpor je snížen až o dva řády během fází S1P1 a S1P2 cyklu, ve kterém dochází k přechodu z 0 do 1. To je uděláno proto, aby se zvýšila rychlost přechodu. Takto snížený zvyš.odpor může dodat až 100-krát větší proud než při své normální hodnotě. Tady je dobré poznamenat, že snížení zvyšovacího odporu je umožněno tím, že zvyšovací odpory tvoří FET tranzistory, nikoliv lineární rezistory. Funkce zvyšovacího odporu bude lépe vidět na obr.6.
Obr.6 Vnitřní zapojení výstupního budiče
Obr.6 Vnitřní zapojení výstupního budiče portů 1 a 3, port 2 vypadá obdobně (viz text níže)

Zvyšovací odpor sestává ze 3 tranzistorů FET s P kanálem (T1,T2,T3). Tzn. při log.0 na GATE bude otevřen, při log.1 bude zavřen. Stávající tranzistor ve výst.budiči (na obr. 2 až 4, na obr.6 označen jako T4) je FET s N kanálem - při log.0 na GATE je tedy zavřen, při log.1 otevřen.
Tranzistor T1 je otevřen na 2 hodinové cykly po přechodu z 0 do 1 v KO portu. Když je otevřen, otevře zároveň T3 (přes invertor). Tento invertor a tranzistor plní KO, který tak drží log.1.
Pokud pin portu vysílá jedničku (nastaven jako vstupní), může být externím zdrojem (součástkou) přizemněn, což způsobí zavření T3, takže pin pak přechází do stavu vysoké impedance. T2 je velmi malý jakoby zvyš.odpor, který je otevřen vždy, když je T4 zavřený. Je přibližně 10-krát menší než T3. Má tu funkci, že obnovuje log.1 na pinu v případě, že na pinu 1 byla a došlo k její ztrátě vlivem externího zdroje (přizemněním). Port 2 funguje podobně s rozdílem při přístupu do externí paměti - pokud port vysílá adresu, pak při jedničkách v této adrese port ponechává otevřený tranzistor T3 (velký zvyšovací odpor).

Připojování pinů portu a jejich zatížení
Výstupní budič pinu (potažmo tranzistor T4 z obr.6) portů 1,2 a 3 může být zatížen proudem 1,6 mA, což umožňuje připojit 4 vstupy obvodů LS-TTL, 12 vstupů ALS-TTL, počet vstupů obvodů HC a HCT je omezen jejich vstupní kapacitou (kolem 5 pF). Piny portů 1,2 a 3 mohou být připojeny i na obvody s otevřeným kolektorem, ale přechod z 0 do 1 nebude v tom případě rychlý, protože log.0 na vstupu zavře T3 a přechod bude řízen pouze tranzistorem T2 (velmi malý zvyš.odpor).
Při přístupu k externí paměti můžeme na port 0 připojit až 8 LS-TTL vstupů. Pokud chceme piny portu používat jako obecné vstupy/výstupy, musíme k nim připojit externí odpory, jejichž druhý konec připojíme na +Ucc.

Instrukce "čtení-modifikace-zápis"
Některé instrukce, načítající stav portu, čtou obsah KO pinů a některé čtou skutečný stav pinů. Instrukce, které čtou obsah KO namísto aktuálního stavu pinu, tedy načtou hodnotu z KO, změní ji (je-li potřeba) a zpět ji přepíší do KO. Proto se o těchto instrukcích říká, že jsou typu "čtení-modifikace-zápis". Seznam těchto instrukcí naleznete níže. Pokud je cílovým operandem port, příp. jen určitý pin portu, tyto instrukce čtou obsah KO namísto aktuálního stavu portu (všech pinů), příp. jen daného pinu .
ANL (log.součin, např. ANL P1, A)
ORL   (log.součet, např. ORL P2, A)
XRL   (log.fce nonekvivalence XOR, např. XRL P3, A)
JBC   (skok a vynulování bitu, je-li bit=1 , např. JBC P1.1, start)
CPL   (negace bitu, např. CPL P3.0)
INC   (inkrementace, např. INC P2)
DEC   (dekrementace, např. DEC P2)
DJNZ  (dekrementace a skok je-li výsledek<>0, např. DJNZ P3, konec)
MOV PX.Y, C  (přesun přenosu do pinu Y portu X)
CLR PX.Y     (vynulování bitu Y portu X)
SETB PX.Y    (nastavení bitu Y portu X)
Na první pohled se může zdát, že poslední 3 instrukce nejsou typu "č-m-z", ale přesto jsou. I když adresují jen jeden pin (bit) portu, načtou celý port (celý byte, všech 8 pinů), modifikují jen adresovaný bit a zapíšou zpět celý byte do klopných obvodů portu. Pro uživatele tento fakt ale není podstatný, důležité pro něj je, to že po těchto 3 instrukcích zůstává stav klopných obvodů ostatních pinů daného portu nezměněn (neovlivněn případným působením připojených externích zdrojů - viz další text).

Důvod, proč instrukce typu "č-m-z" vůbec existují, je ten, že díky nim je možné se vyhnout chybné interpretaci napěťové úrovně na pinu. Nejlépe to bude vidět na příkladu - pin portu chceme využít pro spínání tranzistoru. Na pin tedy připojíme bázi tranzistoru (přes odpor). Když do pinu zapíšeme log.1, tranzistor se otevře. Pokud potom CPU bude číst tento pin - jeho aktuální stav a ne obsah jeho KO - načte napětí báze tranzistoru. Protože ale toto napětí po otevření tranzistoru kleslo na nějakých 0,7V, je stav pinu interpretován jako log.0. Pokud ale použijeme instrukci typu "č-m-z", čímž načteme obsah KO daného pinu, dostaneme správnou hodnotu log.1.

Piny všech čtyř portů můžeme adresovat dvěma způsoby - buď můžeme adresovat jednotlivé piny portu pomocí bitových instrukcí nebo můžeme adresovat celý port - tedy všech 8 pinů daného portu současně - jako jeden byte.
Příklad:
bitové adresování       bytové adresování
setb p1.0               mov p1,a
clr p1.0                inc p1
cpl p1.0                anl p1,a
jnb p1.0,odskok         djnz p1,odskok
atd.                    atd.

Ještě jednou si připomeneme, jak lze měnit funkci pinu na vstupní/výstupní. Každý pin kteréhokoliv portu může být nakonfigurován samostatně jako vstupní nebo výstupní. Můžeme ale samozřejmě nastavit jako vstupní nebo výstupní i celý port pomocí jediné instrukce. To, zda bude pin vstupní nebo výstupní, můžeme měnit v rámci programu kolikrát chceme. Jak nastavíme funkci pinu? Pokud má být výstupní, je to jasné - zápisem nuly dostaneme na výstupu (pinu) log.0, zápisem 1 dostaneme na pinu log.1. Pokud má pin fungovat jako vstupní, pak do něj nejprve musíme natvrdo zapsat 1. Pak teprve můžeme z daného pinu načíst aktuální stav pinu - pokud je připojený signál v úrovni log.1, načteme 1. Pokud je připojený signál v úrovni log.0, načteme 0. Přesněji řečeno - připojené zařízení (např. tlačítko, báze tranzistoru), jehož stav potřebujeme zjistit a které je připojeno na daný pin, nám buď původně zapsanou jedničku ponechá nebo ji naopak "přizemní".
POZN: Po resetu mikroprocesoru jsou ve všech portech zapsány 1 - jsou tedy na nastaveny jako vstupní.
Trošku odlišně funguje čtení u portu 0, jak bylo popsáno výše.

POZN: Na obr.1,2,3,4 a 6 jsou použity české schématické značky hradel až na jednu výjimku. Tou je původní amer.značka
budiče a budiče s negací

Tyto budiče mají povolovací vstup (ten kolmo ke vstupnímu a výstupnímu vývodu). Pokud je na tomto vstupu log.1, vstupní signál může budičem procházet na výstup.
Českým ekvivalentem by měla být tato značka      pro budič a tato značka      pro budič s negací.
Povolovací vstup je zde přiveden na druhý vstup dvouvstupového hradla AND (NAND). Přesto jsem z důvodu "kompatibility" s tištěnou (i českou) literaturou ponechal v obrázcích původní amer.značky.

Zpět na hlavní stránku povídání

Copyright © Michal Fuksa 2001