|
Raspberry Pi
42) Ovládání grafických
displejů
4.část: Displej
128x64 bodů s řadičem ST7920 (označení 12864ZW)
Získal jsem další grafický displej ke zprovoznění.
Tentokrát se jedná o běžně dostupný displej s řadičem ST7920, který má
označení 12864ZW.
Nejsem si úplně jistý, ale pravděpodobně je to tento displej: http://www.ebay.com/itm/330809490475
Katalogový list je zde: http://www.digole.com/images/file/Digole_12864_LCD.pdf
Tento displej je možné řídit pomocí sériové i paralelní
komunikace. Při zprovozňování jsem si kvůli úspoře GPIO pinů v RasPi,
zvolil sériovou variantu komunikace.
Základní popis zobrazovacích režimů
Displej může pracovat ve dvou režimech -
textovém a grafickém.
Po přepnutí do textového režimu může displej zobrazovat
"evropské" znaky o velikosti 8x16 bodů, nebo "čínské"
znaky o velikosti 16x16 bodů. V tomto režimu je také možné si nadefinovat a
zobrazit 4 vlastní "ikony" o velikosti 16x16 bodů.
V textovém režimu se znaky zobrazují na displeji do stanovených pozic, takže
se na displej vejde maximálně 16 sloupců a 4 řádky pro "evropské"
nápisy, nebo 8 sloupců a 4 řádky pro "čínské" nápisy a vlastní
ikony. Není možné text zobrazovat mimo tento rastr.
V textovém režimu není možné tisknout znaky s českou diakritikou (háčky
/ čárky) - ve vnitřní ROM displeje nejsou nadefinovány.
"Evropské" znaky v rastru 16x4 |
Čínské znaky v rastru 8x4 |
Po přepnutí do grafického režimu je možné řídit kterýkoliv
bod na displeji.
Když si v nějakém souboru nadefinujete font (grafický vzhled jednotlivých písmen),
můžete i v grafickém režimu
zobrazovat textové nápisy. Nevýhoda tohoto režimu je však pomalá rychlost.
Při zobrazení textu v grafickém režimu je možné tisknou text do libovolného
místa.
V ukázkovém ovládacím programu jsem použil font 8x8 bodů a pro
jednoduchost jsem pozici X
ponechal v původním rastru, takže je možné po jednotlivých pixelech měnit
jen souřadnici Y.
Oba tyto režimy mohou být zapnuty současně. Takže je možné
například pomocí grafického režimu vytvořit rámeček a pomocí textového
režimu do něj napsat text.
Při použití obou režimů zároveň je třeba si dát pozor na to, že když
se překryje svítící bod v textovém režimu a svítící bod v grafickém režimu,
tak ten bod ve výsledku na displeji zhasne (je to funkce XOR). Není proto možné
napsat nějaký text v textovém režimu a pak ho grafickou čarou škrtnout.
Tady je příklad, jak by ten škrtnutý nápis vypadal blbě v porovnání s přeškrtnutým
nápisem
zobrazeným v grafickém režimu:
Zapojení vývodů podle katalogového listu:
Vývod |
Význam |
1 |
Vss - GND |
2 |
napájení 5V |
3 |
VO - pravděpodobně má sloužit k nastavení
kontrastu, ale pin je nezapojený |
4 |
RS - při sériové komunikaci slouží jako "ChipSelect"
- při "1" displej přijímá data |
5 |
R/W - při sériové komunikaci slouží jako datový
vstup (SID) |
6 |
E - při sériové komunikaci slouží jako hodinový
vstup (SCLK) |
7 |
D0 - paralelní data |
8 |
D1 - paralelní data |
9 |
D2 - paralelní data |
10 |
D3 - paralelní data |
11 |
D4 - paralelní data |
12 |
D5 - paralelní data |
13 |
D6 - paralelní data |
14 |
D7 - paralelní data |
15 |
PSB - přepínaní sériové nebo paralelní komunikace (při
sériové zapojit na GND) |
16 |
NC - nezapojeno |
17 |
RST - externí reset. Po krátkém přivedení
"0" se displej zresetuje. |
18 |
Vout - údajně by tam mělo být nějaké napětí pro
nastavení kontrastu, ale není tam nic |
19 |
Anoda podsvětu (odběr LED diod je asi 60mA při napájení
přímo z +5V) |
20 |
Katoda podsvětu - GND |
Schéma připojení:
GPIO vývody si můžete zvolit podle potřeby, ale v tom případě
je třeba změnit jejich nastavení v programu.
Software:
Základem řízení displeje je tento popis komunikace:
Tímto se do displeje pošle jeden bajt.
V některých případech je třeba odeslat dva bajty okamžitě
po sobě. Odesílal jsem je takto:
Ukázkový skript do pythonu: glcd12864zw.py
K tomu je třeba ještě font (stejný, jako v minulých článcích o řízení
grafických displejů): font2.txt
A ještě jeden ukázkový bitmapový obrázek: pokladnik.bmp
(obrázek je převzatý ze stránky: www.karikaturist.estranky.cz/
a zmenšený na 128x64 bodů)
Všechny 3 soubory si stáhněte do adresáře /home/pi/
a spusťte skript.
Tady je ukázka činnosti skriptu:
Všechny podprogramy jsou jako obvykle vysvětleny přímo v kódu,
tady je jen jejich krátký popis:
init() |
Základní nastavení GPIO portů - stačí ho spustit jen
1x na začátku programu |
init_text() |
Přepne displej do textového režimu (obsah displeje nemaže) |
init_grafika() |
Přepne displej do grafického režimu (obsah displeje nemaže) |
clr_text() |
Smaže obsah textové části displeje (grafická část zůstává
nezměněná) |
clr_grafika(pattern) |
Vyplní celý obsah grafické části displeje zadaným
bajtem. (Při 0x00 displej smaže, při 0xFF ho celý vyplní bílými body,
další hodnoty způsobí vyplnění displeje různými svislými čarami).
Textová část displeje zůstává nezměněná. |
disclear(pattern) |
Provede oba předchozí způsoby smazání zároveň. Po návratu
je displej přepnutý do textového režimu. |
defikon(ikona,ikodata) |
Nadefinuje jednu ze čtyř vlastních ikon
ikona = číslo ikony 0 až 3
ikodata = proměnná, která obsahuje pole: 16x dvoubajtová hodnota |
printiko(cislo , x , y) |
Na souřadnice [x,y] vytiskne jednu ze 4 vlastních ikon.
cislo = číslo ikony 0 až 3
x = sloupec 0 až 7
y= řádka 0 až 3 |
grafický font
8x8 bodů |
znak(kod , x , supery , inverze) |
Zobrazí jeden znak s ASCII kódem "kod" na souřadnice
"x" (0 až 15),
"supery" (0 až 63) - horní strana znaku je na mikrořádce
"supery".
Při "inverze" = True se zobrazí tmavý znak na světlém
pozadí. |
slovo(text , x , supery, inverze) |
Zobrazí text (více znaků) na souřadnicích "x"
a "supery" (parametry stejné jako ve funkci "znak()"). |
Vnitřní font displeje |
velky_znak(kod , x , y) |
Zobrazí jeden znak v textovém režimu na souřadnicích
[x,y].
kod je v rozsahu 1 až 127 (od 32 do 126 je to klasické ASCII)
X je od 0 do 15
Y je řádka 0 až 3 |
velky_napis(text , x , y) |
Pomocí velkých znaků zobrazí na displeji text. Parametry
jsou stejné, jako u funkce "velky_znak()" a platí pro první
znak z textu. |
plot(superx, supery, styl) |
Na souřadnicích "superx" (0 až 127) a "supery"
(0 až 63) zobrazí, smaže, nebo invertuje jeden bod. Jestliže styl=
0, provádí se mazání bodu, při styl=1 se bod zobrazí a při
styl=2 se provádí změna stavu bodu na displeji. |
mem_plot(superx, supery, styl) |
Stejná funkce jako předchozí "plot()", akorát
se body nezobrazují přímo na displeji, ale pouze v dočasném paměťovém
prostoru. Pomocí této funkce je možné rychlejší kreslení. Po použití
je ale nutné přenést obsah té dočasné paměti na displej pomocí
funkce "mem_dump()". |
mem_dump() |
Přenesení obsahu paměti na displej po použití příkazu
mem_plot(). |
h_cara(supery, od , do, styl) |
Vykreslení jednoduché horizontální čáry ve vzdálenosti
"supery" od horního okraje s možností definování začátku
a konce čáry (proměnné "od" a "do"). Parametr
"styl" je stejný jako ve funkci "plot()". |
h_cara2(supery , od , do , pattern ) |
Rychlejší varianta kreslení horizontální čáry.V tomto
případě jsou ale parametry "od" a "do" v rozsahu 0 až 7 (jsou to šestnáctiny pixelů na displeji). Čára
tedy může začínat a končit jen na souřadnicích, na které se
tisknou ikony. Minimální délka takovéto čáry je 16 bodů.
Parametr "pattern" udává styl čáry. Podle jednotlivých
bitů toho parametru se dá nastavit čára plná, čárkovaná, tečkovaná,
čerchovaná... |
v_cara(superx, od, do, pattern) |
Vertikální čára na libovolných souřadnicích.
superx = X souřadnice čáry v rozsahu 0 až 127
od, do = y souřadnice začátku a konce čáry v rozsahu 0 až 63
Parametr "pattern" je stejný jako v předchozím případě. |
load_bmp12864(jmeno_obrazku) |
Načtení dvoubarevného obrázku ze souboru do displeje.
Pozor na správný formát souboru! |
posli_bajt1( rs, bajt) |
Odešle do displeje 1 bajt.
pomocí parametru "rs" se vybírá datový (1), nebo příkazový
(0) registr. |
posli_bajt2( rs, bajt1, bajt2) |
Odešle do displeje 2 bajty najednou .
pomocí parametru "rs" se vybírá datový (1), nebo příkazový
(0) registr. |
|
|
|