AVR. Výcvikový kurz

Znakové LCD se dnes stále častěji používají k zobrazování jednoduchých informací o znacích. Budeme mluvit o tom, jak s nimi pracovat. V této části článku se blíže podíváme na znakové LCD založené na řadiči HITACHI HD44780 (nebo s ním kompatibilním SAMSUNG KS0066). Článek je pokusem o systematizaci informací, které jsem našel při práci s těmito LCD.

Znakový LCD s řadičem HD44780 (KS0066). Rozhraní

Znakový LCD není nic jiného než matice bodů rozdělená na řádky a pole znaků:

K ovládání této matice a zobrazení skutečných znaků se používá speciální řadič.

HD44780 (a kompatibilní s ním KS0066) - je de facto standardem pro černobílé řadiče LCD s paralelním 4bitovým nebo 8bitovým rozhraním. Na základě tohoto řadiče se vyrábí obrovské množství modelů s různým designem a rozlišením, počínaje 8x1 (osm znaků v jednom řádku) a končící 40x4 (obsahující dva nezávislé řídicí čipy). Typická frekvence ovladače je 270 kHz.

Řadič LCD ovládá 3 paměťové bloky:

1. Řadič používá paměť k zobrazení znaku DDRAM (Display Data RAM), kde jsou uloženy ASCII kódy znaků, které chceme vidět na LCD. Je pro ni přiděleno 80 paměťových buněk. Je jasné, že na LCD uvidíme pouze část znaků, které jsou v DDRAM - pokud je náš LCD 1 nebo 2řádkový a zobrazuje 8 znaků na řádek, pak takto:

Jak vidíte, pracovní oblast displeje lze posunout napříč buňkami DDRAM (získá se efekt plíživé čáry).

2. Řídicí jednotka přebírá šablony samotných symbolů CGROM (Character Generator ROM) - paměť generátoru znaků. Tabulka symbolů je uvedena v datovém listu na HD44780.

3. Je k dispozici paměť pro ukládání uživatelských symbolů (jejich šablon) CGRAM (RAM generátoru znaků).

Řadič také v závislosti na určitých podmínkách distribuuje přijatá data do něj registr instrukcí nebo datový registr.

Typické 14kolíkové rozhraní řadiče HD44780:

Uzemnění, společný vodič, GND

Napájecí napětí, Vcc (+ 5 V)

Nastavení kontrastu (Vo)

Výběr registru (R / S pro HD44780, A0 pro KS0066)

Čtení / zápis (R / W)

Falloff Gate E (Povolit)

Bit 0 (nejméně významný pro 8bitové rozhraní)

Datová linka

DB 4 (junior pro 4bitové rozhraní)

DB 7 (starší pro 8 (4) bitové rozhraní)

Pro podsvícený displej

Napájení podsvícení pro podsvícené displeje (anoda)

Napájení podsvícení pro podsvícené displeje (katoda)

Číslování pinů na konkrétním LCD najdete v datovém listu.

Kontrast obrazu na LCD lze změnit připojením dalšího trimovacího rezistoru 10 kOhm následujícím způsobem:

Měli byste se však podívat na specifikaci vašeho řadiče (například LCD Klsn10294v-0 na čipu KS0066 má 1-Vcc a 2-GND). Napájení podsvícení se může u jednotlivých modelů lišit v závislosti na jeho typu. Podsvícení je obvykle napájeno z 5 voltů, rezistor omezující proud (50-100 ohmů) obvykle není nutný.

Přiřazení pinů R / S, R / W, E:

Když přesunete E z vysokého protokolu. úroveň na nízké údaje, které již „visí“ na závěrech DB0..DB7 se zapisují do paměti řadiče LCD pro další zpracování.

S vysokým logem. na úrovni R / S (Register Select), řadič LCD vnímá tuto sadu bitů jako data (znakový kód) a na nízké úrovni - jako instrukci a odešle je do příslušného registru.

R / W určuje směr provozu pinů DB0..DB7 - je-li R / W „0“, můžeme pouze zapisovat na port DB, a pokud R / W \u003d „1“, můžeme z něj číst (například zjistit, že je ovladač zaneprázdněn nebo zdarma pro příjem nových dat). Pokud nebudeme číst data z LCD, můžeme „dát“ R / W na zem.

Sada instrukcí HD44780

Aby bylo možné začít zobrazovat informace na LCD, musí být inicializován jeho řadič (informujte jej o rozhraní, písmu, offsetech atd.). Řídicí jednotka může přijmout pouze 11 příkazů:

Ruční název

Stav připnutí

Čas dokončení

f práce. \u003d 270 kHz

Vymazat celkový LCD Nastavit adresu DDRAM na 0

Nastavení aktuální adresy DDRAM na 0 (kurzor - domov) Data DDRAM se nezmění

Nastavení směru pohybu kurzoru (I / D) a posunutí displeje (S) při výstupu dat

Ovládání zapnutí / vypnutí displeje

Zapnuto vypnuto. displej (D), kurzor (C) a blikající (B)

Posun kurzoru nebo displeje

Přesouvá kurzor a posouvá zobrazení podle DDRAM

Nastavení rozhraní (DL), počet řádků (N) a písmo znaků (F)

Nastavte adresu CGRAM

Nastavení počitadla adresy CGRAM. Poté můžete zapisovat data do CGRAM

Nastavte adresu DDRAM

Nastavení čítače adres DDRAM

Přečtěte si zaneprázdněný příznak a adresu

Je-li BF \u003d 1, provádí řadič LCD interní operaci (zaneprázdněn). AC6-AC0 - aktuální hodnota adresy DDRAM

Zápis dat do paměti RAM

Zápis dat do paměti RAM

Čtení dat z paměti RAM

Čtení dat z RAM

I / D \u003d 1: adresa DDRAM se zvyšuje I / D \u003d 0: klesá
S \u003d 1: Posunutí pracovní oblasti displeje o DDRAM je povoleno
D \u003d 1: zobrazení (obrázek) zapnuto
C \u003d 1: kurzor je zapnutý
B \u003d 1: kurzor bliká

S / C \u003d 1: pohyb displeje S / C \u003d 0: pohyb kurzoru
R / L \u003d 1: vpravo R / L \u003d 0: vlevo

DL \u003d 1: 8 bit DL \u003d 0: 4 bity
N \u003d řádky 1: 2 N \u003d řádky 0: 1
F \u003d 1: 5x10 F \u003d 0: 5x8

ACG: adresa CGRAM
PŘIDAT: DDRAM adresa
AC: adresy čítačů adres DD a CGRAM

Inicializace LCD

Existují 2 způsoby, jak inicializovat řadič LCD:

1. Interním resetovacím obvodem.

2. V manuálním režimu (zasláním několika příkazů, kterými jsme nastavili provozní režim LCD)

Interní resetovací obvod řídicí jednotky začne fungovat, jakmile se zapne napájení. To má jednu nevýhodu - pokud se zdroj energie „plíží“ na provozní úroveň pomalu (pomaleji než za 10 ms), nemusí být automatická inicializace ovladače správná. S touto inicializační metodou samotný řadič provede následující příkazy:

1. Displej jasný

2. Sada funkcí:
DL \u003d 1; 8bitová data rozhraní
N \u003d 0; 1řádkový displej
F \u003d 0; Písmo znaků 5x8 bodů

3. Ovládání zapnutí / vypnutí displeje:
D \u003d 0; Vypnutý displej
C \u003d 0; Kurzor vypnutý
B \u003d 0; Bliká

4. Nastaven režim vstupu:
I / D \u003d 1; Přírůstek o 1
S \u003d 0; Žádná směna

Druhá metoda vylučuje závislost obvodu na napájecím zdroji. Chcete-li inicializovat řadič LCD v ručním režimu, je třeba provést následující algoritmus:

Jak vidíte, zde není nic komplikovaného: na LCD pošleme příkaz za příkazem, přičemž vezmeme v úvahu čas jejich provedení (asi 40 μs) nebo zkontrolujeme zaneprázdněný příznak LCD ovladače (pak musíme dát RW pin na patici mikrokontroléru a nastavit jej na „1“, když to chceme vědět zda je LCD zaneprázdněn nebo ne).

To je ve skutečnosti vše, co souvisí s teorií práce se znakovým LCD. Pokud vám něco uniklo nebo jste udělali chybu, přečtěte si specifikaci ovladače nebo.

V druhé části se budeme zabývat hardwarovou a softwarovou implementací komunikace mezi mikrokontrolérem PIC a LCD.

Zvažme interakci uživatele a zařízení založenou na mikrokontroléru. Uživatel často potřebuje do něčeho zadat informace a z něčeho je přečíst. Klávesnice a displej () jsou pro tyto účely velmi vhodné. Zvažte interakci mezi uživatelem a zařízením založenou na mikrokontroléru. Uživatel často potřebuje do něčeho zadat informace a z něčeho je přečíst. Klávesnice a displej () jsou pro tyto účely velmi vhodné. V této poznámce budeme podrobněji uvažovat o zobrazení informací na symbolickém LCD se syntézou znaků.

Takové indikátory se často používají v designu digitální zařízení, takže s tím musíte být schopni pracovat.
Zvažte typickou vnitřní strukturu syntetizujícího znaménka LCD:

Vnitřní struktura HD44780

Displej LCD je založen na matici tekutých krystalů, která přivádí napětí na prvek, jehož pomocí můžeme „rozsvítit“ bod na obrazovce. V našem případě se matice skládá z prostorů známosti (nejčastěji 8x5 pixelů), seskupených do několika řádků. To vše ovládá vestavěný Řadič HD44780... Řadič má jednobajtové paměťové buňky ( DDRAM), jejichž obsah se na obrazovce skutečně zobrazuje podle tabulky napsané v CGRAM... Paměťových buněk je obvykle více než známých LCD, takže se musíte podívat na řešení známosti v datovém listu. To znamená, že stačí napsat kód požadovaného znaku na správnou pozici a všechno ostatní HD44780 udělá to sám.

Pro výběr pozice je k dispozici virtuální kurzor (číslo aktuální paměťové buňky, AC), který lze ovládat pomocí příkazů, kurzor lze zviditelnit. Ve výchozím nastavení se při psaní znaku do buňky kurzor posune o jednu pozici dopředu. Kódy znaků pro LCD podpora cyrilice je vidět v tabulce:

Nejvyšší kódová tetrada se bude rovnat řádku vybraného znaku a nejnižší - řádku. Můžete si vytvořit vlastní tabulku symbolů tak, že ji napíšete CGRAM... Každý znak vyžaduje 5 bajtů, kde jsou jednotky odpovědné za „osvětlené“ pixely. Například číslice "8" je kódována sekvencí 0x6c, 0x92.0x92.0x92.0x6c.
Kódy příkazů jsou uvedeny v tabulce.

Tabulka symbolů HD44780


Hodnoty příznaku:


Otázkou zůstává: „jak napsat kód požadovaného znaku na požadované místo“? Za tímto účelem zvažte, za co jsou závěry odpovědné. LCD... závěry DB0-DB7 jsou zodpovědní za příchozí / odchozí data. Vysoká úroveň na pinu RS dává indikátor pochopit, že signál na svorkách DB0-DB7 jsou data a low je příkaz. Výstup W / R je zodpovědný za směr dat, ať už jsou data zapisována do paměti nebo z ní čtena (obvykle čtení z LCD nepoužívá, můžeme o něj bezpečně požádat nízká úroveň). Výstupní puls E (alespoň 500 ns trvání) se používá jako signál pro zápis / čtení dat z kolíků DB0-DB7, RS a W / R.

Výstup V0 slouží k nastavení kontrastu obrazu, výstup A, K - k napájení podsvícení (pokud je ve vašem modelu LCD). Zbývající 2 výstupy jsou skutečné napájení LCD... To znamená ovládat LCD potřebujete 8 + 1 + 1 \u003d 10 pinů. Můžete ale pracovat v režimu 4bitového rozhraní. Současně bude horní příkazová / datová tetrada přenášena nejprve na piny DB4-DB7 a poté na dolní. Závěry na DB0-DB3 nejsou používány. Celkem je pro ovládání zapotřebí 6 pinů mikrokontroléru.
Nyní se podívejme na živý příklad. Napíšeme program na výstup textu "webová stránka" na ten, který mám na skladě WH1602А (2 řádky po 16 znacích).

U ostatních LCD zkontrolujte korespondenci buněk DDRAM obeznámenost. Schéma připojení LCD k ovladači vypadá takto.

Schéma zapojení mikrokontroléru AVR


Rezistor R3 - 17 Ohm omezuje proud přes podsvícení a AC VR1 nastavuje kontrast (pokud je vše správně připojeno a naprogramováno, ale indikátor je tichý, otočením VR1 zviditelněte obraz). V žádném případě by neměla být zaměňována polarita. LCD, napájejte jej nad 5,5 V, z mých zkušeností mohu říci, že hoří okamžitě. Účel všech ostatních částí je stejný jako v
Nyní přejdeme k psaní programu. Pro ovládání indikátoru napíšeme program s několika klíčové funkce pracovat s LCD: lcd_dat (nepodepsaný znak x) - pro zápis dat х, lcd_com (nepodepsaný znak x) - pro zápis příkazu х, lcd_init (void) - pro počáteční inicializaci indikátoru:

    #zahrnout // I / O knihovna

  1. #define RS 2 // RS \u003d PD2 - ovládací signál LCD

    #define E 3 // E \u003d PD3 - ovládací signál LCD

  2. #define TIME 10 // Konstanta časového zpoždění pro LCD

    // Taktovací frekvence MK - 4MHz

  3. // Program pro vytvoření zpoždění

    void pause (unsigned int a)

    (nepodepsané int i;

  4. pro (i \u003d a; i\u003e 0; i-);

  5. // Program pro přenos příkazů na LCD

    void lcd_com (nepodepsaný char lcd)

    (unsigned char temp;

  6. temp \u003d (lcd & ~ (1<< RS) ) | (1 << E) ; // RS \u003d 0 je příkaz

    PORTD \u003d teplota; // Výstup na portD horní příkaz tetrad, signály RS, E

    asm ("nop");

    PORTD \u003d teplota & (1<< E) ; // Příkaz Signál k zápisu

  7. temp \u003d ((lcd * 16) & ~ (1<< RS) ) | (1 << E) ; // RS \u003d 0 je příkaz

    PORTD \u003d teplota; // Výstup na portD nejmenší příkaz tetrad, signály RS, E

    asm ("nop"); // Malé zpoždění 1 cyklu MK, ke stabilizaci

    PORTD \u003d teplota & (1<< E) ; // Příkaz Signál k zápisu

  8. pauza (10 * TIME); // Pauza pro provedení příkazu

  9. // Program pro zápis dat na LCD

    void lcd_dat (nepodepsaný char lcd)

    (unsigned char temp;

  10. teplota \u003d (lcd | (1<< RS) ) | (1 << E) ; // RS \u003d 1 jsou data

    PORTD \u003d teplota; // Výstup na portD horní datové signály tetrad, RS, E.

    asm ("nop"); // Malé zpoždění 1 cyklu MK, ke stabilizaci

    PORTD \u003d teplota & (1<< E) ; // Signál pro zápis dat

  11. teplota \u003d ((lcd * 16) | (1<< RS) ) | (1 << E) ; // RS \u003d 1 jsou data

    PORTD \u003d teplota; // Výstup na portD nejméně datová tetrada, signály RS, E

    asm ("nop"); // Malé zpoždění 1 cyklu MK, ke stabilizaci

    PORTD \u003d teplota & (1<< E) ; // Signál pro zápis dat

  12. pauza (TIME); // Pauza pro výstup dat

  13. // LCD inicializační program

    void lcd_init (void)

    lcd_com (0x2c); // 4vodičové rozhraní, velikost znaků 5x8

    pauza (100 * TIME);

    pauza (100 * TIME);

    pauza (100 * TIME);

  14. // Hlavní program

    int main (neplatný)

    DDRD \u003d 0xfc; // Inicializovat portD

    PORTD \u003d 0x00;

  15. pauza (1000);

    lcd_init (); // Inicializace LCD

  16. lcd_dat ("w"); // Výstup „www.site“

    lcd_dat ("w");

    lcd_dat ("w");

    lcd_dat (".");

    lcd_dat ("a");

    lcd_dat ("v");

    lcd_dat ("r");

    lcd_dat ("l");

    lcd_dat ("a");

    lcd_dat ("b");

    lcd_dat (".");

    lcd_dat ("c");

    lcd_dat ("o");

    lcd_dat ("m");

  17. lcd_dat ("I"); // Napište „Je to tak snadné“

    lcd_dat ("t");

    lcd_dat ("" ");

    lcd_dat ("s");

    lcd_dat ("");

    lcd_dat ("s");

    lcd_dat ("o");

    lcd_dat ("");

    lcd_dat ("e");

    lcd_dat ("a");

    lcd_dat ("s");

    lcd_dat ("y");

  18. zatímco (1) // nekonečný cyklus

  19. návrat 1;

Program je velmi jednoduchý, nebude těžké ho pochopit pro každého, kdo alespoň trochu ví C pro AVR... Pro latinu a čísla ASCII kódy se shodují s kódy zapojenými do generátoru znaků LCD, takže je přípustné používat lcd_dat („A“)... Můžete si vytvořit vlastní knihovnu pro práci s LCD oddělením funkcí lcd_dat (unsigned char x), lcd_com (unsigned char x), lcd_init (void) do samostatného modulu LCD.h a podle potřeby jej připojte.

Tato myšlenka šetří spoustu času, stačí zapsat potřebné funkce pouze jednou a potom je neustále používat. Můžete si také všimnout, že je nepohodlné zobrazovat dlouhou frázi po jednom písmenu, za tímto účelem můžete poslat náš výstupní řetězec do pole nepodepsaného znaku a zobrazit jej pomocí smyčky:

    int main (neplatný)

    (nepodepsaná char data [14] \u003d ("w", "w", "w", ".", "a", "v", "r", "l", "a", "b", " . "," c "," o "," m ");

    nepodepsaný znak i;

    DDRD \u003d 0xfc; // Inicializovat portD

    PORTD \u003d 0x00;

  1. pauza (1000); // Zpoždění zapnutí LCD

    lcd_init (); // Inicializace LCD

  2. pro (i \u003d 0; i< 14 ; i++ ) // Výstupní záznam písmeno po písmenu

    lcd_dat (data [i]);

Nezapomeňte, že číslování polí v C začíná od nuly. Stávající program lze použít ve spojení s ovladačem bez podstatných změn ATtiny2313připojením LCD na PORTBjako PORTD v ATtiny2313 má pouze 7 pinů, ne 8 jako v ATmega8.

Také vám doporučuji připojit se LCD pomocí odpojitelných připojení. Je velmi výhodné při ladění programu, když potřebujete zobrazit některá mezilehlá data. Připojil jsem jeden konektor a celou věc. V pokračování této poznámky v blízké budoucnosti zvážím také zobrazení přečtených informací LCD.
Přeji hezký den všem;)

v tomto příkladu je malá chyba

v tomto příkladu je malá chyba, možná z tohoto důvodu příklad nefunguje pro mnoho!

příklad je obecně výstižný a jednoduchý, takže malá chyba nezachytí pozornost (pro ty, kteří jsou vedeni v jazyce „C“), a ještě více pro ty, kteří se teprve seznamují s jazykem AVR a jazykem „C“, možná jsou dokonce zmateni, jak to ... .pište, udělejte to a bude to jako na obrázku ... ale nebylo to tam ...

obecně platí, že celý problém se zpožďovacími cykly, aby displej udržel krok s řadičem, zejména ve funkci

// Program pro vytvoření zpoždění

void pause (unsigned int a)

(nepodepsané int i;

pro (i \u003d a; i\u003e 0; i-);

zdá se na první pohled všechno v pořádku, ale kompilátory pro mikrokontroléry se snaží optimalizovat kód pro maximální kompaktnost výsledného obrazu flash paměti programů ... a nevidět žádný bod v prázdné smyčce a podle toho dále po řetězci po něm: všechna volání, deklarace konstant a vše, co souvisí s tato funkce nemá v jeho mysli smysl ... jednoduše ji odebere z kódu během montáže ...

alespoň to platí pro atmel studio 6.1 a můžete se o tom ujistit při pohledu do složky projektu, existuje soubor * .lss obsahující kód assembleru tohoto programu, generovaný při vytváření projektu. žádný náznak implementace funkce void pause ...

ve výsledku, když ovladač bliká, na displeji se objeví náhodné odpadky nebo prázdnota ... když stisknete reset několikrát, odpadky mohou zmizet a znovu se objevit ... zjevně obličej není synchronizován mezi procesorem a obrazovkou

ale pokud provedete malý pozměňovací návrh

void pause (unsigned int a)

(nepodepsané int i;

pro (i \u003d a; i\u003e 0; i--)
asm ("nop");

Pak to dává smysl pro kompilátor, to také potvrzuje explicitní vzhled implementace funkce v kódu assembleru

0000006c
:
6c: 9c 01 movw r18, r24
6e: 03 c0 rjmp. + 6; 0x76
70: 00 00 nop
72: 21 50 dílčí r18, 0x01; 1
74: 31 09 sbc r19, r1
76: 21 15 cp r18, r1
78: 31 05 CPC R19, R1
7a: d1 f7 brne.-12; 0x70

a s největší pravděpodobností bude vše fungovat .... alespoň pro mě na atmega16 (interní RC synchronizace 1Mhz) a pomocí atmel studio 6.1 to bylo takhle ... možná na jiných frekvencích budete muset hrát s konstantou #define TIME 10 a / nebo s hodnotami předanými funkci neplatná pauza

zde-\u003e pauza (hodnota) ... nebo pauza (hodnota * TIME) ....

hodně štěstí, naučit se ovládat AVR!

Podívej, představ si ten LCD -

Podívejte se, představte si, že LCD je psací stroj, papír v psacím stroji je paměť LCD, vozík je kurzorový ukazatel. LCD navíc nezobrazuje celý obsah paměti, ale pouze část. Něco jako nějaké okno, které se vejde na náš papír s textem.

Zde I / D určuje, jak budeme tisknout, zprava doleva nebo zleva doprava.
S určuje, zda budeme přesouvat okno obrazovky po tom, jak budeme tisknout, nebo ne.
S / C - pouze posune viditelné okno obrazovky nebo vozík psacího stroje.
R / L - určuje, kam (vlevo nebo vpravo) přesuneme obrazovku nebo kurzy pomocí příznaku S / C.

něco v mém chybí!

Odtrhněte svůj prog a proteus a nezačíná na mega8. Obrazovka je tichá, začal jsem kopat do datových listů a to jsem vykopal:
chybí při inicializaci prvních tří!

0011 - počkejte 5 ms
0011 - čekání na 100 μs
0011 - počkejte 2 ms
0010 - počkejte 41 μs
0000 - -
0010 - -
1000
0000
1000
0000
0001
0000
0100

pokud se mýlím, opravte to!

Nefunguje!

Snažil jsem se změnit taktovací frekvence, zpoždění během inicializace a zobrazování symbolů (příkazů), zatím bez úspěchu. Pokud jde o pojistky, pokud chcete konfigurovat piny portu D pomocí DDRB, PORTD se registruje jako nízké výstupy protokolu. úrovni, pak jsem to udělal.
Abych nic nedělal, sestavil jsem jednoduchý program pro zobrazování symbolů pomocí nástrojů CodeVisionAVR, vložil ho do PROTEUS - funguje to ... ... ale odmítá se skutečným LCD ..

Ne, mluvím o tom

Ne, mluvím o pokusu vyvést například blikající světlo na portu D, nebo jen rozsvítit celý port najednou. Když jsem koupil pouze mikrokontrolér, nemohl jsem to udělat. Hrabal jsem se ve fórech a ukázalo se, že jsou tam nějak naprogramovány pojistky, že port D a všech jeho 8 bitů nejsou zahrnuty. Zaškrtněte tento bod, nebo raději zkuste přesunout LCD na jiný port, například B. Skutečnost, že program v proteu funguje, ale se skutečným ne - to je rozdíl v parametrech LCD ucpaných v proteu a skutečném.

Nefunguje!

Sestavil jsem a připojil vše podle schématu, pouze MK používal ATmega16 a LCD WH1602M, respektive jsem pro to kompiloval firmware ve WinAVR. LCD však odmítl cokoli vydávat, také shromažďoval v proteu (na ATmega 8 a LM016L), data z MK se zobrazují, ale na LCD nic není vidět. V čem by mohl být problém? (Je-li to důležité, používá se interní RC oscilátor k taktování na 1MHz)

1. Pro Atmega16 potřebujete

1. U Atmega16 je nutné nejprve zapnout pojistky, aby port D fungoval.
2. Zkuste změnit taktovací frekvenci na 4MHz a 8MHz. Celý problém LCD spočívá v tom, že nejsou dodrženy všechny pauzy během inicializace nebo při zadávání příkazu. A ovladač LCD je na to velmi citlivý.

Mít dotaz:
Sestavil jsem obvod chronometru na mega 8 s hotovým hexem, - hodnoty jsou zobrazeny na WH0802,
indikace - počet tří číslic, které se zobrazují na celé obrazovce, jedna číslice se skládá ze 4 známých. Obrazovka je pseudografická. Jak by mohl být firmware zapsán ??
Autor kategoricky odmítá poskytnout zdrojový kód a práci nekomentuje, pravděpodobně z důvodů „duševního vlastnictví“.
Ve svobodě se chci pokusit napsat vlastní firmware pro vzdělávací účely.

Tváří v tvář takové

Tváří v tvář takové situaci.
K dispozici jsou dva LCD 16x2:
1 - MTC-S16204XFGHSAY
2 - WH1602A-YGH-CTK

První, který používám v projektu s GPS.
Druhý se rozhodl jej použít v projektu s klávesnicí. Ale z nějakého důvodu LCD nefunguje.
Kontrast se upraví a objeví se čtverce. A to je vše.
Možná existuje jiné pořadí inicializace.
Pomozte mi pochopit
Zde jsou datové listy
filebox.od.ua/?file\u003d24a31fc50d62bfcd658bdadac84088ab

Displeje se neliší.

Displeje se neliší. Pinout je stejný. Načasování se mírně liší. Zkuste zvýšit zpoždění při odesílání příkazů na LCD nebo snížit frekvenci MK.

Všechny displeje LCD na HD44780 mají stejný příkazový systém. Jaké rozhraní používáte, 4bitové nebo 8bitové? Pokuste se také zvýšit prodlevu mezi zapnutím LCD a jeho inicializací, a to až na přibližně 0,1 s. Polarita napájecího zdroje pro LCD nebyla zmatená, takže potřebují trochu vyhoření? Pak jsem nějak hloupě spálil a pak se pokusil připojit. Byly také zobrazeny černé čtverečky, data byla zobrazena pokaždé, tj. pracoval extrémně nestabilní.

Používám programy z článků

Používám programy z článků o GPS.
4bitové rozhraní

zkusil program odtud
chipenable.ru/index.php/programming-c/75-chasy-na-mikrokontrollere.html

vydělal

A co změnit ve svém programu?

Věnujte pozornost zpožděním

Věnujte pozornost zpožděním po zadání inicializačních a konfiguračních příkazů. Také jsem měl případ, něco takového, ale ovladače byly oba stejné a program fungoval pouze na jednom.

Analogové pro HD44780

Tváří v tvář problému - nemohu najít LCD WH1602A za rozumnou cenu. například
v chipdip jsou to chipdip.ru/product/wh1602a-ygh-ct-k.aspx
700 dřevěných. Co je YGH v názvu „WH1602A-YGH-CT (K), LCD 16x2, anglicky-rusky“
Jaké jsou analogy LCD založené na HD44780? Našel jsem stránku micronika.ru/order.phtml?vid\u003d64 - tam název FDCC1602A-FSBFBW-51SR obsahuje 1602A,
právě jsem si všiml. Možná se FDCC1602A-FSBFBW-51S obejde bez velké změny kódu?
Jaké problémy mohou nastat při používání
není ve skutečnosti HD44780 od Hitachi, ale jeho analogy?
PS Nebylo by špatné číst o použití různých LCD, analogů xd44780, než MELT "ovsky"
LCD jsou špatné

K aktivaci čtyřbitového režimu je nutné programově generovat řídicí signály podle časových diagramů na obr.1. Ve struktuře se shodují s diagramem 8bitové sběrnice, s výjimkou zdvojnásobeného počtu „E“ pulsů. Komunikační linky procházejí bity nejvyššího řádu datové sběrnice DB4-DB7, nízké řady DB0-DB3 zůstávají nevyužité.

Obr. 1

Výhodou režimu je malý počet vodičů, zjednodušení topologie desky s plošnými spoji a hospodárnost linek portu MC. Nevýhodou je snížená rychlost přenosu dat na LCD, protože informace musí být přenášeny ve dvou částech (nibbles nebo tetrads) po 4 bitech. S přihlédnutím k povinným časovým zpožděním v programu a fyzické setrvačnosti „tekutých krystalů“ však pokles rychlosti téměř nepociťujeme.

Zvažme princip fungování 4bitové sběrnice na příkladu testovacího programu pro náš LCD. Na displeji se s druhou pauzou zobrazí číslice desetinné adresy známé 0-255 a grafické obrázky symbolů, které obsahují.

Postava: 2

Jak víte, každý LCD má vestavěný generátor znaků, což je oblast ROM s objemem více než 8 Kb, který je šitý ve výrobě. První polovina ROM s adresami 00-7Fh tradičně obsahuje obrysy čísel, interpunkční znaménka a velká a malá písmena latinské abecedy. Všechno je jako v IBM PC. Druhá polovina je „ponechána na milost“ národních abeced. V tomto ohledu má HD44780 modifikaci designu se třemi hlavními možnostmi pro šití generátoru znaků:

latina a evropské jazyky (evropské standardní písmo nebo euro)
latinské a japonské znaky (japonské standardní písmo nebo Japonsko)
latinka a cyrilice (vlastní písmo nebo ruština, obr. 2)

Ne všechny buňky generátoru znaků jsou vyplněny. Když se odkazuje na „prázdné“ buňky, na obrazovce se zobrazí libovolné informace, které se nejčastěji skládají z přeexponovaných bodů. Prvních 8 znaků s adresami 0x00-0x07 je označeno hvězdičkou. Pokud je to požadováno, mohou být uživatelem nezávisle naprogramovány.

Který generátor znaků je k dispozici na konkrétním displeji LCD, by měl být uveden v jeho symbolu nebo v technických parametrech, ačkoli v praxi musíte věřit čestnému slovu prodejce. Dalším přístupem je vidět na obrazovce LCD všechny možné styly znaků. Pojďme napsat, zkompilovat program a naprogramovat kontroler, poté se na horním řádku LCD obrazovky zobrazí s druhou pauzou číslice adresy desetinného místa 0-255 a grafické obrázky symbolů, které obsahují. Pokud se grafika a pořadí symbolů objeví, jak je znázorněno na obrázku 2, pak je LCD v pořádku.

class \u003d "eliadunit"\u003e

Dále sestavíme obvod podle obr.3, jeho jediný rozdíl spočívá v tom, že datová sběrnice je připojena přes 4vodičové vedení, tj. DB4-DB7 jsou připojeny a DB0-DB3 zůstávají nevyužité. R / W výstup displeje je připojen k minus, protože náš displej je přijímač dat.

Níže je uveden kód testovacího programu generátoru znaků LCD.

// Program pro kontrolu generátoru znaků LCD # zahrnout #zahrnout #define RS PC0 #define EN PC2 // Funkce pro zápis příkazu na LCD void lcd_com (nepodepsaný znak p) (PORTC & \u003d ~ (1<< RS); // RS = 0 (запись команд) PORTC |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p & 0xF0); // Выделяем старший нибл _delay_us(100); PORTC &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); PORTC |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p << 4); // Выделяем младший нибл _delay_us(100); PORTC &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); } // Функция записи данных в ЖКИ void lcd_dat(unsigned char p) { PORTC |= (1 << RS)|(1 << EN); // RS = 1 (запись данных), EN - 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p & 0xF0); // Выделяем старший нибл _delay_us(100); PORTC &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); PORTC |= (1 << EN); // EN = 1 (начало записи команды в LCD) PORTD &= 0x0F; PORTD |= (p << 4); // Выделяем младший нибл _delay_us(100); PORTC &= ~(1 << EN); // EN = 0 (конец записи команды в LCD) _delay_us(100); } // Функция инициализации ЖКИ void lcd_init(void) { DDRC |= (1 << PC2)|(1 << PC0); // PC1, PC0 - выходы PORTC = 0x00; DDRD = 0xFF; // порт D - выход PORTD = 0x00; _delay_ms(50); // Ожидание готовности ЖК-модуля // Конфигурирование четырехразрядного режима PORTD |= (1 << PD5); PORTD &= ~(1 << PD4); // Активизация четырехразрядного режима PORTC |= (1 << EN); PORTC &= ~(1 << EN); _delay_ms(5); lcd_com(0x28); // Шина 4 бит, LCD - 2 строки lcd_com(0x08); // Полное выключение дисплея lcd_com(0x01); // Очистка дисплея _delay_us(100); lcd_com(0x06); // Сдвиг курсора вправо _delay_ms(10); lcd_com(0x0C); // Включение дисплея, курсор не видим } // Основная программа int main (void) { unsigned char znak = 0; // определяем переменную lcd_init(); // Инициализация дисплея while (1) { lcd_com(0x80); // Вывод в верхнюю левую позицию 1 строки lcd_dat(znak/100 + "0"); // Выделяем сотни lcd_dat((znak/10)%10 + "0"); // Выделяем десятки lcd_dat(znak%10 + "0"); // Выделяем единицы lcd_dat("="); // Выводим знак равенства lcd_dat(znak); // Выводим содержимое знакогенератора _delay_ms(100); // Тут можно поменять задержку вывода символов znak++; // Следующий символ знакогенератора } }

Pro práci se znakovými grafickými displeji doporučujeme použít knihovnu LiquidCrystal, která je součástí standardní sady Arduino IDE a je navržena pro práci na 8bitovém (4bitovém) paralelním rozhraní. Pokud je váš displej připojen k Arduinu přes sběrnici I2, musíte nainstalovat knihovnu LiquidCrystal_I2C (většina funkcí opakuje funkce první knihovny).

Podporované displeje:

Zobrazit Připojení a inicializace
LCD1602 - znakový displej (16x02 znaků),


#zahrnout
[ , 8 , 9 , 10 , 11 ]);
void setup () ( lcd.begin (16, 2);}

// Vysvětlení:

void setup () ( OBJECT.begin (NUMBER_COLUMNS, NUMBER_LINE); )


LiquidCrystal OBJECT (RS, E, D0, D1, D2, D3, D4, D5, D6, D7);


s rozhraním I2C (modrá)

#zahrnout
#zahrnout
LiquidCrystal_I2C lcd (0x27 nebo 0x3F, 16 , 2);
void setup () ( lcd.init (); }

// Vysvětlení:



LCD1602 I2C - zobrazení znaků (16x02 znaků),
s rozhraním I2C (zelená)

#zahrnout
#zahrnout
LiquidCrystal_I2C lcd (0x27 nebo 0x3F, 16 , 2);
void setup () ( lcd.init (); }

// Vysvětlení:
LiquidCrystal_I2C OBJECT (ADDRESS_I2C, NUMBER_COLUMNS, NUMBER_LINE);
// ADDRESS_I2C může být buď 0x27 nebo 0x3F

LCD2004 - zobrazení znaků (20x04 znaků),
s paralelním rozhraním (modrá)

#zahrnout
LiquidCrystal lcd (2, 3, 4, 5, 6, 7[ , 8 , 9 , 10 , 11 ]);
void setup () ( lcd.begin (20, 4);}

// Vysvětlení:
LiquidCrystal OBJECT (RS, E, D4, D5, D6, D7);
void setup () (OBJECT.begin (NUMBER_ OF COLUMNS, NUMBER_ OF ROWS);)

// Pokud je použito 8 vodičů datové sběrnice, uveďte všechny
LiquidCrystal OBJECT (RS, E, D0, D1, D2, D3, D4, D5, D6, D7);

LCD2004 I2C - zobrazení znaků (20x04 znaků),
s rozhraním I2C (modrá)
#zahrnout
#zahrnout
LiquidCrystal_I2C lcd (0x27 nebo 0x3F, 20 , 4);
void setup () ( lcd.init (); }

// Vysvětlení:
LiquidCrystal_I2C OBJECT (ADDRESS_I2C, NUMBER_COLUMNS, NUMBER_LINE);
// ADDRESS_I2C může být buď 0x27 nebo 0x3F

# 1 Příklad

Zobrazujeme nápis na displeji LCD1602 připojeném přes sběrnici I2C. Chcete-li pracovat s displejem LCD2004, musíte změnit řádek 3 na LiquidCrystal_I2C lcd (0x27,20,4);

#zahrnout // Knihovnu pro práci s LCD displejem propojujeme přes sběrnici I2C LiquidCrystal_I2C lcd (0x27,16,2); // Deklarujte objekt knihovny a určete parametry zobrazení (adresa I2C \u003d 0x27, počet sloupců \u003d 16, počet řádků \u003d 2) // Pokud se nápis nezobrazí, nahraďte adresu 0x27 hodnotou 0x3F void setup () (// lcd.init (); // Zahájení práce s LCD displejem lcd.backlight (); // Zapnutí podsvícení LCD displeje lcd.setCursor (0, 0); // Nastaví kurzor na pozici (0 sloupec, 0 řádek) lcd.print ("LCD"); // Zobrazit text „LCD“ počínaje od nastavené polohy kurzoru lcd.setCursor (0, 1); // Nastavte kurzor na pozici (sloupec 0, 1 řádek) lcd.print („www.iarduino.ru“); // Zobrazujeme text „www.iarduino.ru“, počínaje nastavenou pozicí kurzoru) // // void loop () () // Kód uvnitř funkce smyčky je prováděn neustále. Ale protože zobrazujeme statický text, musíme ho zobrazit pouze jednou při spuštění, bez použití kódu smyčky

# 2 Příklad

Zobrazujeme nápis na displeji LCD1602 připojeném přes 4bitovou paralelní sběrnici. Chcete-li pracovat s displejem LCD2004, musíte změnit 5. řádek na lcd.begin (20, 4);

#zahrnout // Propojíme knihovnu LiquidCrystal pro práci s LCD displejem LiquidCrystal lcd (2,3,4,5,6,7); // Deklarujeme objekt knihovny s uvedením pinů displeje (RS, E, D4, D5, D6, D7) // Pokud je použito 8 vodičů datové sběrnice, pak označíme (RS, E, D0, D1, D2, D3, D4, D5, D6, D7) void setup () (// lcd.begin (16, 2); // Zahájit práci s LCD displejem a určit počet (sloupce, řádky) lcd.setCursor (0, 0); // Nastavit kurzor do polohy (0 sloupec, 0 řádek) lcd.print ("LCD2004"); // Zobrazí text "LDC1602" počínaje od nastavené polohy kurzoru lcd.setCursor (0, 1); // Nastaví kurzor na pozici (0 sloupec, 1 řádek ) lcd.print ("www.iarduino.ru"); // Zobrazí text "www.iarduino.ru", počínaje od nastavené polohy kurzoru) // // void loop () () // Kód uvnitř funkce smyčky se provádí neustále ... Ale protože zobrazujeme statický text, musíme ho zobrazit pouze jednou na začátku, bez použití kódu smyčky

# 3 Příklad

Na displeji LCD1602 připojeném přes sběrnici I2C zobrazujeme nápis „Russian language“:

#zahrnout // Propojujeme knihovnu pro práci se sběrnicí I2C #include // Knihovnu pro práci s LCD displejem propojujeme přes sběrnici I2C LiquidCrystal_I2C lcd (0x27,16,2); // Deklarujte objekt knihovny se specifikací parametrů zobrazení (adresa I2C \u003d 0x27, počet sloupců \u003d 16, počet řádků \u003d 2) // uint8_t symbol \u003d (// Deklarujte pole 6 vlastních symbolů (k a th z s), každý symbol skládá se z 8 bajtů (0, 0,18,20,24,20,18,0), // do (0, 0,17,19,21,25,17,0), // a (10, 4 , 17,19,21,25,17,0), // d (0, 0,15,17,15, 5, 9, 0), // i (0, 0,14,17, 6,17 , 14, 0), // s (0, 0,17,17,29,19,29,0)); // s // void setup () (// lcd.init (); // Zahájení práce s LCD displejem lcd.backlight (); // Zapnutí podsvícení LCD displeje lcd.createChar (1, symbol); // Načíst 1 znak „k“ na displeji RAM lcd.createChar (2, symbol); // Načte 2. znak „a“ do paměti RAM lcd.createChar (3, symbol); // Načte 3. „znak“ na displeji RAM lcd.createChar (4, symbol); // Načte 4. symbol „i“ do paměti RAM lcd.createChar (5, symbol); // Načte 5. znak „z“ do paměti RAM lcd.createChar (6, symbol); // Načte 6 znak "s" na displeji RAM lcd.setCursor (0, 0); // Nastaví kurzor na pozici (0 sloupec, 0 řádek) lcd.print ("Pycc \\ 1 \\ 2 \\ 3 \\ 4 \\ 5 \\ 6 \\ 1" ); // Zobrazit text „Ruský jazyk“, kde je „Pycc“ psán latinsky, a „jazyk ky“ - znaky z RAM displeje) // // Pokud potřebujete zobrazit znak z RAM displeje, napište \\ a číslo znaku // void loop ( ) () // Kód uvnitř funkce smyčky běží nepřetržitě. Ale protože zobrazujeme statický text, musíme ho zobrazit pouze jednou na začátku, bez použití kódu smyčky

Společné funkce knihoven LiquidCrystal a LiquidCrystal_I2C:

  • začít (sloupky, řádky, ); - Zobrazit inicializaci zadáním počtu sloupců, řádků a velikosti znaků.
  • průhledná (); - Vymaže displej s kurzorem na 0,0 (Trvá to hodně času!).
  • domov (); - Nastavení kurzoru do polohy 0,0 (Trvá to hodně času!).
  • zobrazit (); - Rychlé zapnutí displeje (beze změny dat v RAM).
  • noDisplay (); - Rychlé vypnutí displeje (beze změny dat v paměti RAM).
  • blink (); - Zapněte blikající kurzor (s frekvencí přibližně 1 Hz).
  • noBlink (); - Vypněte blikající kurzor.
  • kurzor (); - Povolit podtržení kurzoru.
  • noCursor (); - Vypněte podtržení kurzoru.
  • scrollDisplayLeft (); - Posouvá displej doleva. Posunutí souřadnic displeje o jeden sloupec doleva (beze změny RAM).
  • scrollDisplayRight (); - Posune displej doprava. Posunutí souřadnic displeje o jeden sloupec doprava (beze změny RAM).
  • zleva do prava (); - Označuje v budoucnu posunutí polohy kurzoru, po zobrazení dalšího znaku o jeden sloupec doprava.
  • zprava doleva (); - V budoucnu indikuje posunutí pozice kurzoru, po zobrazení dalšího znaku o jeden sloupec doleva.
  • noAutoscroll (); - Označuje v budoucnu zarovnání textu nalevo od pozice kurzoru (jako obvykle).
  • automatické rolování (); - Označuje pro další zarovnání textu napravo od pozice kurzoru.
  • createChar (číslo, pole ); - Zápis vlastního znaku na displej CGRAM pod zadaným číslem.
  • setCursor (col, řádek ); - Nastavení kurzoru na pozici označenou číslem sloupce a řádku.
  • vytisknout (text ); - Zobrazit text, symboly nebo čísla na obrazovce displeje. Syntaxe je podobná funkci se stejným názvem ve třídě Serial.

Funkce implementované pouze v knihovně LiquidCrystal_I2C:

  • init (); - Inicializace displeje. Měl by to být první příkaz knihovny LiquidCrystal_I2C po vytvoření objektu. Ve skutečnosti je tato funkce také v knihovně LiquidCrystal, ale v této knihovně je volána automaticky (ve výchozím nastavení) při vytvoření objektu.
  • podsvícení (); - Zapněte podsvícení displeje.
  • noBacklight (); - Vypněte podsvícení displeje.
  • setBacklight (vlajka ); - Ovládání podsvícení (true - enable / false - disable), používá se místo funkcí noBacklight a backlight.

Spojení:

// Pro sběrnici I2C:
#zahrnout
#zahrnout
LiquidCrystal_I2C lCD (adresa , plk , řádek );
void setup () (
lcd.init ();
}

Parametr:
  • adresa: Zobrazit adresu na sběrnici I2C - 0x27 nebo 0x3F
  • col:
  • řádek:
// Pro 4vodičovou paralelní sběrnici:
#zahrnout
Tekutý krystal lCD ( RS , E , D4 , D5 , D6 , D7 );
void setup () (
lcd.begin ( plk , řádek );
}
Parametr:
  • RS: Arduino pin #, ke kterému je připojen RS pin
  • E: Arduino pin #, ke kterému je připojen pin E.
  • D0 ... D3: Počet pinů Arduino, ke kterým jsou připojeny piny D0-D3
  • D4 ... D7: Počet pinů Arduino, ke kterým jsou připojeny piny D4-D7
  • col: počet sloupců implementovaných na displeji
  • řádek: počet řádků realizovaných displejem
// Pro paralelní 8vodičovou sběrnici:
#zahrnout
Tekutý krystal lCD ( RS , E , D0 , D1 , D2 , D3 , D4 , D5 , D6 , D7 );
void setup () (
lcd.begin ( plk , řádek );
}
začít (plk , řádek , );
Inicializace displeje s velikostí obrazovky a symboly.
Parametr:
  • col: počet sloupců implementovaných na displeji
  • řádek: počet řádků realizovaných displejem
  • velikost: velikost znaků určená konstantou:
    LCD_5x8DOTS (výchozí) nebo LCD_5x10DOTS
/ * Pro sběrnici I2C: * / #include // Propojujeme knihovnu pro práci se sběrnicí I2C #include // Knihovnu pro práci s LCD displejem propojujeme přes sběrnici I2C LiquidCrystal_I2C lcd (0x3F, 20.4); // Deklarujte objekt knihovny a určete parametry zobrazení (adresa I2C \u003d 0x3F, počet sloupců \u003d 20, počet řádků \u003d 4) // void setup () (// lcd.init (); // Zahájit práci s LCD displejem lcd.backlight (); // Zapne podsvícení LCD displeje ... // Zobrazit informace, které by se měly zobrazit při spuštění) // // void loop () () // ... // Zobrazit informace, které by se měly měnit podle algoritmu vašeho kódu) // / * Pro 4vodičovou paralelní sběrnici: * / #include // Propojíme knihovnu LiquidCrystal pro práci s LCD displejem LiquidCrystal lcd (2,3,4,5,6,7); // Deklarujeme objekt knihovny s uvedením pinů displeje (RS, E, D4, D5, D6, D7) // Pokud je použito 8 vodičů datové sběrnice, pak označíme (RS, E, D0, D1, D2, D3, D4, D5, D6, D7) void setup () (// lcd.begin (16, 2); // Zahajte práci s LCD displejem, zadejte počet (sloupce, řádky) ... // Zobrazit informace, které by se měly zobrazit při spuštění) / / // void loop () () // ... // Zobrazit informace, které by se měly změnit podle algoritmu vašeho kódu) //

Funkce ovládání displeje:

zobrazit ();
Zapne displej poté, co byl vypnut funkcí noDisplay.
Poznámka: Funkce běží rychle a beze změn paměti RAM displeje.
noDisplay ();
Vypne displej.
Data na displeji se nezobrazí, dokud není vyvolána funkce zobrazení, ale nebudou vymazána z paměti RAM a po vyvolání funkce displeje se zobrazí znovu.
Poznámka: Funkce se provádí rychle a beze změn paměti RAM displeje.
scrollDisplayLeft ();
Posune zobrazení souřadnic o jeden sloupec doleva.



scrollDisplayRight ();
Posune zobrazení souřadnic o jeden sloupec doprava.
Konstantní volání této funkce vytvoří efekt plíživé linky.
Souřadnice jsou posunuty jak pro informace dostupné na displeji, tak pro informace, které se zobrazí po.
Poznámka: Funkce se provádí beze změny paměti RAM displeje.
Pokud funkci zavoláte 40krát za sebou, pak se souřadnice vrátí do původního bodu
průhledná ();
Vymaže displej s kurzorem nastaveným na 0,0.
Informace na displeji budou trvale vymazány.
Poznámka: Trvá to dlouho.
podsvícení ();
Zapne podsvícení displeje.
noBacklight ();
Vypněte podsvícení displeje.
Poznámka: Tato funkce je implementována pouze v knihovně LiquidCrystal_I2C.
setBacklight (vlajka );
Ovládání podsvícení (místo funkcí noBacklight a podsvícení).
Parametr:
  • vlajka: true pro povolení, false pro vypnutí podsvícení.
Poznámka: Tato funkce je implementována pouze v knihovně LiquidCrystal_I2C.
/ * Zobrazit štítek pro monitorování řídicích funkcí displeje: * / lcd.cursor (0,0); // Nastavte kurzor do horního rohu displeje (sloupec 0, řádek 0) lcd.print ("iarduino.ru"); // Zobrazí text „iarduino.ru“ (první písmeno „i“ bude na pozici „0,0“ a poslední „u“ na pozici „10,0“, neviditelný kurzor na pozici „11,0“) // lcd.noDisplay (); // Vypněte displej (nápis zmizí z displeje) lcd.display (); // Zapněte displej (nápis se na displeji objeví na stejném místě) lcd.scrollDisplayLeft (); // Posunutí souřadnic sloupců doleva (na displeji se zobrazí „arduino.ru“ bez prvního písmene „i“, které bude přesahovat displej, ale zůstane v jeho paměti RAM) lcd.scrollDisplayRight (); // Posuňte souřadnice sloupců doprava (na displeji se zobrazí „iarduino.ru“ na stejném místě, kde byl původně zobrazen) lcd.clear (); // Vyčistěte displej (nápis trvale zmizí z displeje) lcd.noBacklight (); // Zakázat podsvícení displeje lcd.backlight (); // Zapnutí podsvícení displeje lcd.setBacklight (0); // Vypnutí podsvícení displeje lcd.setBacklight (1); // Zapne podsvícení displeje

Funkce ovládání kurzoru:

setCursor (plk , řádek );
Nastaví kurzor na zadanou pozici.
Parametr:
  • col: číslo sloupce (od 0).
  • řádek: číslo řádku (od 0)
domov ();
Nastavení kurzoru na pozici 0,0. Funguje jako setCursor (0,0);
Poznámka: Trvá to dlouho.
blink ();
Zapne blikající kurzor.
Poznámka: Kurzor zabírá celé pole znaků a bliká na frekvenci přibližně 1 Hz na pozici, kde byl dříve nastaven.
noBlink ();
Vypněte blikající kurzor.
Poznámka: Kurzor se stane neviditelným, ale jeho poloha zůstane.
kurzor ();
Povolit podtržení kurzoru.
Poznámka: Kurzor se stane znakem podtržítka a je v pozici, kde byl dříve umístěn.
noCursor ();
Vypněte podtržení kurzoru.
Poznámka: Kurzor se stane neviditelným, ale jeho poloha zůstane.
lcd.setCursor (0, 1); // Umístěte kurzor na první znak druhého řádku (číslování řádků a sloupců začíná od 0) lcd.home (); // Nastaví kurzor na první znak prvního řádku (jako při volání lcd.setCursor (0,0);) lcd.blink (); // Zviditelní kurzor (na pozici kurzoru bude blikat obdélník) lcd.noBlink (); // Nastaví kurzor jako neviditelný (odstraní blikající obdélník) lcd.cursor (); // Zviditelní kurzor (na pozici kurzoru se objeví podtržítko) lcd.noCursor (); // Zneviditelní kurzor (odstraní podtržítko) // Pokud kurzor zasáhne místo, kde je znak, pak tento znak nezmizí

Funkce udávající směr a zarovnání:

zleva do prava ();
Označuje, že po každém novém znaku by měla být pozice kurzoru posunuta o jeden sloupec doprava.
Poznámka: Pokud napíšete text „abc“, na displeji se zobrazí „abc“ a text bude napravo od původní polohy kurzoru.
(Jako obvykle)
zprava doleva ();
Označuje, že po každém novém znaku by měla být pozice kurzoru posunuta o jeden sloupec doleva.
Poznámka: Pokud vytisknete text „abc“, na displeji se zobrazí „cba“ a text bude nalevo od původní polohy kurzoru.
(Psaní zprava doleva)
noAutoscroll ();
Označuje, že v budoucnu by měl být text zarovnán doleva z původní polohy kurzoru.
Poznámka: Pokud umístíte kurzor na pozici 10.0 a zobrazíte text, bude první znak zobrazeného textu na této pozici.
(Jako obvykle)
automatické rolování ();
Označuje, že později by měl být text zarovnán doprava z původní polohy kurzoru.
Poznámka: pokud umístíte kurzor na pozici 10.0 a zobrazíte text, bude kurzor na této pozici.
(Souřadnice displeje se posunou doleva, jako kdybyste volali funkci scrollDisplayLeft tolikrát, kolikrát jsou v zobrazeném textu písmena)
lcd.leftToRight (); // Řekněte kurzoru, aby se posunul doprava (jako obvykle v evropském psaní) lcd.clear (); lcd.setCursor (5.0); lcd.print ("ABC"); // Na displeji uvidíme: „ABC“ (Po „A“ se kurzor posunul doprava a zobrazil „B“, poté se kurzor posunul doprava a zobrazil „C“) lcd.rightToLeft (); // Řekněte kurzoru, aby se pohyboval doleva (stejně jako při psaní zprava doleva) lcd.clear (); lcd.setCursor (5.0); lcd.print ("ABC"); // Na displeji uvidíme: „CBA“ (Po „A“ se kurzor přesunul doleva a zobrazil „B“, poté se kurzor přesunul doleva a zobrazil „C“) lcd.noAutoscroll (); // Nastavit zarovnání doleva (jako obvykle) lcd.clear (); lcd.setCursor (5.0); lcd.print ("ABC"); // Na displeji se zobrazí: „ABC“ (jako obvykle) lcd.autoscroll (); // Nastavit zarovnání doprava (souřadnice zobrazení budou posunuty doleva o počet zobrazených znaků) lcd.clear (); lcd.setCursor (5.0); lcd.print ("ABC"); // Na displeji uvidíme: „ABC“ (souřadnice displeje se posunou o 3 znaky doleva, protože po každém znaku se volá funkce scrollDisplayLeft)

Funkce pro zadávání textu a symbolů:

createChar (num, array);
Zápis vlastního znaku na displej CGRAM pod zadaným číslem.
Pokud chcete zobrazit text (pomocí funkce tisku), ve kterém by měl být nainstalovaný znak, zadejte lomítko a číslo, pod kterým byl tento znak napsán: print ("C \\ 1MBO \\ 2").
Parametr:
  • číslo: číslo, pod kterým bude znak zapsán.
  • pole: pole představující znak, který se má zapsat.
Poznámka: Pole se skládá z několika bytů, jejichž počet se rovná počtu řádků ve znaku. Každý nastavený bit bajtu odpovídá nastavenému (zobrazenému) pixelu znaků.
tisk (text);
Zobrazuje text, znaky nebo čísla na displeji.
Parametr:
  • text: znak, číslo nebo řetězec, který se má zobrazit.
Poznámka: Syntaxe je podobná funkci se stejným názvem ve třídě Serial.
#zahrnout // Propojujeme knihovnu pro práci se sběrnicí I2C #include // Knihovnu pro práci s LCD displejem propojujeme přes sběrnici I2C LiquidCrystal_I2C lcd (0x27,16,2); // Deklarujte objekt knihovny a specifikujte parametry zobrazení (adresa I2C \u003d 0x27, počet sloupců \u003d 16, počet řádků \u003d 2) // uint8_t symbol_d \u003d (0b00000, // 1 řádek symbolu „d“ 0b00000, // 2 řádek symbolu „d "0b00110, // 3 řádky znaku" d "0b01010, // 4 řádky znaků" d "0b01010, // 5 řádků znaků" d "0b01010, // 6 řádků znaků" d "0b11111, // 7 řádků znaků" d „0b10001); // 8 řetězec symbolu „d“ Celé pole lze zapsat do jednoho řádku: uint8_t symbol_d \u003d (0,0,6,10,10,10,31,17); // uint8_t symbol_i \u003d (0b00000, // 1 řádek symbolu "a" 0b00000, // 2 řádky symbolu "a" 0b10001, // 3 řádky symbolu "a" 0b10011, // 4 řádky symbolu "a" 0b10101, // 5znakový řetězec "a" 0b11001, // 6znakový řetězec "a" 0b10001, // 7znakový řetězec "a" 0b00000); // 8 řetězec symbolů "a" Celé pole lze zapsat do jednoho řádku: uint8_t symbol_i \u003d (0,0,17,19,21,25,17,0); void setup () (// lcd.init (); // Zahájení práce s LCD displejem lcd.backlight (); // Zapnutí podsvícení LCD lcd.createChar (1, symbol_d); // Načtení prvního znaku lcd do paměti displeje .createChar (2, symbol_i); // Načte druhý symbol do paměti displeje lcd.clear (); // Vyčistí obrazovku lcd.setCursor (0,0); // Nastaví kurzor do nejvyššího rohu lcd.print ("Pa \\ // void loop () (// lcd.setCursor (0,1); lcd.print (""); // vymazat celý spodní řádek lcd.setCursor (0,1); lcd.print ("i"); lcd.print ("arduino"); lcd.print (". ru"); // zobrazí text "i" "arduino" ".ru" ve spodním řádku delay (2000); // počkat 2 sekundy lcd.setCursor ( 0,1); lcd.print (""); // vymaže celý spodní řádek lcd.setCursor (0,1); lcd.print (12,345); // vytiskne číslo 12,34 (jsou zobrazena 2 desetinná místa) zpoždění (2000 ); // počkejte 2 sekundy lcd.setCursor (0,1); lcd.pri nt (""); // vymazat celý spodní řádek lcd.setCursor (0,1); lcd.print (12, HEX); // zobrazí číslo 12 jako šestnáctkové zpoždění čísla (2000); // počkejte 2 sekundy lcd.setCursor (0,1); lcd.print (""); // vymazat celý spodní řádek lcd.setCursor (0,1); lcd.print (1); // zobrazí zpoždění číslo 1 (2000); // počkejte 2 sekundy)

Takový displej byl nějakou dobu nečinný.


A teď byla touha spojit to s jedním z projektů, můžete se samozřejmě pokusit najít knihovnu s hotovými funkcemi, ale v tomto případě bude obrázek toho, jak funguje displej, neúplný a nejsme s tím spokojeni. Jakmile jednou zjistíte princip LCD displeje, nebude těžké napsat vlastní knihovnu pro požadované zobrazení, pokud chybí nebo vám nějak nevyhovuje.

Pojďme tedy začít.
První věc, kterou musíte udělat, je najít pinout, to znamená, který kontakt je za co zodpovědný, druhým je najít název řadiče, který řídí displej, pro tento účel stáhneme datový list na tento LCD a otevřete jej na první stránce.


Kontakty se počítají zleva doprava, první je označen červenou šipkou. Napájecí napětí je 5 voltů, řídicí jednotka S6A0069 nebo podobné, například ks0066U.

Proč jsme hledali název řídícího kontroléru? Faktem je, že datový list na displeji má časová zpoždění (časový diagram), je popsán příkazový systém, ale neexistuje žádná banální inicializace a bez ní nikde.
Dále otevřete druhou stránku a uvidíme tabulku, ve které je napsáno, pro který kontakt je, za co je zodpovědný.


DB7 ... DB0 - datová / adresová sběrnice.

R / W - určuje, co budeme dělat, číst (R / W \u003d 1) nebo psát (R / W \u003d 0)

R / S - určuje, že pošleme příkaz (RS \u003d 0) nebo data (RS \u003d 1)

E - stroboskopický vstup, změnou signálu na tomto vstupu umožňujeme displeji číst / zapisovat data.

LED ± - ovládání podsvícení.

Musím říci, že na displeji, který jsem dostal, se podsvícení jen tak nezapne, k tomu je potřeba pájet rezistor označený na desce jako R7. Ale ještě to nepotřebujeme.

Stáhněte si datový list do řídicí jednotky a najděte instrukci pro inicializaci. Kliknutím na ně lze obrázky zvětšit.



Ukázalo se, že existují dva takové pokyny, pro 8bitový a 4bitový režim. O jaké režimy se jedná? Tyto režimy určují, kolik řádků budou data přenášena: čtyřmi nebo osmi. Podívejme se na přenos znovu 4 dráty, v tomto případě bude displej fungovat pomaleji, ale ušetříme 4 piny mikrokontroléru a implementace osmibitového režimu se příliš neliší.

Schéma připojení informací je následující.


Kontrast lze upravit připojením potenciometru mezi napájecí kolíky.

Rád bych vás upozornil na skutečnost, že během inicializace R / S a R / W vždy rovna nule, to znamená, že pošleme příkazy.

Během inicializace můžete konfigurovat:

  • N - počet zobrazených řádků
  • C - povolí nebo zakáže kurzor
  • B - nechte kurzor blikat
  • I / D - zvyšuje nebo snižuje hodnotu čítače adres
  • SH - posune okénko displeje
Podívejme se na poslední dva body podrobněji.
Obrázek níže ukazuje, na jakou adresu musí být data zapsána, aby byla zobrazena na určité pozici, například pokud chceme zobrazit znak na první pozice druhého řádku, pak bychom měli napsat na adresu 0x40.


Poté se hodnota čítače automaticky změní, buď se zvýší nebo sníží, a spolu s tím se změní i pozice kurzoru.

Mimochodem, paměť, do které zapisujeme, se nazývá DDRAM, vše, co zapíšeme do této paměti, se zobrazí, stále existuje CGROM, která ukládá tabulku generátoru znaků.


Tuto tabulku nelze změnit, ale lze z ní převzít hotové symboly. Další typ paměti je CGRAM, představuje také tabulku generátoru znaků, ale symboly v této tabulce nakreslíme sami.


Nyní pár slov o pohybu obrazovky, faktem je, že obvykle na displeji nevidíme všechny DDRAM, ale pouze určitou část, jak je znázorněno na obrázku níže.


Můžeme také psát do neviditelné části, ale to, co napíšeme, nebude viditelné, dokud nepřesuneme okno obrazovky na toto místo.

Po dokončení teorie přejdeme k praxi.
Obrázek komunikace s LCD displejem ve 4bitovém režimu je následující.


Data se odesílají po bajtech, ale protože máme 4bitový režim, je třeba k odeslání bajtu odeslat 2 zprávy, nejvýznamnější bit vpřed. Na obrázku je první premisa označena D7 (senior tetrad), druhá D3 (junior tetrad). Před dalším odesláním musíme zkontrolovat příznak zaneprázdnění a pokud není nastaven znovu, můžeme jej odeslat, pokud je nastaven, počkáme, až ovladač, který ovládá LCD, dokončí svou činnost.

S obecným obrázkem odesílání pojďme zjistit, jak implementovat operaci odeslání.


Chcete-li odeslat, musíte použít 8bitovou sběrnici:
  • R / W nastaveno na 0
  • vydáme příkazový kód / data na sběrnici
  • zpoždění 2us
  • spodní stroboskop E

Operace čtení je implementována stejným způsobem:

  • ujistěte se, že je hlavní ovladač volný
  • R / W nastaveno na 1
  • zvedněte bránu E (v tomto okamžiku LCD pošle data na sběrnici)
  • zpoždění 2us
  • přečtěte si, co dal LCD
  • spodní stroboskop E
Odkud pochází latence 2us?

Nad časováním je tabulka, ve které je napsáno, jaké jsou zpoždění zobrazené v grafu, takže doba pulzního záblesku - tw by měla být rovna 230nS nebo 450nS v závislosti na napájecím napětí, vzali jsme trochu s rezervou. Proč jsme uvažovali pouze o tomto zpoždění? Protože hodnota zbývajících zpoždění je velmi malá.

Odeslání na 4bitové sběrnici:

  • ujistěte se, že je hlavní ovladač volný
  • nastavte RS na 0 (příkaz) nebo 1 (data), v závislosti na tom, co pošleme
  • R / W nastaveno na 0
  • zvýšit bránu E (nastavena na 1)
  • vydáváme starší notebook v pneumatice
  • zpoždění 2us
  • spodní stroboskop E
  • zpoždění 1us
  • zvýšit bránu E (nastavena na 1)
  • vydáváme mladší notebook v autobuse
  • zpoždění 2us
  • spodní stroboskop E

Čtení na 4bitové sběrnici:

  • ujistěte se, že je hlavní ovladač volný
  • pullup vstupní port dat
  • nastavte RS na 0 (příkaz) nebo 1 (data), v závislosti na tom, co čteme
  • R / W nastaveno na 1
  • zvýšit bránu E (nastavena na 1)
  • zpoždění 2us
  • četli jsme starší notebook
  • spodní stroboskop E
  • zpoždění 1us
  • zvýšit bránu E (nastavena na 1)
  • zpoždění 2us
  • četli jsme juniorský zápisník
  • spodní stroboskop E

Zvýšení stroboskopu a výstup příkazu / dat na sběrnici lze zaměnit. Nyní je snadné inicializovat displej. Abychom zjednodušili inicializaci, nahradíme čtení příznaku zaneprázdnění zpožděním a na práci s příznakem se podíváme později.
Je třeba poznamenat, že při inicializaci ve 4bitovém režimu se používají 4bitové příkazy a po inicializaci 8bitový příkazový systém, takže pro inicializaci implementujeme samostatnou funkci pro odesílání příkazů void Write_Init_Command (data uint8_t).
// Inicializační kód pro Atmega16 #define F_CPU 8000000UL #define LCD_PORT PORTA #define LCD_DDR DDRA #define LCD_PIN PINA #define DATA_BUS 0XF0 #define RS 0 #define RW 1 #define E 2 #include #zahrnout void Write_Init_Command (uint8_t data) (// nohy, kterými se příkazy / data přenášejí na výstup LCD_DDR | \u003d DATA_BUS; // pošleme příkaz LCD_PORT & \u003d ~ (1<Vesele blikající kurzor naznačuje, že inicializace byla úspěšná. V