Při návrhu rozhraní mezi počítačem a jiným elektronickým systémem nemáme mnoho volnosti a musíme se podřídit již existujícím rozhraním a protokolům. Jako velice slibné se jeví připojení pomocí USB (Universal Serial Bus). Toto rozhraní není náročné na kabeláž (postačí mu 4mi vodiče), poskytuje dostatečnou přenosovou rychlost pro většinu aplikací, nabízí napájení přímo z PC a zároveň je dostupné na všech novějších počítačích. Nevýhodou však je, že komunikační protokol USB je poměrně složitý na implementaci. Rozumným řešením, které hodlám v tomto referátu představit, je použítí mikročipu, který sám umí komunikovat po USB a uživateli nabídne jednodušší rozhraní.
Právě tyto obvodny nabízí firma FTDI Chip (http://www.ftdichip.com/). Konkrétně se jedná o obvody FT232R (převodník USB na seriový UART) a FT245R (převodník USB na FIFO s 8bit paralelní sběrnicí). První zmiňovaný lze využít pro stavbu redukce USB - RS232 (tj. standardní COM port). Ve zbytku referátu se budu zabývat pouze druhým zmiňovaným (USB - FIFO převodníkem).
![]() |
|
Další informace o zapojení naleznete v dokumentu [1], příadně v ukázkové aplikaci (6. část). Aby mohl obvod fungovat, je nutné doplnit jej několika pasivními součástkami (6MHz krystal, rezistory a kondenzátory). Volitelně lze také připojit sériovou paměť EEPROM 93C46 (případně 93C56 nebo 93C66), do které lze uložit informace o výrobku (viz. 5. část)
Jak jsem již uvedl v předchozích kapitolách, obvod FT245 převádí USB na 8 bitovou paralelní sběrnici. Dosud jsem však nezmínil, jak je řízen provoz na této sběrnici. Obvod je navržen tak, že přenechává veškeré řízení na uživateli (tj. na jiném zařízení). K tomuto účelu jsou určeny piny RD, WR, TXE a RXF (viz. 2. část). Piny RD a WR jsou řídící brány, které spouští čtení (resp. zápis) z/na sběrnici. Proti nim jsou flagy RXF a TXE, které signalizují připravenost ke čtení/zápisu. Cykly čtení (resp. zápisu) probíhají následovně:
Cyklus čteníOperace čtení nesmí začít, dokud RXF neklesne na nízkou úroveň, čímž signalizuje, že ve vyrovnávácí paměti jsou připravena data ke čtení. Řídící obvod může zahájit čtení snížením brány RD na nízkou úroveň. Obvod FT245 vystaví na sběrnici data a to s max. spožděním T3, které podle specifikace nepřesáhne 50ns. Obvod zajišťuje, že data budou dostupná, po celou dobu, dokud řídící obvod nevrátí RD zpět na vysokou úroveň. Minimální a maximální specifikované časové odstupy jsou vypsány v dokumentu [1]. |
![]() |
![]() |
Cyklus zápisuOperace zápisu může být zahájena pouze pokud je TXE na nízké úrovni (čímž signalizuje připravenost k zápisu). Změna stavu brány WR na vysokou úroveň signalizuje obvodu, že bude probíhat zápis. Obvod nastaví své piny D0-D7 na vstup a očekává vystavení platných dat. Řídící obvod může vystavit platná data kdykoli v době T7, kdy drží WR ve vysoké úrovni, avšak nejméně 20ns (čas T9) před tím, než spustí WR zpět do nízké úrovně. Dle schématu by měl řídící obvod držet platná data na sběrnici ještě po dobu T10 po spuštění WR, avšak specifikace uvádí, že min. délka intervalu T10 je 0ns. Přesnou specifikaci všech časových odstupů naleznete rovněž v dokumentu [1]. |
Společnost FTDI nabízí ke stažení (zdarma) ovladače pro její produkty. Podporovány jsou operační systémy Windows (včetně Windows CE), Linux i MacOS. Ovladače jsou nabízeny ve dvou verzích: VCP (Virtual Com Port) a D2XX. Ovladače VCP vytvoří v systému nový virtuální COM port a veškerá komunikace pak probíhá přes něj. Tento ovladač je vhodný zejména pro nasazení s obvodem FT232. USB se pak stává transparentní a HW i SW aplikace pracuje se stadnardním COM portem. Ovladače D2XX nabízí uživateli DLL knihovnu, která definuje základní komunikační funkce (poslání a příjem bytu, nastavení rozhraní, práce s pamětí EEPROM, apd.). Právě těmito funkcemi se zde budu zabývat.
FT_STATUS FT_Open (int iDevice, FT_HANDLE *ftHandle)
iDevice - pořadové číslo zařízení (0 - pokud jiné zařízení není připojeno k systému)
ftHandle - proměnná na kterou ukazuje bude v případě úspěchu naplněna platným handlerem
Návratová hodnota: FT_OK pokud je vše vpořádku, jinak obsahuje kód FT chyby
Tato funkce při úspěšném volání vrátí (v proměnné *ftHandle) handler otevřeného zařízení, který je potřeba pro volání dalších funkcí. Zařízení připojovaná k systému postupně dostávají čísla (0, 1, 2 ...), kterými jsou identifikována při otevírání (parametr iDevice). Pokud je v systému jen jedno FTDI zařízení, stačí volat funkci FT_Open s parametrem iDevice = 0. Pokud je zařízení víc, je potřeba volat jiné funkce, abychom zjisitili, které zařízení je které (viz FT_OpenEx, FT_ListDevices, FT_GetDeviceInfoList, ...)
FT_STATUS FT_Close (FT_HANDLE ftHandle)
ftHandle - handler otevřeného zařízení
Návratová hodnota: FT_OK pokud je vše vpořádku, jinak obsahuje kód FT chyby
Funkce zavře používaný handeler zařízení.
FT_STATUS FT_Read (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToRead, LPDWORD lpdwBytesReturned)
ftHandle - handler otevřeného zařízení
lpBuffer - ukazatel na buffer, do kterého budou data uložena
dwBytesToRead - počet bytů ke čtení
lpdwBytesReturned - ukazatel na proměnnou, do které bude uložen počet skutečně přečtených bytů
Návratová hodnota: FT_OK pokud je vše vpořádku, jinak obsahuje kód FT chyby
Funkce se pousí přečíst dwBytesToRead bytů z USB. Pokud není ve vyrovnávací paměti dostatek přijatých bytů, funkce se zablokuje a čeká na příchod zbývajících bytů. Lze nastavit maximální čas, po který má čekat (viz FT_SetTimeouts). Počet bytů, které aktualně čekají ve vyrovnávací paměti, lze získat funkcemi FT_GetStatus nebo FT_GetQueueStatus.
FT_STATUS FT_Write (FT_HANDLE ftHandle, LPVOID lpBuffer, DWORD dwBytesToWrite, LPDWORD lpdwBytesWritten)
ftHandle - handler otevřeného zařízení
lpBuffer - ukazatel na buffer, ve kterém jsou data k odeslání
dwBytesToWrite - počet bytů k zápisu
lpdwBytesWritten - ukazatel na proměnnou, do které bude uložen počet skutečně zapsaných bytů
Návratová hodnota: FT_OK pokud je vše vpořádku, jinak obsahuje kód FT chyby
Funkce pošle dwBytesToWrite na zařízení USB. Pokud nemohou být data odeslána ihned (např. protože konzument nestíhá data odebírat), funkce se zablokuje. Max dobu po kterou bude zablokovaná lze nastavit funkcí FT_SetTimeouts.
FT_STATUS FT_ResetDevice (FT_HANDLE ftHandle)
ftHandle - handler otevřeného zařízení
Návratová hodnota: FT_OK pokud je vše vpořádku, jinak obsahuje kód FT chyby
Vyvolá reset obvodu FTDI.
FT_STATUS FT_SetDtr (FT_HANDLE ftHandle)
FT_STATUS FT_ClrDtr (FT_HANDLE ftHandle)
FT_STATUS FT_SetRts (FT_HANDLE ftHandle)
FT_STATUS FT_ClrRts (FT_HANDLE ftHandle)
ftHandle - handler otevřeného zařízení
Návratová hodnota: FT_OK pokud je vše vpořádku, jinak obsahuje kód FT chyby
Tyto funkce nastavují (Set) nebo nulují (Clr) řídící bity Dtr (Data Terminal Ready) a Rts (Request To Send), které se používají u rozhraní RS232. Použití těchto funkcí má smysl pouze s obvodem FT232.
FT_STATUS FT_SetTimeouts (FT_HANDLE ftHandle, DWORD dwReadTimeout, DWORD dwWriteTimeout)
ftHandle - handler otevřeného zařízení
dwReadTimeout - maximalní počet milisekund, po které bude operace FT_Read čekat na data
dwWriteTimeout - maximalní počet milisekund, po které bude operace FT_Write čekat na data
Návratová hodnota: FT_OK pokud je vše vpořádku, jinak obsahuje kód FT chyby
Vyvolá reset obvod FTDI.
FT_STATUS FT_GetQueueStatus (FT_HANDLE ftHandle, LPDWORD lpdwAmountInRxQueue)
ftHandle - handler otevřeného zařízení
lpdwAmountInRxQueue - ukazatel na proměnnou, do které se uloží počet bytů aktuálně dostupných k přečtení
Návratová hodnota: FT_OK pokud je vše vpořádku, jinak obsahuje kód FT chyby
Výsledné číslo uložené v *lpdwAmountInRxQueue je vhodné rovnou předat funkci FT_Read. Tím se dosáhne nejoptimálnějšího vytížení linky (FT_Read přečte všechna akt. dostupná data a nezablokuje se).
Zde byly zmíněny pouze základní funkce pro ovládání a komunikaci s ovbody FTDI. Podrobnější popis a další funkce (zejména pak funkce pro práci s pamětí EEPROM a identifikaci jednotlivých USB zařízení) naleznete v dokumentu [2]
![]() Program MPROG |
Přídavná paměť EEPROM uchovává základní informace o součástce. Např:
Tyto informace jsou automaticky poskytnuty operačnímu systému při připojení zařízení do USB. Měnit je lze pomocí funkcí popsaných v dokumentu [2]. Firma ASIX napsala šikovnou utilitku MPROG, která umí upravovat položky v paměti EEPROM právě připojeného FTDI zařízení. Formát vnitřní reprezenace dat v paměti bohužel není běžně dostupný (tj. firma FTDI jej nezveřejnila). Paměť EEPROM je volitelnou součástí a v jednodušších aplikacích se bez ní velice dobře obejdeme. |
Při stavbě USB rozhraní s obvodem FT245B jsem potřeboval navrhnout jednoduchou aplikaci, na které bych rozhraní také vyzkoušel. Za tímto účelem jsem navrhl systém zobrazování informací z PC na malém znakovém LCD displeji. Displej je sám o sobě stejně pasivní součástkou jako obvod FT245, a proto bylo potřeba přidat ještě nějaký řídící obvod, který by se staral o správný provoz na sběrnici a důsledně dodržoval i předepsané časové prodlevy. Nakonec jsem vybral mikrokontrolér PIC 16F84 od firmy Microchip, protože s ním mám již nějaké zkušenosti a umím jej naprogramovat.
Na schématu je vidět zapojení všech 4 zařízení a pasivních součástek. Při fyzickém návrhu jsem umístil obvod FT245 a pamět EEPROM se všemi potřebnými součástkami na jeden tištěný spoj (viz. část 6.3). Ze schématu je rovněž patrné, že na 8bit sběrnici je připojen také mikrokontrolér PIC. Toto zapojení jsem navrhl, aby kontrolér také mohl posílat příkazy na řadič LCD displeje.
Celý systém je navržen jednosměrně (tj. PC může posílat příkazy, ale neobdrží žádný feedback). K jednosměrné komunikaci jsem přistoupil proto, že kontrolér PIC má pouze 13 použitelných pinů, z toho 8 je připojeno na sběrnici a 3 jsou potřeba pro LCD. Zbývají tedy pouze 2 piny pro řízení obvodu FT245 a čtení je v této aplikaci mnohem důležitější. Brána WR a flag TXE zůstali nevyužity.
LCD displej nabízí také komunikaci ve speciálním 4-bitovém módu. Z 8mi bitové sběrnice se využijí pouze 4 bity a každý byte se tedy posílá na dvakrát (horní a dolní 4 bity). Tím bych ušteřil 4 piny na kontroléru PIC a mohl bych si tak dovolit zapojit obvody, aby komunikovaly obousměrně. Komunikační protokol by se však zesložitil a podle mého názoru by ale výsledný efekt neodpovídal vynaložené námaze. Mohlo by to však být užitečné (a námaha by se již vyplatila), pokud bych chtěl obohatit aplikaci např. o tlačítka u displeje.
Kontrolér PIC by mohl samozřejmě jen řídit provoz na sběrnici a o komunikaci s LCD displejem by se staral software v PC. Vzhledem k vlastnostem obvodů PIC jsem se rozhodl napsat sofistikovanější program pro kontrolér a ponechat softwarové aplikaci méňě práce. Tento přístup si rovněž vyžádal navržení sofistikovanějšího protokolu pro komunikaci mezi počítačem a kotrolérem.
Kontrolér PIC má na starosti několik věcí. V první řadě je zodpovědný za korektní inicializaci LCD displeje po náběhu napájení.
Dále nabízí tyto nízkoúrovňové funkce:
- tisk čistého textu na LCD displej, kde LCD displej se chová jako terminál (tj. text odscrolovává nahoru)
- nastavení základních parametrů displeje (zobrazení kurzoru, blikání kurzoru, nastavení fontu apd.)
- vymazání displeje
- přímé přeposlání bytu z USB do LCD displeje
Aby mohl počítač ovládat kontorolér posílá mu "příkazy". Kontrolér (pokud zrovna nevykonává příkaz) aktivně čeká na příchod nového příkazu (tj. v nekonečné smyčce testuje flag RXF). Příkazy jsou různě dlouhé. PIC nejprve přijme první (instrukční) byte a z něho pozná, jaký příkaz mu je poslán a kolik další (datových) bytů má ještě přimout. Proces zpracování jednotlivých příkazů je tedy silně stavový a softwarová aplikace jej musí striktně dodržovat. V případě nedodžení počtu datových bitů nastane problém, protože kontrolér bude chápat datové bity jako instrukce a chování začne být nedefinované. Kontrolér rozeznává tyto instrukce:
00nn nnnn
- Nejvyšší dva bity signalizují, že se jedná o instrukci přenosu čistého textu. Spodních 6 bitů se chápe jako číslo (z rozsahu 0-63),
které říká kontroléru, kolik datových bytů bude následovat. Kontrolér tedy načte příslušný počet bytů a zapíše je na diplej jako text. O další věci
(např. posun řádků na displeji) se stará kontrolér automaticky. Tato instrukce se dá také využít jako instrukce NOP. Pokud kontrolér přijme byte 0x00 (tj. 0000 0000),
chápe to, jako zápis 0 znaků textu a tedy nebude nic vykonávat. V případě, že by se softwarové aplikaci náhodou stalo, že ztratí přehled o tom,
kolik datových bytů má ještě poslat (avšak v dobře napsané aplikaci takový problém vůbec nenastane), může poslat kontroléru sekvenci 64 znaků 0x00,
a tím si zajistí, že kontrolér bude ve stavu očekávání další instrukce.
01?e dcbf
- Nastavení parametrů / smazání displeje. Kontrolér přečte tuto instrukci a následně provede příslušnou úpravu v nastavení LCD displeje,
případně zajistí jeho smazání. Instrukce je samostatná - tj. nenásledují po ní žádné datové byty. Význam jednolivých bitů v instrukčním byte:
(e)rase - 0 = pouze nastavení parametrů, 1 = nastavení parametrů a smazání displeje.
(d)isplay - 0 = vypnout, 1 = zapnout displej
(c)ursor - 0 = schovat, 1 = zobrazit kurzor
(b)link - 0 = vypnout, 1 = zapnout blikání kurzoru
(f)ont - 0 = výchozí font 5x7, 1 = vysoký font 5x10 (ne všechny displeje tuto funkci podporují)
Pozn: ? = na hodnotě tohoto bitu nezáleží
1??? ???r
- Přímé propojení FT245 s LCD řadičem. Po této instrukci kontrolér přijme právě jeden datový byte, které přímo přepojí na řadič LCD
(byte se neukládá v kontroléru, ale je poslán přímo po sběrnici). Na korektní komunikaci s LCD je potřeba mít ještě správně nastavený RS flag, který rozlišuje,
zda budou data na sběrnici chápána jako instrukce nebo jako data (znak). Před započetím transakce nastaví kontrolér RS flag u LCD řadiče na hodnotu r
(nejnižší bit instrukčního bytu). Dokumentaci k řadiči LCD displeje naleznete v příloze [5]
Aplikaci (v tomto kontextu by se hodilo spíše označení firmware) pro kontrolér jsem napsal v PIC assemleru a přeložil volně dostupným překladačem od firmy Microchip. K naprogramování samotného kontroléru mi posloužil programátor PICOLO, který je asi nejlevnějším programátorem PICů na českém trhu. Jako ovládací aplikaci pro programátor používám program UP od firmy Asix, který je zdarma. Kód programu v assembleru nebudu vkládat do tohoto dokumentu, ale nabídnu jej k prostudování jako přílohu [4]. Přesto, že je tento referát česky, komentáře v programu jsem psal již ze zvyku v angličtině (sorry for any inconvenience :) ).
Při výrobě mi šlo především o převodník mezi USB a FIFO. Samotná aplikace měla pouze otestovat toto rozhraní. Na vyrobeném tištěném spoji je proto umístěn pouze obvod FT245, paměť EEPROM a nezbytné pasivní součástky (odpory, kondenzátory a především 6MHz krystal). Pro připojení k počítači jsem na desku umístil také konektor USB typu B (pro připojení k PC pak stačí použít klasický USB A-B kabel). Piny 8 bitové sběrnice, řídící brány a flagy jsem vyvedl na externí kolíčky s rozpětím 2,54mm, které zajišťují snadné propojení s jinými elektronickými aplikacemi.
Při návrhu desky jsem si sice vše pečlivě dvakrát zkontroloval, ale i tak se mi podařilo udělat v návrhu chybu. Konkrétně jsem u zapojení konektoru pro USB špatně nastudoval specifikaci a desku navrhl zapojenou zrcadlově. Vše samozřejmě vyřešila ostrá rýsovací jehla (kterou jsem přerušil vodivé cesty) a několik drátových propojek. Pravidlo číslo jedna, které je tedy třeba dodržovat (a zkušenějším čtenářům již není vůbec třeba jej přípomínat) je kontrolovat návrh desky vícekrát.
Pro výrobu jsem použil stadnardní jednoustranonou kuprextitovou destičku, kterou jsem řádně očistil a odmastil technickým benzínem. Vodivé cesty jsem překreslil speciálním lihovým fixem s tenkým hrotem. Přebytečnou měď mi pomohl odstranit můj věrný pomocník chlorid železitý (FeCl3). Nakonec zbývalo už jen vyvrtat otvory pro součástky miniaturní vrtačkou s 0,9mm vrtákem.
Samotné letování obvodu FT245 se nakonec ukázalo jako velice obtížné, avšak ne nemožné. Je to zábava na dlouhé hodiny, která prověří vaši zručnost stejně jako pevnost nervů. K letování jsem použil stolní hrotovou pájku (s odděleným transformátorem), abych obvod nezničil. Vždy po přiletování několika málo pinů jsem hrot znovu naostřil na brusce, protože šířka jehly se s nabalujícím cínem rychle zvětšovala. Ne příliš vkusný výsledek můžete vidět na obrázku vpravo. Osazení ostatních součástek již nebylo problémem.
Pokud bych se měl do podobného letování pouštět znovu, rozhodně bych zvolil jiný postup. Jako nejlepší volba pro domácí podmínky mi připadá nanesení pájecí pasty na tištěný spoj a následné zapájení všech pinů naráz pomocí horkovzdušné pájky. K tomu postačí i obyčejná horkovzdušné pájka na plyn (není třeba sahat po drahých horkovzdušných stanicích).
Poslední část projektu, kterou zbývalo dořešit, bylo napsání jednoduchého programu, který by ovádal LCD displej (prostřednictvím USB a kontroléru PIC). Celý program jsem napsal v jazyce C s použitím knihoven FTDI (pro komunikaci po USB) a GTK+ 2.6 (pro vytvoření uživatelského rozhraní). Program je určen pro platformu Windows. Vyvíjel jsem jej v prostředí Dev-C++, pro které jsou také určeny zdrojové kódy dostupné v příloze [5] (zdrojové kódy by měly jít přeložit i v jiných prostředích, avšak doporučuji použít kompiláor GCC). Uživatelské tozhraní i komentáře zdrojových kódů jsou opět v angličtině.
![]() Posílání jednoduchého textu na LCD |
![]() Nastavení vlastností displeje |
![]() Posílání řídících bytů přímo na řadič LCD |
![]() Výpis bytů poslaných přes sběrnici |
Hlubší komentář tomuto software si dovolím vypustit. Všechny důležité věci naleznete v části 4 a v části 6.2. Při čtení zdrojových souborů mějte prosím na paměti, že část kódu generoval program Glade (určený k navrhu uživatelského rozhraní s použitím knihoven GTK+). Soubory, které stojí za prohlédnutí jsou (usb.h, usb.c, a callbacks.c).
Rozhraní mezi počítačem a jinými elektronickými systémy se čím dál více stává nezbytností dokonce i pro amatéry (jako jsem například já), kteří mají elektrotechniku jen jako koníček. Implementovat protokol USB by bylo velice náročné i za použití sofistikovanějších kontrolérů, ale - jak jsem se snažil ukázat v tomto referátu - existují i alternativní řešení. I přesto, že je elektrotechnika mým koníčkem, znovu bych se do tohoto projektu nepouštěl. Letování a příprava desky pro takto miniaturní obvod je velice náročná. Bylo sice velice zábavné procvičit si moje dovednosti s tenkým lihovým fixem a následně s pájkou, ale při zpětném pohledu bych dal přednost zakoupení modulu (např. UMP2), který je osazen odvodem FT245B s potřebnými součástkami. Modul nabízí možnost připojit si včechny ostatní součástky (včetně USB konektoru a EEPROM) podle vlastních potřeb a zároveň má piny osazené ve vzdálenosti 2.5 mm (tedy jako obvod ve standardním DIP pouzdře).
Jako další slibná alternativa tomuto řešení se nabízí zakoupení redukce USB-RS232 (např. i založené na FT232), která zachová výhody USB (dostupnost, rychlost) a zároveň nabídne jednoduché sériové rozhraní, se kterým se dobře pracuje jak po stránce hardwarové, tak softwarové.