PICAXE a grafický LCD displej

PICAXE bez problémů zvládne i řízení grafického LCD displeje, jako příklad použijeme spolupráci PICAXE 20X2 a grafického displeje SIG12864C1 s dvěma řadiči Avant SBN0064G. Displej s 128×64 body je plně grafický. Je rozdělen na dvě poloviny 64×64 bodů, každá z nich má svůj vlastní řadič.

Všechny vývody mimo selektů CSA a CSB volby řadiče jsou spojeny paralelně, CSA v úrovni L aktivuje levou polovinu, CSB pravou. Lze pracovat i s oběma polovinami současně, což některé činnosti, jako například mazání, významně zkrátí.

Displej komunikuje po osmibitové paralelní sběrnici. Volba mezi zápisem a čtením se provádí pomocí vývodu RW a volba mezi instrukcí a daty pomocí vývodu RS. Pokud není nutné číst obsah nebo stav (stavový registr) displeje, lze vývod RW trvale nastavit na zápis. K zápisu (čtení) se používá vývod EN a sestupná hrana pulzu na něm, data však musí být přítomna v době celého pulzu EN (!). Při ovládání z PICAXE není časování kritické, protože mikrokontrolér je dostatečně pomalý (což platí i pro řadu X2 s nastavenými hodinami 64 MHz), při připojení k rychlejšímu ovládání je vhodné sledovat stavový byte a další operaci spustit, až když je displej s předchozí hotov.

LCD_graf1Sloupce se číslují zleva od 0 do 63 v každé polovině, řádky (banky) shora dolů od 0 do 7. Byte dat se zobrazí tak, že nejméně významný bit je nahoře, nejvíce významný dole. Displej umí parametrem „přemapovat“ přiřazení grafické paměti a zobrazení po jednotlivých bitech (řádcích bodů). Toho lze využít například k snadnému a rychlému „rolování“ obsahu displeje ve svislém směru.

Obsluha tohoto grafického displeje je až nečekaně jednoduchá, není potřeba žádná inicializace, nejsou tu úskalí třeba toho typu, že dvouřádkový displej se musí inicializovat jako čtyřřádkový. Protože jsou však k dispozici opravdu jen základní příkazy, je obsluha současně pracná, o vše se musí postarat mikrokontrolér. Displej neobsahuje ROM (EEPROM) pro znaky, jakékoli znaky musí být zobrazeny stejně jako ostatní grafika. K dispozici je:

  • zapnutí/vypnutí práce s diplejem (registr 1 bit)
  • přemapování prvního řádku displeje (registr 6 bit)
  • nastavení pozice kurzoru do daného sloupce (při zápisu/čtení se zvýší o 1)
  • nastavení pozice kurzoru do daného řádku (banku)
  • čtení status registru
  • zápis/čtení osmibitových dat do grafické paměti

První příklad dělá jen to, že střídavě maže a zaplňuje celý displej. To důležité v něm jsou podprogramy pro zapnutí, vypnutí, přemapování začátku, nastavení sloupce a řádku, vyplnění displeje daným bytem a vykreslení bodu na daných souřadnicích. Tyto podprogramy stejně jako počáteční přiřazení symbolů už v dalších příkladech nebudou kvůli zkrácení opakovány.

REM grafický SIG12864C1 - PICAXE 20X2
 symbol RS=C.0                          ;H data, L příkazy
 symbol EN=C.1                          ;H platná
 symbol CSA=C.2                         ;levá polovina displeje (L akt.)
 symbol CSB=C.3                         ;pravá polovina displeje (L akt.)
 symbol RW=C.4                          ;čtení/zápis (L zápis)
 let dirsB=%11111111                    ;port B připravit pro data
 low EN                                 ;počáteční stav EN
 pause 200                              ;čas na náběh displeje
 setfreq m64                            ;maximální rychlost 64 MHz
 gosub zapni                            ;zapnutí displeje
 do                                     ;smyčka programu
  b3=0                                  ;všechny body zhasnout (bílé)
  gosub vypln                           ;provést příkaz
  pause 16000                           ;počkat 1 s
  b3=255                                ;všechny body rozsvítit (černé)
  gosub vypln                           ;provést příkaz
  pause 16000                           ;počkat 1 s
  loop                                  ;konec smycky
zapni:                                  ;zapne zobrazení displeje
 low RS low RW                          ;bude povel, zápis
 pinsB=$3F                              ;příkaz zapnutí
 pulsout EN,1                           ;zapsat příkaz
 return
vypni:                                  ;vypne zobrazení displeje
  low RS low RW                         ;bude povel, zápis
  pinsB=$3E                             ;příkaz vypnutí
  pulsout EN,1                          ;zapsat příkaz
  return
pocatek:                                ;dle b0 nastaví adresu horní linky 0-63
  low RS low RW                         ;bude povel, zápis
  b0=b0 or %11000000                    ;maska počáteční adresy
  pinsB=b0                              ;nastavení adresy
  pulsout EN,1                          ;zapsat příkaz
  return
radek:                                  ;dle b0 nastaví kurzor na řádek 0-7
  low RS low RW                         ;bude povel, zápis
  b0=b0 or %10111000                    ;maska povelu
  pinsB=b0                              ;nastavení řádku (banky)
  pulsout EN,1                          ;zapsat příkaz
  return
sloupec:                                ;dle b0 nastaví kurzor na sloupec 0-63
  low RS low RW                         ;bude povel, zápis
  b0=b0 or %01000000                    ;maska povelu
  pinsB=b0                              ;nastavení sloupce
  pulsout EN,1                          ;zapsat příkaz
  return
vypln:                                  ;dle b3 vyplní displej (b1,b2 pracovní)
  low CSA low CSB                       ;současně do obou polovin!
  b0=0 gosub pocatek                    ;žádné přemapování
  for b1=0 to 7                         ;pro všechny řádky
  b0=b1 gosub radek                     ;nastav řádek
  b0=0 gosub sloupec                    ;začátek sloupce
  high RS                               ;budou data, ne povely
  pinsB=b3                              ;data na port B
  for b2=0 to 63                        ;do všech sloupců
  pulsout EN,1                          ;zapiš data
  next b2
  next b1
  high CSA high CSB                     ;vypnout selekty
  return
bod:                                    ;b4=x,b5=y - vykresli bod (b6,b7,b8 pracovní)
  if b4<64 then                         ;bod v levé/pravé polovině
  low CSA b0=b4 else
  low CSB b0=b4-64 endif
  b8=b0                                 ;odložit souřadnici na později
  gosub sloupec                         ;v dané polovině nastavit sloupec
  b0=b5/8                               ;který řádek (celistvý byte)
  gosub radek                           ;nastav řádek
  b0=b5//8                              ;který bit
  select b0                             ;výběr bitu dle zbytku po dělení
  case 0 b6= 1
  case 1 b6= 2
  case 2 b6= 4
  case 3 b6= 8
  case 4 b6= 16
  case 5 b6= 32
  case 6 b6= 64
  case 7 b6=128
  endselect
  high RW high RS                       ;bude čtení dat z displeje
  let dirsB=%00000000                   ;port otočit na vstup
  pulsout EN,1                          ;první čtení z displeje (chybné)
  pulsout EN,1                          ;druhé čtení
  let b7=pinsB                          ;zapsat do proměnné
  let dirsB=%11111111                   ;vrátit port na výstup
  b7=b7 or b6                           ;přidat nový obsah do byte
  b0=b8                                 ;nastavit původní souřadnici sloupce
  gosub sloupec                         ;nastavit kurzor na sloupec
  high RS low RW                        ;bude zápis dat
  let pinsB=b7                          ;nastavit data
  pulsout EN,1                          ;zapsat data
  high CSA high CSB                     ;odstranit selekty
  return

Druhý příklad vykreslí kolem celého grafického pole rámeček a pak jej v nekonečné smyčce postupně zcela vyplní náhodně generovanými body. Důležité je všimnout si, že v podprogramu pro zakreslení bodu nelze pracovat s jednotlivými pixely displeje, nejprve se musí načíst z dané pozice stávající obsah (a to dvakrát, protože první čtení vezme poslední stav uložený v paměti na vstupu, teprve druhé dostane požadovaný obsah), pak do tohoto bytu funkcí OR přidat nový bod a celý byt opět uložit. Nové tělo programu vypadá takto:

setfreq m64                               ;maximální rychlost
gosub zapni                               ;zapnout displej
b3=0 gosub vypln                          ;smazat displej
for b4=0 to 127                           ;vodorovné čáry rámečku
 b5=0 gosub bod b5=63 gosub bod next b4
for b5=0 to 63                            ;svislé cáry rámečku
 b4=0 gosub bod b4=127 gosub bod next b5
do                                        ;nekonečná smyčka programu
 random w7                                ;generuj náhodné číslo
 b4=b14/2 b5=b15/4                        ;náhodné souřadnice x,y
 gosub bod                                ;zapiš bod
loop                                      ;konec smyčky

IMGP9473b


Třetí příklad na malém vzorku ukazuje práci s textem respektive číslicemi. Vypíše do obou polovin displeje krátký nápis „128X64“ (do paměti ukládá tento příklad jen znaky, které budou použity) a pak nechá levou polovinu displeje rolovat nahoru a současně pravou dolů. Uvedeno je pouze tělo programu a jeden nový podprogram.

data 5, (%00000000,%01000010,%01111111,%01000000,%00000000);1
data 10,(%01100010,%01010001,%01001001,%01000101,%01000010);2
data 20,(%00110000,%00101000,%00100100,%01110010,%00100001);4
data 30,(%00111100,%01001010,%01001001,%01001001,%00110000);6
data 40,(%00110110,%01001001,%01001001,%01001001,%00110110);8
data 200,(%01100011,%00010100,%00001000,%00010100,%01100011);X
gosub zapni                       ;zapnout displej
b3=0 gosub vypln                  ;smazat displej
low CSA low CSB                   ;obě poloviny současně
b0=15 gosub sloupec               ;nastavit sloupec
b0=4 gosub radek                  ;nastavit řádek
b0="1" gosub znak                 ;výpis znaků z tabulky v EEPROM
b0="2" gosub znak
b0="8" gosub znak
b0="X" gosub znak
b0="6" gosub znak
b0="4" gosub znak
pause 3000                        ;počkat před rolováním
do                                ;nekonečná smyčka
 for b10=0 to 63                  ;jeden cyklus rolování
 pause 40                         ;zpomalení
 low CSA high CSB                 ;levá polovina
 b0=b10 gosub pocatek             ;posunutí nahoru
 high CSA low CSB                 ;pravá polovina
 b0=62-b10 gosub pocatek          ;posunutí dolů
 next b10
 pause 3000                       ;zastavit
 loop                             ;opakovat
znak:                             ;vypíše znak z b0 ($48-$90), b1,b2 pracovní
 b0=b0-48*5                       ;adresa znaku v EEPROM
 high RS low RW                   ;zápis dat do videopaměti
 for b1=1 to 5                    ;5 bytu znaku
 read b0,b2                       ;načíst byt z EEPROM
 let pinsB=b2                     ;dát na výstup
 pulsout EN,1                     ;zapsat do displeje
 inc b0                           ;další byt
 next b1
 let pinsB=0                      ;0 na výstup (mezera - 6. byt)
 pulsout EN,1                     ;zapsat do displeje
return

Poslední příklad poukazuje mino jiné na problém spolupráce PICAXE a plně grafického displeje, který nemá implementovanou znakovou sadu. Vytvořit jednoduchou grafiku může být celkem snadné, ale kompletní znaková sada se do paměti PICAXE těžko vejde, takže buď je nutné omezit se jen na některé znaky jako v předchozím případě (v rastru 5×7 se jich do 256 bytů EEPROM vejde 51 bez mezer), nebo připojit k mikrokontroléru externí paměť. Samozřejmě je také možné uložit do EEPROM celé nápisy jako obrázky a následně je přenést na displej.

IMGP9475bJe-li to třeba, musí být součástí programu i vykreslení jednoduchých obrazců, čar, obdélníků, kružnic, vyplnění plochy a podobně. To vše je pracné, náročné na programovou paměť, a v neposlední řadě i za chodu programu pomalé. Další problém představuje značný počet pinů mikrokontroléru, které ovládání grafického displeje vyžaduje.


Většinu potíží a omezení ve využití grafického displeje spolu s PICAXE může vyřešit grafický interpretr GLIC-K1, který je navržen pro spolupráci s černobílými displeji 128×64 bodů s řadičem KS0108, ale to není případ našeho konkrétního displeje.

Obvod se s PICAXE propojí jen třemi vodiči a komunikuje sériově rychlostí 2400 Bd. S ohledem na to, že se přenáší jen jednobytové povely a jejich parametry to naprosto stačí. Naopak, vzhledem k tomu, že vykonání některých příkazů může být časově náročné, během zadávání příkazů je třeba hlídat i jejich dokončení pomocí signálu RDY. K obvodu může být (většinou bude) připojena i externí EEPROM 24LC512.

kopr2