Komunikace pomocí sériového portu RS-232C

4. 12. 2008
Doba čtení: 14 minut

Sdílet

Ve čtyřicáté části seriálu o architekturách počítačů si ukážeme, jakým způsobem se dá se sériovým portem pracovat na běžném osobním počítači. Popíšeme si i zapojení kabelů sériového portu, od těch nejjednodušších se dvěma vodiči až po kabely umožňujícími řízení toku dat pomocí handshakingu.

Obsah

1. Komunikace pomocí sériového portu RS-232C
2. Zapojení konektorů a propojovacích kabelů
3. Sériové porty na osobních počítačích
4. Konfigurační registry UART
5. Nastavení přenosové rychlosti sériového portu
6. Konfigurace dalších parametrů přenosové linky
7. Odkazy na Internetu
8. Obsah dalšího pokračování seriálu

1. Komunikace pomocí sériového portu

V předchozí části tohoto seriálu jsme si popsali základní způsob přenosu dat pomocí sériového portu RS-232C. Dnes si řekneme, jak lze nakonfigurovat a následně i použít sériový port či více portů, které jsou zabudovány do osobních počítačů. Velmi podobným způsobem však pracují i sériové porty použité v dalších zařízeních, nezávisle na tom, jakým konkrétním řadičem (UART) či konektorem jsou tato zařízení vybavena. Na osobních počítačích se dnes ponejvíce můžeme setkat se sériovým portem vyvedeným na konektor DB-9 (přesněji DE-9, používají se však obě označení), popřípadě lze najít i počítače vybavené širokým konektorem DB-25, protože jen na tomto typu konektoru jsou vyvedeny všechny signály postupně přidávané k sériovému portu (jedná se zejména o signály použité u některých modemů a také o druhou obousměrnou sériovou linku). Sériová komunikace odpovídající RS-232C však může probíhat i po kabelech ukončených konektorem typu RJ-11 či RJ-45, výjimkou nejsou ani zařízení používající některou z variant konektoru DIN (v minulosti populární a po mechanické stránce velmi odolný „pětikolík“), různé typu jacků u menších zařízení atd.

pc4001

Obrázek 1: Universální kabely použité při propojování různých zařízení vybavených sériovými porty. V praxi se můžeme ponejvíce setkat se dvěma typy kabelů – u jedněch se prohazují signály TxD a RxD (vysílání a příjem) i další signálové vodiče, druhé typy kabelů jsou pouze „prodlužovací“, tj. na obou konektorech jsou propojeny vždy stejné piny.

Základem komunikace přes sériový port typu RS-232C je simplexní, poloduplexní či plně duplexní asynchronní přenos dat, ke kterým může být doplněn paritní bit, přičemž komunikační protokol je rozšířen i o takzvané start a stop bity, které slouží k synchronizaci vysílacího a přijímacího zařízení (přítomnost stop bitu navíc dává přijímací straně dostatek času na uložení právě načteného bajtu do vyrovnávacího datového registru či datové fronty – FIFO – a vygenerování přerušení pro komunikační program). Osobní počítače jsou vybaveny buď samostatným čipem UART popř. USART, nebo je tento universální vysílač a přijímač zabudován do nějakého složitějšího čipu (většinou jižního můstku – south bridge – na základní desce). Komunikaci na nejnižší úrovni, včetně generování start bitu, stop bitu i paritního bitu, obstarává právě UART, programátorovi postačuje vhodně nastavit parametry přenosové linky a při vlastním přenosu dat dostatečně rychle reagovat na přerušení, které přijde ve chvíli, kdy se mají data vysílat či jsou naopak přijata.

pc4002

Obrázek 2: Síťové zařízení umožňující propojení sériových portů a Ethernetu. Tyto sériové porty lze nastavit na všechny standardní rychlosti, včetně obvyklých 115200 bitů za sekundu.

Přítomnost specializovaného čipu UART/USART v osobním počítači mj. znamená, že vlastní komunikace již není tak náročná na zatížení mikroprocesoru, jako komunikace po paralelním portu, u které se o posílání dat, příjem dat i samotný handshaking musel starat mikroprocesor a nikoli specializovaný čip (poznamenejme, že na některých jednodušších mikrořadičích není UART přítomen; to však nemusí vadit, protože se komunikace jak na straně vysílače, tak i na straně příjemce, dá na mikrořadičích poměrně snadno naprogramovat, především tehdy, když je k dispozici časovač připojený na přerušení). V následujících kapitolách si řekneme základní informace o ovládání UART/USART na té nejnižší úrovni (přes konfigurační registry mapované do I/O prostoru mikroprocesoru) i na úrovni operačního systému. Tato vyšší úroveň je v mnoha Unixových systémech představována systémovým programem setserial, díky němuž je možné pracovat i s nestandardně připojenými sériovými porty.

2. Zapojení konektorů a propojovacích kabelů

Na třetím obrázku je nakreslen konektor typu DB-9/DE-9 spolu se jmény jednotlivých pinů používaných při komunikaci po sériovém portu. Pro mnoho zařízení připojených k osobnímu počítači postačují pouze piny TxD, RxD a Ground, ovšem například pro rychlé propojení dvou počítačů nebo pro komunikaci s modemem se využívají i další piny, pomocí nichž se zajišťuje hardwarové řízení toku dat – handshaking – (DTR/DSR či RTS/CTS) i přenos některých informací z modemu do počítače (DCD, RI). V následujících odstavcích si popíšeme některé typické zapojení propojovacích kabelů, ovšem již nyní je nutné říci, že mnoho (především starších) zařízení vyžaduje odlišně zapojené kabely a pro některá tato zařízení je dokonce nutné použít sériový port vyvedený na konektor typu DB-25, protože na kratším konektoru některé méně často používané signály chybí. V praxi se často setkáme s následujícími typy zapojení:

  1. Pokud se komunikuje se zařízením, které nevrací žádná data (řádkový LCD, některé tiskárny), je možné zapojit pouze dva vodiče – TxD a Ground. Pin TxD na straně počítače se propojí s pinem RxD na přijímací straně.
  2. I zařízení, které naopak pouze posílají data směrem do počítače, lze propojit také dvěma vodiči. Na straně zařízení se pin TxD spojí s pinem RxD na počítači, vše se doplní signálovou zemí Ground.
  3. Při požadavku na poloduplexní přenos s malým důrazem na přenosovou rychlost (a SW řízením přenosu) stačí na obou konektorech navzájem propojit piny TxD a RxD a výsledek propojit jedním vodičem (druhým vodičem je zem).
  4. Velmi časté je zapojení, kdy se pin TxD z prvního konektoru propojí s pinem RxD na konektoru druhém a naopak. Získáme tak podporu pro plně duplexní přenos po třech vodičích – TxD–RxD, RxD–TxD, Ground–Ground. Vyžadováno je SW řízení přenosu dat.
  5. Při požadavku na HW řízení přenosu lze použít některou z konfigurací takzvaného null modemu. První zapojení vypadá takto: TxD–RxD, RxD–TxD, Ground–Ground, (RTS+CTS)–(RTS+CTS) (signály jsou spojeny), (DSR+DTR)–(DSR+DTR).
  6. Úplné zapojení null modemu: TxD–RxD, RxD–TxD, Ground–Ground, RTS–CTS, CTS–RTS, DSR–DTR, DTR–DSR (význam si popíšeme příště).
  7. Některé sériové tiskárny vrací stavový bit a musí být zapojeny takto: TxD–RxD, Ground–Ground, (DSR+CTR)–DTR. Jedná se o takzvaný protokol DTR.
pc4003

Obrázek 3: Význam jednotlivých pinů konektoru DB-9/DE-9 v případě, že je využívaný sériovým portem.

3. Sériové porty na osobních počítačích

Sériové porty jsou na osobních počítačích používány již od prapůvodního IBM PC. Proto existuje podpora pro jejich ovládání v BIOSu, tj. programu, který se mj. stará o základní inicializaci zařízení a spuštění zavaděče operačního systému – počítač se při takzvaném POSTu (Power On Self Test) pokouší nalézt první dva (v některých případech dokonce první čtyři) sériové porty v pořadí COM1COMn a uloží bázové adresy jejich konfiguračních registrů do své datové oblasti nazývané proměnné BIOSu, která se v reálném režimu mapuje od adresy 0×0400 výše (na moderních základních deskách je možné adresy sériových portů – a tím i jejich jméno – měnit přímo v konfiguraci BIOSu, u starších desek se musely použít jumpery). Operační systémy spuštěné po inicializaci proměnných BIOSu buď tyto informace použijí, nebo se samy pokouší o nalezení dostupných sériových portů. V případě multiportových karet (k dostání jsou například karty obsahující osm či dokonce šestnáct sériových portů) je to dokonce nezbytné, protože standardní BIOS více než dva (čtyři) porty nedokáže najít.

pc4004

Obrázek 4: Počítačová myš připojitelná k sériovému portu. Tyto typy myší, z nichž mnohé díky své odolnosti vydržely až do dnešních dnů, jsou stále v operačních systémech podporovány.

Následuje výpis proměnných BIOSu, které se vztahují k sériovým portům (pro doplnění předchozích částí tohoto seriálu jsem přidal i údaje o portech paralelních):

Adresa Symbolické jméno Význam
0×0400 COM1 bázová adresa prvního sériového portu
0×0402 COM2 bázová adresa druhého sériového portu
0×0404 COM3 bázová adresa třetího sériového portu
0×0406 COM4 bázová adresa čtvrtého sériového portu
0×0408 LPT1 bázová adresa prvního paralelního portu
0×040a LPT2 bázová adresa druhého paralelního portu
0×040c LPT3 bázová adresa třetího paralelního portu
0×040e LPT4 bázová adresa čtvrtého paralelního portu

Každý standardní sériový port se ovládá pomocí sedmi konfiguračních registrů; v průběhu vysílání či příjmu dat může být navíc generováno hardwarové přerušení (více viz následující kapitoly). Konfigurační registry řadičů sériových portů jsou umístěny do I/O oblasti, tj. přistupuje se k nim pomocí strojových instrukcí IN a OUT (v Céčku se jedná o funkce či makra inb() a outb(), viz popis programování paralelního portu uvedený ve třicáté sedmé části tohoto seriálu). Standardně, tj. po nalezení sériových portů BIOSem, je rozsah adres konfiguračních registrů jednotlivých sériových portů COM1COM4 a číslo generovaného hardwarového přerušení následující:

Port I/O adresa od I/O adresa do Přerušení
COM1 0×3f8 0×3ff IRQ4
COM2 0×2f8 0×2ff IRQ3
COM3 0×3e8 0×3ef IRQ4, IRQ5 nebo IRQ7
COM4 0×2e8 0×2ef IRQ3, IRQ5 nebo IRQ7
pc4005

Obrázek 5: Díky značnému rozšíření sériového portu existuje mnoho součástek, které sériovou komunikaci podporují. Na tomto schématu je ukázáno jednoduché zapojení teplotního čidla k počítači. Přes pin RxD se čte teplota posílaná ve formě stále opakované sekvence bytů.

4. Konfigurační registry UART

Stručný význam jednotlivých konfiguračních registrů mapovaných do výše uvedeného rozsahu sedmi adres (každý z registrů má délku jednoho bajtu) je uveden v tabulce zobrazené pod tímto odstavcem. Některé registry jsou určeny pouze pro čtení, další jen pro zápis, a do zbylých je možné data číst či naopak zapisovat (zapisovaná a čtená dat mají obecně rozdílný význam). Funkce prvních dvou konfiguračních registrů při programovém zápisu je dvojí – registr na offsetu 0 běžně slouží k vysílání bajtu (přesněji řečeno k zápisu bajtu, který je později bit po bitu vyslán na linku) a registr na offsetu 1 pro nastavení přerušení. Ovšem tyto registry mají i alternativní funkce, protože se pomocí nich nastavuje dělitel hodin, který je použitý jak při vysílání, tak i při příjmu. Hodnota dělitele hodin určuje přenosovou rychlost. To, jaké informace se v daném okamžiku zapisují do konfiguračních registrů na offsetu 0 a 1 závisí na stavu sedmého (nejvyššího) bitu registru ležícího na offsetu 3 (takzvaný DLAB). Při vysílání dat je tento bit nulový, ovšem v průběhu konfigurace sériového portu je nastavený na jedničku. V tabulce jsou popsány registry standardního UARTu, který neobsahuje frontu vysílaných a přijímaných dat:

Port (offset) Adresa pro COM1 Adresa pro COM2 čtení zápis význam
+0 0×3f8 0×2f8 ano ano vysílací a přijímací registr, dolní bajt dělitele hodin
+1 0×3f9 0×2f9 ne ano povolení přerušení, horní bajt dělitele hodin
+2 0×3fa 0×2fa ano ne identifikace přerušení (příznak, co přerušení způsobilo)
+3 0×3fb 0×2fb ano ano řízení linky, počet stop bitů, nastavení parity atd.
+4 0×3fc 0×2fc ne ano řízení modemu – doplňkových výstupních signálů
+5 0×3fd 0×2fd ano ne čtení stavu linky – chyb při přenosu
+6 0×3fe 0×2fe ano ne čtení stavu modemu – doplňkových vstupních signálů
pc4006

Obrázek 6: Jeden z dnes již historických terminálů, který se k serveru připojoval přes sériový port. Již na tomto terminálu je patrný jeden (ve své době „novátorský“) designový prvek – horní část terminálu se začínala čím dál tím více zešikmovat a zakulacovat, aby se na něj nedaly stavět hrnečky s kávou :-) a především papíry či knihy, které by zakrývaly větrací otvory.

5. Nastavení přenosové rychlosti sériového portu

Již minule jsme si řekli, že obě komunikující zařízení, tedy jak přijímací, tak i vysílací strana, se nejprve musí vhodným způsobem nakonfigurovat, aby přijímač věděl, v jakém formátu má data očekávat a jak rychle je nutné vzorkovat datovou linku, neboli jaká je přenosová rychlost. Na obou zařízeních se musí především nastavit počet přenášených bitů v jednom celku, což je pět až osm bitů (dnes prakticky vždy osm bitů, tj. jeden bajt), přenosová rychlost uváděná v počtu bitů přenesených za jednu sekundu (bitrate), délka stopbitu a v některých případech i to, zda a jakým způsobem se přenáší paritní bit, který představuje velmi primitivní podobu detekčního kódu. Toto nastavení musí být na přijímači i vysílači shodné, což je také jeden z důvodů, proč je většina zařízení typu UART konfigurovatelná – pomocí několika konfiguračních registrů se přijímač a vysílač nastaví tak, aby spolu mohly navzájem komunikovat. V případě sériových portů v osobních počítačích se tyto hodnoty nastavují pomocí konfiguračních registrů ležících na offsetu 0, 1 a 3 (viz tabulka uvedená v předchozí kapitole).

Pomocí konfiguračních registrů ležících na offsetu 0 a 1 lze nastavit přenosovou rychlost. Ta se nezadává přímo, ale formou dvoubajtové hodnoty, kterou jsou děleny hodinové impulsy generované čipem UART (na čip je připojený krystal s frekvencí nastavenou typicky na hodnotu 14,7456 MHz, 18,432 MHz či 29,4912 MHz, základní frekvence je rovna 1,8432 MHz). V další tabulce jsou vypsány hodnoty dělitele zapisované do konfiguračních registrů ležících na offsetu 0 a 1 (nižší – vyšší bajt). Hodnota dělitele se získá snadno když si uvědomíme, že bitová rychlost vynásobená hodnotou dělitele se vždy rovná konstantě 115200:

bitů za sekundu dělitel poznámka
110 1040 nepřesné, ale v mezích normy
150 768
300 384
600 192
1200 96
2400 48 cca touto rychlostí se nahrávaly programy z kazety na osmibitových počítačích
4800 24
9600 12 bez problémů funguje i při propojení počítačů třemi zvonkovými dráty na vzdálenost cca 10 metrů :-)
18200 6
38400 3
57600 2
115200 1 této přenosové rychlosti lze dosáhnout na kratší vzdálenosti

Výše uvedené přenosové rychlosti možná někteří ze čtenářů znají, protože odpovídají teoretickým přenosovým rychlostem modemů. Mohlo by se zdát, že rychlost modemu (přesněji řečeno rychlost přenosu dat po vytáčené analogové či digitální lince) by měla být stejná, jako rychlost nastavená na sériovém portu, pomocí kterého počítač s modemem komunikuje. Ve skutečnosti by se však měla pro tuto komunikaci nastavit rychlost minimálně o jeden stupeň větší (38400 bps – 57600 bps apod.), protože do modemu jsou kromě vlastních dat přenášeny i další řídicí bajty a samotný externí modem dokáže vysílaná data komprimovat. Pokud by tedy byly obě přenosové rychlosti nastaveny na stejnou hodnotu, mohlo by se stát, že by byl přenos dat přes vytáčenou linku nepatrně pomalejší (a v případě u nás platných tarifů i dražší), protože by se čekalo na data posílaná z počítače nebo naopak pro data posílaná z modemu do počítače. Nicméně připojení počítače modemem je dnes (pro domácnosti) spíše nouzové řešení (ovšem propojení dvou počítačů po vlastním metalickém vedení na vzdálenost delší, než je běžný dosah Ethernetu, je například v průmyslu stále používáno).

pc4007

Obrázek 7: Grafický terminál VT-105 ovšem jako stojánek na knížky plně vyhovoval.

6. Konfigurace dalších parametrů přenosové linky

Přes konfigurační port ležící na offsetu 3 se nastavuje počet přenášených bitů. V současnosti většina aplikací vyžaduje vždy přesun osmi bitů (jednoho znaku/bajtu), ovšem z historických důvodů je podporován i přenos pěti, šesti či sedmi bitů. Rozdělení dat na pětice/šestice/sed­mice bitů musí řešit programátor, ovšem do UARTu se vždy zapisuje všech osm bitů, z nichž je přeneseno jen n nejnižších bitů. Dále se v tomto konfiguračním registru povoluje či zakazuje paritní bit (tj. zda se vůbec paritní bit posílá) a také, jakým způsobem má UART paritní bit generovat. Možné jsou čtyři možnosti – lichá parita (lichý součet jedniček), sudá parita, paritní bit je vždy nulový (takzvaná space) a paritní bit je vždy jedničkový (mark). Velmi důležitý je sedmý, tj. nejvyšší bit tohoto registru, protože se pomocí něj mění smysl prvního a druhého konfiguračního registru – viz předchozí kapitola, ve které jsme se zabývali nastavením přenosové rychlosti.

Bit registru na offsetu 3 Význam
0–2 délka přenášeného slova a počet stop bitů:
    000: 5 bitů/znak, 1 stop bit
    001: 6 bitů/znak, 1 stop bit
    010: 7 bitů/znak, 1 stop bit
    011: 8 bitů/znak, 1 stop bit
    100: 5 bitů/znak, 1,5 stop bitu
    101: 6 bitů/znak, 2 stop bity
    110: 7 bitů/znak, 2 stop bity
    111: 8 bitů/znak, 2 stop bity
3 povolení parity: 0=žádná parita
4–5 typ parity:
    00: lichá parita
    01: sudá parita
    10: paritní bit je vždy 0
    11: paritní bit je vždy 1
6 vysílání sekvence nul (takzvaný break)
7 pokud je zde uložena hodnota 1, lze nastavit dělitel rychlosti

Na takto nízké úrovni se sériovým portem dnes pracují prakticky jen vývojáři jádra. Pro běžné uživatele (kteří však musí mít delegována příslušná práva) je v Unixovém světě určena utilita setserial, pomocí které se parametry sériového přenosu dají specifikovat. Tato utilita také dokáže vypsat současné nastavení a dokonce i typ čipu UART, který je v počítači použit (novější UART mají přednost v tom, že obsahují fronty, více si řekneme v další části seriálu). Typické nastavení portu pro komunikaci se označuje jako 8N1, tj. přenáší se osm bitů bez parity a s jedním stop bitem. Přenosovou rychlost je nutné nastavit tak, aby ji podporovala obě zařízení, ovšem lze ji také uměle snížit (například tehdy, když se komunikuje na delší vzdálenost po méně kvalitní lince).

pc4008

Obrázek 8: Jeden ze způsobů ovládání nějakého zařízení pomocí PDA. Všimněte si, že jsou zde použity hned tři typy konektorů – „kolébkový“ konektor u PDA, standardní DB-9/DE-9 a na konci také standardní (i když u sériového portu poněkud neobvyklý) konektor typu RJ-11.

ict ve školství 24

7. Odkazy na Internetu

8. Obsah dalšího pokračování seriálu

V následující části seriálu o architekturách počítačů téma sériové komunikace pomocí portu typu RS-232C dokončíme. Řekneme si, jakým způsobem lze řídit přenos dat; jak pomocí signálů DTR/DSR či RTS/CTS, tak i programově – většinou pomocí řídicích znaků XON a XOFF.

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.