Zobrazení znaku na oled displeji s SSD1306 čipem

Ahoj, mám doma oled displej s rozlišením 128x64 a zkouším s ním nějak pracovat. Je dělaný na I2C sběrnici. Nějak jsem spachtlil nějaký krátký program, který by mohl něco dělat, ale očividně nedělá :slight_smile: Když jsem ten displej zapojil poprvé, jenom na napájení. byl čistý, nic na něm nebylo zobrazené a tím, že je oled, tak ani nesvítí. Tak jsem si říkal, že na něho pošlu třeba písmeno “a”. Zjistil jsem si adresu registru a jestli je write bit 0 nebo 1 a poslal to. Ještě předtím jsem samozřejmě pustil sběrnici. Mám k procesoru připojené ještě dvě ledky, které mi ukazujou, jestli má statický registr hodnotu jakou má mít, jakože jestli to proběhlo v pořádku nebo spíš, jestli ten displej obdržel informaci a vrátil ACK. Podle toté podmínky to proběhlo, ale je tam asi nějaká jinačí chyba a já nevím jaká. Pošlu sem screen toho programu a obrázek, jak ten displej komunikuje. Jsem totiž zmatený z toho řídicího bitu, jak to funguje. Je tam bit Co a D/C# a já nějak nedokážu pochopit, jak to funguje nebo proč jsou tam dva. Má s tím někdo tady zkušenosti? A navíc nevím, jestli to písmeno posílám dobře.

sdhbecva.cz/images/Pozn%C3%A1mka1.png
sdhbecva.cz/images/Pozn%C3%A1mka2.png

  1. Chybí Ti tam inicializace displeje.
  2. Je to grafický displej, na který nemůžeš napsat ‘a’ tak, že pošleš znak ‘a’ do displeje. Ten znak na displej musíš byte po bytu vykreslit. To znamená, že v paměti procesoru musíš mít znakovou sadu a musíš si napsat rutinu, které pošleš to ‘a’ a ta rutina si v datech najde, kde je to ‘a’ uložené a příslušný počet bytů pošle na displej. Samozřejmostí by mělo být i to, že pošleš souřadnice, kam to ‘a’ chceš vykreslit a na základě toho si rutina spočítá, na jakou adresu v paměti displeje začne to ‘a’ vykreslovat.

Najjednoduchšie sa to spraví tak, že si v MCU vyhradiš 1kB na tzv. maliarske platno. Tam si nakresliš čo len chceš. Ako písal Balú, aj písmenká. Sú to v podstate iba obrázky s nejakou veľkosťou v smere X a v smere Y.
Určite si rýchlo spravíš rutiny na vykreslenie kruhu, obdĺžnika, písmenok a iných ikoniek na toto plátno.
A tak ako ich pudeš postupne vykreslovať na to 1kB plátno (128*64/8 = 1kB) môžeš si tam ešte doplniť rutinky, že keď vkladáš nejaký útvar, či sa má s pôvodným podkladom OR-ovať, XOR-ovať a tak podobne.
No a keď to všetko máš, spustíš rutinu, ktorá ten celý 1kB pošle do displeja.

Obrovská výhoda tohto prístupu je, že pri použití iného displeja použiješ iba inú rutinu na zápis do iného LDC/OLED displeja. Alebo kľudne aj rutinu, ktorá bude dáta z maliarskeho plátna pravidelne posielať na VGA výstup napríklad pre zobrazenie 256x256pixlov v 16color zobrazení. Jasné, že plátno musí byť “trochu” väčšie, ale systémom použitým v ZX Spectre zas nie až o moc (256x256/8 na pixle a 32x32 na farebnu paletu = 9216B).

S ATmegou na 18MHz som musel dokonca prekreslovanie do LCD 128x64 brzdiť, lebo už dochádzalo k interferenciám medzi obnovovacou frekvenciou displeja a posielaním údajov doň. Tak som zistil, že rýchlejšie ako 3x za sekundu nemá ani zmysel meniť na bežnom LCD displeji (EADOG128x64).
komunikoval som cez SPI rozhranie, ktoré som simuloval softwarovo. Popri tom samozrejme bežalo nejaké riadenie, nejaká komunikácia cez RS linku, zber údajov, atď atď

Pre zobrazovanie na VGA výstupe sa na nejakú tú prácu dal využiť iba čas cez vertikálny zatemňovací impulz. No na konci každého behu v čase horizontálnej synchronizácie som stihol prijať/odvysielať bajt cez nejaké hw rozhranie. Použil som ATmegu 1284 na (20MHz) kvôli väčšej pamäti a jeden z UARTOV v móde SPI na generovanie VGA signálu na prepínač (74HCT157) farba pozadia/farba popredia.

Uvádzam to len ako námet na spôsob práce s softvérom ako niečím modulárnym. Aj pri obládaní LCD i VGA mám použitý rovnaký sw na vykresľovanie pixlov na vnútorné plátno.