VGA zobrazovač s mikrokontrolerem

Jan Polášek, Marek Dohnal, UREL, FEEC, VUT Brno
xpolas13stud.feec.vutbr.cz
xdohna08stud.feec.vutbr.cz

Obsah:

  1. Úvod
  2. Realizace
  3. Rozbor programu
  4. Závěr
  5. Literatura

Úvod

Tento projekt ukazuje, jak je možné zobrazovat text na VGA monitoru pomocí mikrokontroleru. Je zde vysvětlena synchronizace obrazu a vykeslování textu na monitoru. Výsledný obraz má rozlišení 640 x 480 bodů s obnovovací frekvencí 60 Hz. Zobrazený text má 20 řádku a 19 znaků na řádek. Po zapnutí je zobrazena úvodní obrazovka, další text je do zobrazovače možné posílat pomocí sériového rozhraní. K realizaci byla použita zkušební deska, která se používá při výuce předmětu MMIA.

Realizace

Obraz VGA je tvořen 525 řádky, z nichž 480 je viditelných. Řádky obrazu jsou postupně vykreslovány na stínítko monitoru, čímž je tvořen obraz. Aby bylo možné určit začátek snímku a začátek řádku, jsou mimo oblast aktivního videa posílány horizontální a vertikální synchronizační impulsy.
Pro zobrazení obrazu na monitoru je nutné dodržet frekvenci synchronizačních impulsů. Kritická je zejména jejich pravidelnost. Proto se pro tvorbu impulsů použije přerušení od interního čítače. Synchronizační rutina je tvořena tak, že interní čítač generuje přerušení s řádkovou frekvencí 31,469 kHz. Je zavedena proměnná, která počítá řádky, to je potřeba pro generování horizontálního synchronizačního impulsu, který je aktivní po dobu trvání třetího a čtvrtého řádku. Na začátku každého přerušení se přičte 1 k proměnné počítající řádky a je generován horizontální synchronizační impuls, který trvá asi 3,77 s. Pokud je počet řádků roven 525, tak je proměnná vynulována. V řádcích 37 až 517 probíhá vykreslování obrazu.

Pro propojení monitoru a mikrokontroleru je třeba napojit synchronizační impulsy a obrazový signál. Monitor je připojen patnáctipinovým třířadým konektorem CANON. Horizontální synchronizační impuls je generován na PORTD7 mikrokontroleru a připojen na pin 13 konektoru VGA. Vertikální synchronizační impuls je generován na PORTD6 a připojen je na pin 14 VGA konektoru VGA. Signály synchronizačních impulsů mají úrovně TTL a je možné je připojit přímo z mikrokontroleru na VGA konektor. Aktivní jsou v úrovni L. obrazový signál je napojen z pinu MOSI mikrokontroleru na piny 1, 2 a 3 VGA konektroru. Na vstupech 1, 2 a 3 VGA konektoru jsou za normálních okolností přivedeny signály R, G, B pro vytváření barevného obrazu, ale vzhledem k tomu, že vytvářený obraz bude černobílý, tak jsou tyto piny propojeny. úroveň signálu na barevných vstupech je 0 až 0,7 V, kdy vyššímu napětí odpovídá větší jas Charakteristická impedance barevných vstupů je 75 ohmů. Výstup z pinu MOSI má úroveň TTL, takže jsou barevné vstupy připojeny přes rezistor 120 ohmů, což zajistí přizpůsobení napěťových úrovní. Piny 5, 6, 7, 8 a 10 VGA konektoru jsou propojeny na zem. Zapojení je patrné z následujícího obrázku.
Zapojení

Pro zobrazování textu na monitoru je třeba vytvořit a do paměti mikrokontroleru umístit znakovou sadu v podobě matic s jednotlivými znaky. Jednotlivé znaky jsou v paměti umístěny tak, že každý znak je rozložen na jednotlivé řádky umístěné v paměti za sebou. Z tohoto důvodu je každý znak sady široký 8 bodů. Výška matice znaku je 12 bodů. Matice znaku má z jedné strany v sobě obsaženu mezeru, která slouží jako mezera mezi jednotlivými znaky. Stejně tak má matice v sobě obsaženy mezery z vrchu a ze spodu, které slouží jako mezera mezi jednotlivými řádky textu. Toto opatření dovolí skládat znaky při vykreslování hned za sebe, aniž by mezi ně musely být vkládány mezery, a přesto jsou vykreslené znaky na obrazovce od sebe odděleny. Na jeden znak v matici zbývá tedy maximálně 7 bodů na šířku a 10 bodů na výšku. Signál je na výstup zapisován jako řetězec tvořený řádky těchto matic jdoucích za sebou. Znaková sada obsahuje velká a malá písmena, číslice a speciální znaky, které jsou obsaženy na anglické klávesnici. Znaky jsou v paměti uloženy za sebou podle pořadí, jaké mají v tabulce ASCII. Celý princip generování textu funguje tak, že je vytvořeno pole, které má takovou velikost, jako je maximální počet znaků, který je možné zobrazit na obrazovce. V tomto poli jsou uloženy kódy jednotlivých znaků v takovém pořadí, v jakém jsou znaky zobrazeny na obrazovce. Kódy znaků jsou ve formátu ASCII. Funkce, která se stará o vykreslování textu, si z tohoto pole bere adresy znaků ze znakové sady. Generování obrazu probíhá tak, že do registru SPDR je načten řádek matice znaku, jehož adresu získá vykreslovací funkce z pole znaků. Řádek je z registru vysunut na pin MOSI rozhraní SPI. Poté je načten do registru SPDR řádek matice dalšího znaku, který následuje na řádku textu, opět je "vysunut" a tak se pokračuje až do vykreslení jednoho řádku obrazu. Z registru SPDR jsou data po načtení vysouvána automaticky, aniž by byl spotřebováván strojový čas. Jsou zavedeny proměnné "akt_radek_textu" a "akt_radek_znaku". Proměnná "akt_radek_textu" udává, kolikátý řádek textu je právě vykreslován a proměnná "akt_radek_znaku" udává, kolikátý je vykreslován řádek matice znaku. Tato proměnná funguje jako ukazatel na aktuální vykreslovaný řádek matice znaku. Je inkrementována s každým řádkem obrazu, dokud nejsou vykresleny všechny řádky matice znaku. Poté je proměnná vynulována a začne se kreslit další řádek textu. Maximální rychlost vysouvání dat z registru SPDR na pin MOSI je rovna poloviční taktovací frekvenci mikrokontroleru, při použití mikrokontroleru s frekvencí 16 MHz je tedy maximální rychlost změny na pinu MOSI 8 MHz. Počet znaků na jeden řádek textu při vykreslování přes pin MOSI rozhraní SPI je 19. Výška jednoho znaku v matici je 12 bodů, ale každý řádek matice je kreslen dvakrát, písmo má tak na monitoru přirozenější tvar. Kdybychom vykreslovali každý řádek jednou, písmo by bylo příliš roztaženo do šířky. Takto je výška jednoho znaku na obrazovce 24 obrazových řádků. Počet zobrazitelných řádků textu je 480 / 24, tedy 20. Pole znaků má tedy velikost 19 * 20, což je 380 znaků.

Rozbor programu

Při práci na projektu byl vytvořen zdrojový kód programu, kde je vše detailně okomentováno. Celý projekt ve formátu zip je ke stažení zde.

Na začátku programu jsou uvedeny deklarace a definice, jak je běžné. Za zmínku stojí část, kde jsou definovány řetězce pro vykreslení úvodní obrazovky. Tyto řetězce jsou uloženy v programové paměti, aby nezaplňovaly operační paměť. Následuje synchronizační rutina, která startuje s přerušením od interního čítače 0. Dále se v oblasti aktivního videa povolí vykreslování a na začátku každého řádku textu se vynuluje proměnná pro počítání řádků znaku. V řádcích obrazu, kde nezačíná nový řádek textu, se musí provést několik instrukcí "No Operation", které zaberou stejně strojového času, jako nulování proměnné pro počítání řádků znaku, aby vykreslování obrazu začínalo na všech řádcích stejně. Poté následuje funkce pro inicializaci a nastavení. Zde je povoleno použití jednotek SPI a USART a nastaveny jejich parametry, vše je zřejmé z kódu. Dále je provedeno nastavení idle režimu, nastavení směrového registru portu D pro synchronizaci a nastavení časovače 0 pro spouštění synchronizace. Nakonec je povoleno globální přerušení. Program pracuje tak, že na začátku každého obrazového řádku je provedena synchronizace a když aktuální obrazový řádek patří do oblasti aktivního videa je, povoleno vykreslování. Ve funkci kresli obraz je nekonečná smyčka, která čeká na povolení vykreslování. Jakmile je vykreslování povoleno, začne vykreslování obrazového řádku. To se děje pomocí cyklu while, kde je zapnuto vykreslování a pak jsou postupně načítány do registru SPDR řádky matic znaků, tak jak jdou po sobě znaky na řádku textu. Po načtení řádku matice posledního znaku na řádku textu se čeká na jeho vykreslení na obrazovku, to je ošetřeno několika instrukcemi "No Operation", a potom dojde k vypnutí vykreslování. Takto jsou postupně vykreslovány všechny obrazové řádky. Na začátku nekonečné smyčky je mikrokontroler uveden do režimu idle, ze kterého je probouzen při povolení vykreslování v synchronizační rutině a nebo při přijetí znaku přes sériové rozhraní. To je potřeba proto, aby vykreslování každého řádku začalo přesně stejnou dobu po impulsu horizontální synchronizace, aby byl obraz na monitoru stabilní. Kdyby nebyl mikrokontroler uváděn do režimu idle, obraz by se na monitoru chvěl. Po inicializaci jsou do pole znaků nakopírovány řetězce, z nichž je tvořena úvodní obrazovka. Když dojde k příjmu znaku přes sériové rozhraní, skočí se do funkce, která zajišťuje příjem znaků a tvorbu pole znaků pro vykreslování. To funguje následovně: Je zavedena proměnná "cislo_akt_znaku", která vyjadřuje pořadí znaku, který byl naposledy přijat, v poli znaků. Po příjmu znaku je vyhodnoceno, jestli přijaty znak není Backspace nebo Enter. Když je přijat Backspace, dojde ke smazání posledního přijatého znaku v poli znaků, když je přijat Enter, provede se přechod na nový řádek. (hodnota proměnné "cislo_akt_znaku" se navýší tak, aby se příští přijatý znak zobrazil na novém řádku). Pokud je přijat jiný znak než Backspace nebo Enter, zapíše se jeho adresa na aktuální pozici v poli znaků a proměnná "cislo_akt_znaku" je inkrementována o 1. Dojde-li k tomu, že je pole znaků plné (obrazovka je už celá zaplněna znaky), je po příjmu nového znaku vynulováno, je vynulována také proměnná "cislo_akt_znaku" a nově přijatý znak se vypíše na začátek obrazovky.

Obraz na monitoru vypadá následovně:
Zobrazení na monitoru

Závěr

V projektu bylo objasněno, jakým způsobem je možné s pomocí mikrokontroleru vytvářet obraz zobrazitelný na VGA monitoru. Výsledkem je program, který umožňuje generování obrazu o rozlišení 20 řádků textu a 19 znaků na řádek. Tyto hodnoty jsou omezeny nízkou pracovní frekvencí mikrokontroleru, při vyšší pracovní frekvenci je možné dosáhnout většího počtu znaků na řádek. Data pro zobrazení jsou do mikrokontroleru zasílána přes sériové rozhraní, rychlost je 1200 b/s, 8 datových bitů, bez parity.
Tento projekt vychází z bakalářské práce Jana Poláška [1], kde celá problematika rozebrána podrobněji a jsou zde uvedeny odkazy na další informační zdroje.

Literatura

[1] POLÁŠEK, J. VGA zobrazovací zařízení s mikrokontrolerem: bakalářská práce. Brno: Vysoké učení technické v Brně, Fakulta elektrotechniky a komunikačních technologií, 2008. 34 s. Vedoucí bakalářské práce: Ing. Zbyněk Fedra, Ph.D.