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). Vstupně / výstupní (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.
Obr.1 Vnitřní zapojení jednoho
pinu portu P0
Obr.2 Vnitřní zapojení jednoho
pinu portu P1
Obr.3 Vnitřní zapojení jednoho
pinu portu P2
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 na další stránce.
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í.
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í.
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.
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 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.
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
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 jsou z
důvodu "kompatibility" s tištěnou (i českou) literaturou ponechány v
obrázcích původní amer.značky.
|
© DH servis 2002 - |