A intra
Toate secretele computerului pentru începători și profesioniști
  • Jocuri și simulatoare despre tancuri pe PC (PC) - recenzie și descriere
  • Obțineți: bani de aur, nemurire mutantă
  • YAN Yandex Direct - ce este și cum să îmbunătățiți randamentele
  • Căști wireless Google Pixel Buds cu translator - recenzie Avantajele și dezavantajele căștilor wireless Google Pixel Buds, preț
  • Cum să faci o carte de vizită în Microsoft Word în diferite moduri?
  • Computerul se repornește singur - înțelegem motivele pentru care computerul se repornește constant, ce trebuie făcut
  • Program pentru interacțiunea dintre indicatorii PIC16 și LCD. Lucrul cu un LCD cu caractere bazat pe controlerul HD44780 Instalarea și inițializarea unui monitor LCD

    Program pentru interacțiunea dintre indicatorii PIC16 și LCD.  Lucrul cu un LCD cu caractere bazat pe controlerul HD44780 Instalarea și inițializarea unui monitor LCD

    Să luăm în considerare interacțiunea dintre un utilizator și un dispozitiv bazat pe microcontroler. De foarte multe ori utilizatorul trebuie să introducă informații cumva și să le citească din ceva. O tastatură și un afișaj () sunt foarte potrivite pentru aceste scopuri. Luați în considerare interacțiunea dintre utilizator și un dispozitiv bazat pe microcontroler. De foarte multe ori utilizatorul trebuie să introducă informații cumva și să le citească din ceva. Tastatura și afișajul () sunt foarte potrivite pentru aceste scopuri. În această notă, vom arunca o privire mai atentă la afișarea informațiilor pe un simbol LCD cu sintetizarea semnelor.

    Astfel de indicatori sunt adesea folosiți la proiectarea dispozitivelor digitale, așa că trebuie să știți cum să lucrați cu ele.
    Să luăm în considerare structura internă tipică a unei sintetizări de semne LCD:

    Structura internă a HD44780

    LCD-ul se bazează pe o matrice de cristale lichide, prin aplicarea de tensiune elementului căruia putem „aprinde” un punct de pe ecran. În cazul nostru, matricea este formată din spații familiare (cel mai adesea 8x5 pixeli), grupate pe mai multe rânduri. Toate acestea sunt gestionate de sistemul încorporat Controler HD44780. Controlerul are celule de memorie pe un singur octet ( DDRAM), al cărui conținut este de fapt afișat pe ecran conform tabelului înregistrat în CGRAM. De obicei, există mai multe celule de memorie decât cele familiare LCD, așa că trebuie să vă uitați la adresarea locurilor familiare din fișa de date. Adică trebuie doar să scriem codul caracterului dorit în poziția dorită și orice altceva HD44780 o va face singur.

    Pentru a selecta o poziție, există un cursor virtual (numărul celulei de memorie curente, AC), care poate fi controlat cu ajutorul comenzilor; cursorul poate fi făcut vizibil. În mod implicit, când scrieți un caracter într-o celulă, cursorul se deplasează înainte cu o poziție. Codurile de caractere pentru LCD susținerea chirilicei poate fi văzută în tabel:

    Tetrada înaltă a codului va fi egală cu rândul simbolului selectat, iar tetrada joasă va fi egală cu linia. Vă puteți crea propriul tabel de simboluri scriindu-l CGRAM. Fiecare caracter necesită 5 octeți, unde unii sunt responsabili pentru pixelii „aprinși”. De exemplu, numărul „8” este codificat ca 0x6c, 0x92.0x92.0x92.0x6c.
    Codurile de comandă sunt date în tabel.

    Tabel de caractere HD44780


    Semnificațiile steagului:


    Întrebarea rămâne deschisă: „cum se scrie codul simbolului necesar în poziția necesară?” Pentru a face acest lucru, să vedem de ce sunt responsabile concluziile. LCD. concluzii DB0-DB7 sunt responsabili pentru datele de intrare/ieșire. Un nivel ridicat la pinul RS lasă indicatorului să știe că semnalul la pini DB0-DB7 este date, iar low este o comandă. Concluzie W/R responsabil pentru direcția datelor, indiferent dacă datele sunt scrise în memorie sau citite din ea (de obicei citind din LCD nu este utilizat, îi putem aplica în siguranță un nivel scăzut). Impuls de ieșire E(cu o durată de cel puțin 500 ns) este utilizat ca semnal pentru scrierea/citirea datelor de la pini DB0-DB7, R.S.Și W/R.

    Concluzie V0 folosit pentru a seta contrastul imaginii, pinii A, K - pentru a alimenta lumina de fundal (dacă modelul dvs. o are LCD). Cei 2 pini rămași sunt sursa de alimentare reală LCD. Adică să controlezi LCD Vor fi necesari 8+1+1=10 pini. Dar puteți lucra în modul de interfață pe 4 biți. În acest caz, tetrada de comandă înaltă/date de pe pinii DB4-DB7 va fi transmisă mai întâi, iar apoi cea scăzută. Concluzii DB0-DB3 nu sunt folosite. În total, sunt necesari 6 pini de microcontroler pentru control.
    Acum să ne uităm la un exemplu viu. Să scriem un program pentru a scoate text "site-ul web" la ce am pe stoc WH1602A(2 rânduri de 16 caractere).

    Pentru alte LCD-uri, ar trebui să verificați corespondența celulelor DDRAM cunoștințe. Schema de conectare LCD la controler arată așa.

    Schema de conectare la microcontrolerul AVR


    Rezistor R3- 17 Ohm limitează curentul prin iluminarea de fundal și AC VR1 setează contrastul (dacă totul este conectat și programat corect, dar indicatorul este silențios, rotiți VR1 pentru ca imaginea să devină vizibilă). De asemenea, sub nicio formă nu trebuie confundată polaritatea. LCD, alimentați-l peste 5.5V, din experiența mea pot spune că ard instantaneu. Scopul tuturor celorlalte părți este același ca în
    Acum să trecem la scrierea programului. Pentru a controla indicatorul, vom scrie un program cu mai multe funcții cheie pentru a lucra LCD: lcd_dat(unsigned char x) – pentru scrierea datelor x, lcd_com(unsigned char x) – pentru scrierea comenzii x, lcd_init(void) – pentru inițializarea inițială a indicatorului:

      #include //Biblioteca de intrare/ieșire

    1. #define RS 2 //RS=PD2 - Semnal de control LCD

      #define E 3 //E=PD3 - Semnal de control LCD

    2. #define TIME 10 //Constantă de întârziere pentru LCD

      //Frecvența de tactare MK - 4 MHz

    3. //Program de generare a întârzierii

      void pauză (unsigned int a)

      ( nesemnat int i;

    4. pentru (i= a; i> 0; i--);

    5. //Program pentru transmiterea comenzilor către LCD

      void lcd_com (lcd char nesemnat)

      ( unsigned char temp;

    6. temp= (lcd& ~(1<< RS) ) | (1 << E) ; //RS=0 este o comandă

      PORTD= temp; //Trimite cea mai semnificativă tetradă a comenzii, semnalele RS, E către portD

      asm("nu");

      PORTD= temp& ~(1<< E) ; //Semnal de înregistrare de comandă

    7. temp= ((lcd* 16 ) & ~(1<< RS) ) | (1 << E) ; //RS=0 este o comandă

      PORTD= temp; //Ieșiți tetrada de ordin scăzut a comenzii, semnalează RS, E la portD

      asm("nu"); //Întârziere mică de 1 ciclu MK, pentru stabilizare

      PORTD= temp& ~(1<< E) ; //Semnal de înregistrare de comandă

    8. pauză (10 * TIMP) ; //Pauză pentru executarea comenzii

    9. //Program pentru scrierea datelor pe LCD

      void lcd_dat (lcd char nesemnat)

      ( unsigned char temp;

    10. temp= (lcd| (1<< RS) ) | (1 << E) ; //RS=1 este date

      PORTD= temp; //Trimit cele mai semnificative semnale de date tetrad, RS, E la portD

      asm("nu"); //Întârziere mică de 1 ciclu MK, pentru stabilizare

      PORTD= temp& ~(1<< E) ; //Semnal de înregistrare a datelor

    11. temp= ((lcd* 16 ) | (1<< RS) ) | (1 << E) ; //RS=1 este date

      PORTD= temp; //Ieșiți semnalele de ordin scăzut de date tetrad, RS, E la portD

      asm("nu"); //Întârziere mică de 1 ciclu MK, pentru stabilizare

      PORTD= temp& ~(1<< E) ; //Semnal de înregistrare a datelor

    12. pauză(TIME) ; //Pauză pentru ieșirea datelor

    13. //Program de inițializare LCD

      void lcd_init(void)

      lcd_com(0x2c); //Interfață cu 4 fire, dimensiune de caractere 5x8

      pauză (100 * TIMP) ;

      pauză (100 * TIMP) ;

      pauză (100 * TIMP) ;

    14. //Programul principal

      int main(void)

      DDRD= 0xfc ; //Inițializați portD

      PORTD= 0x00 ;

    15. pauză(1000);

      lcd_init() ; //Inițializarea LCD-ului

    16. lcd_dat("w"); //Ieșire „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("Eu"); //Scrie „Este atât de ușor”

      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. în timp ce (1) //ciclu fără sfârșit

    19. întoarcere 1;

    Programul este foarte simplu, nu va fi greu pentru oricine care are măcar puține cunoștințe să-l înțeleagă. C Pentru AVR. Pentru latină și numere ASCII codurile se potrivesc cu cele programate în generatorul de caractere LCD, prin urmare este permisă utilizarea lcd_dat('A'). Vă puteți crea propria bibliotecă pentru a lucra cu LCD-uri, separând funcțiile lcd_dat(unsigned char x), lcd_com(unsigned char x), lcd_init(void) într-un modul separat LCD.hși conectați-l după cum este necesar.

    Această idee economisește mult timp; trebuie să scrieți o singură dată funcțiile necesare și apoi să le folosiți tot timpul. Puteți, de asemenea, să rețineți că este incomod să scoateți o frază lungă câte o literă; pentru a face acest lucru, puteți împinge șirul nostru de ieșire într-o matrice de caractere nesemnate și îl puteți scoate folosind o buclă:

      int main(void)

      ( date char nesemnate [ 14 ] = ( "w" , "w " , "w " , " . " , " a " , " v " , " r " , " l " , " a " , " b " , " ." , "c" , "o" , "m" );

      nesemnat char i;

      DDRD= 0xfc ; //Inițializați portD

      PORTD= 0x00 ;

    1. pauză(1000); //Întârzie, astfel încât LCD-ul să aibă timp să se pornească

      lcd_init() ; //Inițializarea LCD-ului

    2. pentru (i= 0; i< 14 ; i++ ) //Trimite intrarea literă cu literă

      lcd_dat(data[ i] ) ;

    Nu uitați că numerotarea matricei în C începe de la zero. Programul existent poate fi utilizat împreună cu controlerul fără modificări semnificative ATtiny2313, conectarea LCD La PORTB, la fel de PORTD la ATtiny2313 are doar 7 pini, nu 8, ca ATmega8.

    De asemenea, recomand conectarea LCD folosind conexiuni detașabile. Este foarte convenabil când depanați un program când trebuie să afișați niște date intermediare. Am conectat un conector și asta a fost tot. În continuarea acestei note, în viitorul apropiat voi lua în considerare afișarea informațiilor citite pe LCD.
    O zi buna tuturor ;)

    există un mic defect în acest exemplu

    Există un mic defect în acest exemplu, poate din acest motiv exemplul nu funcționează pentru mulți!

    În general, exemplul este laconic și simplu, așa că micul defect nu atrage atenția (pentru cei care sunt familiarizați cu limbajul „C”) și cu atât mai mult pentru cei care tocmai se familiarizează cu AVR și „C”. ” limbaj, poate că sunt chiar perplexi de cum s-a întâmplat... .ei scriu, fac așa și va fi ca în poză....dar nu este cazul...

    În general, întreaga problemă este cu ciclurile de întârziere, astfel încât afișajul ține pasul cu controlerul, și anume în funcția -

    //Program de generare a întârzierii

    void pauză (unsigned int a)

    ( nesemnat int i;

    pentru (i=a;i>0;i--);

    totul pare să fie corect la prima vedere, dar compilatoarele pentru microcontrolere se străduiesc să optimizeze codul pentru compactitatea maximă a imaginii rezultate din memoria flash a programelor... și nu văd niciun sens într-o buclă goală și, în consecință, mai jos în lanț după ea: toate apelurile, declarațiile de constante și tot ce este legat de această funcție este lipsită de sens în opinia lui... pur și simplu o elimină din cod în timpul asamblarii...

    cel puțin acest lucru este valabil pentru atmel studio 6.1 și puteți verifica acest lucru uitându-vă la folderul proiectului, există un fișier *.lss care conține codul de asamblare al acestui program, generat la construirea proiectului. nici un indiciu despre implementarea funcției void pauză...

    ca urmare, la clipirea firmware-ului controlerului, display-ul ajunge cu gunoi aleatoriu sau gol... cand apasati reset de mai multe ori gunoiul poate sa dispara si sa reapara... este evident ca procesorul si ecranul sunt iesite sincronizare

    dar dacă faci o mică corectare

    void pauză (unsigned int a)

    ( nesemnat int i;

    pentru (i=a;i>0;i--)
    asm("nu");

    Apoi, pentru compilator, acest lucru are sens, acest lucru este confirmat și de aspectul evident al implementării funcției în codul de asamblare

    0000006c
    :
    6c:9c 01 movw r18, r24
    6e: 03 c0 rjmp .+6 ; 0x76
    70:00 00 nop
    72: 21 50 subi 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

    si cel mai probabil totul va merge....cel putin la mine pe atmega16 (sincronizare RC interna 1Mhz) si folosind atmel studio 6.1 exact asa a fost...poate la alte frecvente va trebui sa te joci cu #define TIME 10 constantă și/sau valorile transmise funcției void pauză

    aici-> pauză(valoare) ...sau pauză(valoare*TIME) ....

    Succes în învățarea cum să operați AVR-ul!

    Uite, imaginează-ți că LCD-ul...

    Uite, imaginează-ți că LCD-ul este o mașină de scris, hârtia din mașină de scris este memoria LCD, căruciorul este indicatorul cursorului. În plus, LCD-ul nu afișează întregul conținut al memoriei, ci doar o parte. Pare un fel de fereastră pe care am instalat-o pe hârtie cu text.

    Aici I/D determină modul în care vom imprima, de la dreapta la stânga sau de la stânga la dreapta.
    S determină dacă vom muta fereastra ecranului pe măsură ce scriem sau nu.
    S/C - pur și simplu mută fereastra ecranului vizibil sau căruciorul mașinii de scris.
    R/L - specifică unde (stânga sau dreapta) vom muta ecranul sau cursurile folosind steag S/C.

    Cred că ceva lipsește!

    Ți-am smuls programul și proteus și nu voi începe pe mega8. Ecranul este tăcut, am început să caut prin fișele tehnice și iată ce am găsit:
    Ceea ce lipsește este inițializarea primelor trei!

    0011 - așteptați 5 ms
    0011 - așteptați 100 µs
    0011 - așteptați 2 ms
    0010 - așteptați 41 µs
    0000 - -și-
    0010 - -și-
    1000
    0000
    1000
    0000
    0001
    0000
    0100

    corectează-mă daca greșesc!

    Nu funcționează!

    Am încercat să schimb frecvențele de ceas, întârzierile în timpul inițializării și ieșirea simbolurilor (comenzilor), până acum fără succes. În ceea ce privește siguranțele, dacă doriți să configurați pinii portului D folosind DDRB, PORTD se înregistrează ca ieșiri jurnal scăzute. nivel, apoi am făcut-o.
    Neavând altceva de făcut, am compilat un program simplu de ieșire a simbolurilor folosind instrumentele CodeVisionAVR, l-am pus în PROTEUS - funcționează!... dar cu un LCD adevărat refuză..

    Nu, vorbesc despre asta

    Nu, vorbesc despre încercarea de a pune o lumină intermitentă pe portul D, de exemplu, sau doar să aprindeți întregul port deodată. Când am cumpărat doar un microcontroler, nu am putut face asta. Am scotocit pe forumuri si s-a dovedit ca sigurantele sunt cumva programate acolo si ca portul D si toti cei 8 biti ai lui nu sunt porniti. Verificați acest punct, sau mai bine, încercați să mutați LCD-ul pe alt port, de exemplu pe B. Faptul că programul funcționează în Proteus dar nu cu cel real este diferența dintre parametrii LCD-ului înfundat în Proteus și cel adevarat.

    Nu funcționează!

    Am asamblat și conectat totul conform diagramei, doar MK a folosit ATmega16 și LCD WH1602M și, în consecință, a compilat firmware-ul pentru acesta în WinAVR. Totuși, LCD-ul a refuzat să scoată ceva, l-am colectat și în Proteus (pe ATmega 8 și LM016L), datele de la MK sunt scoase dar nu se vede nimic pe LCD. Care ar putea fi problema? (Dacă acest lucru este important, utilizați oscilatorul RC intern pentru a tasta la 1 MHz)

    1. Pentru Atmega16 ai nevoie

    1. Pentru Atmega16, trebuie mai întâi să porniți siguranțele pentru ca portul D să funcționeze.
    2. Încercați să schimbați frecvența ceasului la 4 MHz și 8 MHz. Întreaga problemă cu LCD-ul este că toate pauzele nu sunt menținute în timpul inițializării sau la emiterea unei comenzi. Și controlerul LCD este foarte sensibil la asta.

    Am o întrebare:
    Am asamblat un circuit de cronometru pe Mega 8 cu un hex gata făcut - citirile sunt afișate pe WH0802,
    indicația este un număr de trei cifre care sunt afișate pe întregul ecran, o cifră este formată din 4 caractere. Ecran pseudo-grafic. Cum se poate scrie firmware-ul??
    Autorul refuză categoric să furnizeze codul sursă și nu comentează lucrarea, probabil din motive de „proprietate intelectuală”.
    În timpul meu liber vreau să încerc să-mi scriu propriul firmware în scopuri educaționale.

    Am dat peste asta

    Am dat peste această situație.
    Există două ecrane LCD 16x2:
    1 - MTC-S16204XFGHSAY
    2 - WH1602A-YGH-CTK

    Pe primul îl folosesc într-un proiect cu GPS.
    Am decis să îl folosesc pe al doilea într-un proiect cu tastatură. Dar din anumite motive, LCD-ul nu funcționează.
    Contrastul este ajustat și apar pătrate. Asta e tot.
    Poate că există o altă ordine de inițializare.
    Ajută-mă să înțeleg
    Iată fișele tehnice
    filebox.od.ua/?file=24a31fc50d62bfcd658bdadac84088ab

    Afișajele nu sunt diferite.

    Afișajele nu sunt diferite. Pinout-ul este același. Timpurile variază ușor. Încercați să creșteți întârzierea la trimiterea comenzilor către LCD sau să reduceți frecvența microcontrolerului.

    Toate ecranele LCD de pe HD44780 au un sistem de comandă identic. Ce interfață folosești, pe 4 sau pe 8 biți? De asemenea, încercați să creșteți întârzierea dintre pornirea LCD-ului și inițializare, la aproximativ 0,1s. Polaritatea sursei de alimentare pentru LCD nu este amestecată, au nevoie de puțin pentru a se arde? Am ars-o prostește și apoi am încercat să-l conectez. Au fost afișate și pătrate negre, datele au fost afișate de fiecare dată, adică. a lucrat extrem de instabil.

    Folosesc programe din articole

    Folosesc programe din articole despre GPS.
    interfață pe 4 biți

    Am incercat programul de aici
    chipenable.ru/index.php/programming-c/75-chasy-na-mikrokontrollere.html

    a mers

    Ce ar trebui să schimbi în programul tău?

    Atenție la întârzieri

    Atenție la întârzierile după emiterea comenzilor de inițializare și configurare, acesta poate fi cazul. Am avut și un caz similar, dar controlerele erau ambele la fel, iar programul a funcționat doar pe unul.

    Analogii HD44780

    Am întâmpinat o problemă - nu găsesc LCD-ul WH1602A la un preț rezonabil. De exemplu
    în chipdip acestea sunt disponibile chipdip.ru/product/wh1602a-ygh-ct-k.aspx
    700 de lemn. Ce este YGH în numele „WH1602A-YGH-CT(K), LCD 16x2, engleză-rusă”
    Ce analogi de LCD-uri bazate pe HD44780 există? Am găsit pagina micronika.ru/order.phtml?vid=64 - acolo numele FDCC1602A-FSBFBW-51SR conține 1602A,
    Tocmai am observat. Poate că FDCC1602A-FSBFBW-51S va funcționa fără multe schimbări de cod?
    Ce probleme pot apărea la utilizare
    nu HD44780 real de la Hitachi, ci analogii lui?
    PS Nu ar fi o idee rea să citiți despre utilizarea diferitelor LCD-uri, analoge ale HD44780, decât cele MELT.
    LCD-urile sunt proaste

    În acest articol voi da un exemplu de una dintre opțiunile de inițializare a unui indicator alfanumeric cu cristale lichide pe platforma de controler HD44780 sau KS0066 pentru programatori începători în limbaj de asamblare în raport cu microcontrolerele PIC16.

    Acest program face parte din programul pentru contorul de temperatură și umiditate descris în articolul „”. Pentru confortul de a lucra cu articolul și fișierul sursă al programului, este mai bine să descărcați mai întâi proiectul, să imprimați fișierul sursă și să-l puneți în fața dvs. Când scrieți un program pentru a inițializa un afișaj LCD, a scrie comenzi și a afișa simboluri pe indicator, este mai bine să utilizați macrocomenzi create în acest scop. Să ne uităm la ecran.

    După directivele de înlocuire a textului, apar macro-uri - programe mici care pot fi accesate din programul principal cât de mult doriți, în orice moment. Prima macro, impuls_E, asigură recepționarea unui impuls de gate pe linia E, liniile de gate și sincronizare. Linia 14 – setează una logică pe linie, prin două pseudo-comenzi NOP, linia 17 – setează un zero logic. Astfel, primim un impuls pozitiv pe linia E cu o durată de 2 μs la o frecvență de oscilator cu cuarț de 4 MHz. Următoarea macrocomandă este Load_Znak. Ne permite să încărcăm codul simbolului în registrul DR pentru a-l afișa pe indicator. Veți observa că în această macrocomandă există un apel către o altă macrocomandă scrisă mai jos. Să ne uităm la macrocomanda send_LCD. Linia 26 – citiți conținutul registrului Write_data, i.e. codul personajului care ar trebui să fie în el. Linia – 27, schimbați nibble-urile înalte și joase ale registrului. Linia – 28, selectăm ciugulirea înaltă a codului caracterului, care este deja în ciugulirea scăzută, și trimitem aceste date în portul B. Faptul este că înregistrarea datelor în modul de operare pe 4 biți al controlerului indicator are loc secvenţial, mai întâi ciugulirea înaltă a registrului, apoi junior - linia 31... 33. După transmiterea unui ciugulit, trebuie generat un impuls stroboscopic. Aceasta este ceea ce vedem, liniile 30 și 34. Pentru ca controlerul de afișare să proceseze informațiile, a fost introdusă o întârziere de 200 de microsecunde în macro. După macrocomenzile pe care le-am creat, există o procedură standard de inițializare a microcontrolerului. În articolul „” am vorbit despre principalele proprietăți ale afișajelor LCD și am atins subiectul creării propriilor simboluri. După cum am spus mai devreme, nu există un simbol de grad în indicatorii mei. Așa că îl vom încărca în generatorul de caractere al indicatorului. Pentru a face acest lucru, vom scrie o mică subrutină, care ar trebui să fie situată în spatele procedurii de inițializare a microcontrolerului și înaintea programului principal.Subrutina începe pe linia 69, unde introducem codul de adresă în zona CGRAM, 40h - primul utilizator adresa va fi stocată la această adresă. Uită-te la captura de ecran 2.

    Deoarece fiecare caracter ocupă opt registre de memorie, următorul caracter pe care îl creăm va începe la adresa 40h + 08h = 48h. Următorul este 48h + 08h = 50h. Nu uitați că adunarea are loc în sistemul numeric hexazecimal. Și așa, liniile 69 și 70 – se încarcă adresa de pornire a simbolului. Urmează înregistrarea alternativă a opt octeți ai codului de caractere. Vom lua codul simbolului gradului din programul LCDCC.

    Va trebui să repetăm ​​puțin ceea ce a fost în articolul „Indicatori alfanumerici cu cristale lichide”. Să ne uităm la captura de ecran a acestui program. Făcând clic pe celulele matricei, desenăm simbolul dorit, în acest caz este o pictogramă de grad simbolică. Mai jos, programul scrie imediat coduri pentru punctele selectate ale matricei. Acum trebuie să scriem aceste coduri în controlerul indicatorului. Asta am făcut. Acum am ajuns la inițializarea indicatorului în sine. Uită-te la captura de ecran 3.

    Înainte de inițializare, de exemplu, vom scrie date în registre pentru a trimite valori la indicator. Să introducem, de exemplu, o valoare a temperaturii de 21,7 grade. Apoi vom crea un proiect în Proteus și vom vedea cu ce găsim. Asa de. Captura de ecran 3, rândurile 88... 93 – scrierea numerelor în registre. Inițializarea începe cu eticheta InitLCD, așa cum era de așteptat, așteptăm cel puțin 15 ms. După o pauză, liniile 98... 100, scrieți numărul trei în registrul Reg_3 - acesta va fi de câte ori este transmisă comanda 30h = b’0011 0000’ (30h). Și scriem trei în registrul portului B, pentru scrierea ulterioară în controlerul indicator, acest număr trei se află în jumătatea de octet înalt al comenzii. Formăm un impuls stroboscopic, linia 102, pauză de 5 ms. Revenim la eticheta Setloop. Trimitem comanda până când registrul Reg_3 este resetat, adică. de trei ori. După transmiterea acestei comenzi, controlerul indicator va fi gata de funcționare, dar în modul de 8 biți. Acum să trecem la modul pe 4 biți. Pentru a face acest lucru, vom trimite comanda 20h. Rețineți că comenzile sunt scrise în controlerul indicatorului în modul pe 4 biți. Deci, avem comanda 20h sau 0010 0000. Deoarece în modul de 4 biți comenzile sunt transmise în două etape, mai întâi datele celei mai semnificative nibble a registrului, le introducem pe cele două în registrul portului B și le scriem în controler indicator și, deoarece cea mai de jos ciugulire este goală, atunci nu transmitem nimic.

    După ce scriem 2 în portul B, facem stroboscop pe linia E și facem o pauză de 200 us. Acum indicatorul va funcționa în modul cu 4 cifre. Următoarea comandă este comanda pentru a seta modul de operare - două linii, font - 5x7. Cod de comandă 28h. Urmează comanda 0C pentru a porni indicatorul. Ei bine, atunci cred că o să-ți dai seama. Da, un pic mai mult. În Proteus, simbolul pictogramei de grad pe care l-am creat nu este afișat corect; afișează două puncte, deși în realitate totul funcționează bine. Să ne uităm la fotografie. Noroc.

    Astăzi, indicatoarele LCD cu cristale lichide simbolice sunt din ce în ce mai folosite pentru a afișa informații simbolice simple. Vom vorbi despre cum să lucrăm cu ei. În această parte a articolului, vom arunca o privire detaliată asupra ecranelor LCD cu caractere bazate pe controlerul HITACHI HD44780 (sau SAMSUNG KS0066 compatibil). Articolul este o încercare de a sistematiza informațiile pe care le-am găsit când lucram cu aceste LCD-uri.

    LCD cu caractere cu controler HD44780 (KS0066). Interfață

    Un LCD cu caractere nu este altceva decât o matrice de puncte, împărțită în linii și câmpuri de caractere:

    Un controler special este folosit pentru a controla această matrice și a scoate caracterele reale.

    HD44780 (și compatibilul său KS0066) este standardul de facto pentru controlerele afișajelor LCD monocrome care sintetizează caractere cu o interfață paralelă pe 4 sau 8 biți. Pe baza acestui controler, sunt produse un număr mare de modele cu design și rezoluții diferite, începând de la 8x1 (opt caractere pe o linie) și terminând cu 40x4 (conținând două cipuri de control independente). Frecvența de funcționare tipică a controlerului este de 270 kHz.

    Controlerul LCD funcționează cu 3 blocuri de memorie:

    1. Controlerul folosește memoria pentru a scoate un caracter DDRAM(Display Data RAM), unde sunt stocate codurile ASCII ale caracterelor pe care vrem să le vedem pe LCD. Pentru aceasta sunt alocate 80 de celule de memorie. Este clar că pe LCD vom vedea doar o parte din caracterele care sunt în DDRAM - dacă LCD-ul nostru are 1 sau 2 rânduri și afișează 8 caractere pe linie, atunci așa:

    Zona de lucru a afișajului, după cum puteți vedea, poate fi deplasată de-a lungul celulelor DDRAM (obțineți un efect de linie târâtoare).

    2. Controlerul preia șabloanele simbolurilor în sine de la CGROM(Character Generator ROM) – memorie generator de caractere. Tabelul cu simboluri poate fi găsit în specificațiile pentru HD44780.

    3. Memoria este furnizată pentru stocarea simbolurilor utilizatorului (șabloanele acestora) CGRAM(RAM generator de caractere).

    De asemenea, operatorul, în funcție de anumite condiții, distribuie datele primite în el registrul de instrucțiuni sau registrul de date.

    Interfață tipică de controler HD44780 cu 14 pini:

    Pământ, comun, GND

    Tensiune de alimentare, Vcc (+5V)

    Ajustarea contrastului (Vo)

    Selecție de înregistrare (R/S pentru HD44780, A0 pentru KS0066)

    Citire/Scriere (R/W)

    Strobe la cădere E (Activare)

    Bit 0 (minor pentru interfața pe 8 biți)

    Linie de date

    DB 4 (minor pentru interfața pe 4 biți)

    DB 7 (înalt pentru interfața de 8 (4) biți)

    Pentru display iluminat din spate

    Putere de iluminare de fundal pentru ecrane iluminate din spate (anod)

    Putere de iluminare de fundal pentru afișaje cu iluminare din spate (catod)

    Ne uităm la numerotarea pinii de pe un anumit LCD din fișa de date.

    Contrastul imaginii de pe LCD poate fi modificat prin conectarea unui rezistor suplimentar de reglare de 10 kOhmi conform următoarei diagrame:

    Dar, ar trebui să vă uitați la specificațiile controlerului dvs. (de exemplu, LCD-ul Klsn10294v-0 de pe cipul KS0066 are 1-Vcc și 2-GND). Sursa de alimentare cu iluminare de fundal poate varia de la model la model, în funcție de tipul acesteia. De obicei, lumina de fundal este alimentată de 5 volți; un rezistor de limitare a curentului (50-100 ohmi) este de obicei opțional.

    Alocarea pinului R/S, R/W, E:

    Când E trece de la un log ridicat. date de la nivel la scăzut care sunt deja „atârnate” pe terminale DB0..DB7, sunt scrise în memoria controlerului LCD pentru procesarea ulterioară.

    La buștean înalt. nivel la R/S (Selectare registru), controlerul LCD percepe acest set de biți ca date (cod caracter), iar la un nivel scăzut – ca o instrucțiune și îi trimite la registrul corespunzător.

    R/W determină direcția de funcționare a pinii DB0..DB7 - dacă R/W este „0”, atunci putem scrie doar în portul DB, iar dacă R/W = „1”, atunci putem citi din el (de exemplu, aflați dacă controlorul este ocupat sau este liber să primească date noi). Dacă nu citim datele de pe LCD, atunci putem „planta” R/W pe sol.

    Set de instrucțiuni HD44780

    Pentru a începe afișarea informațiilor pe LCD, controlerul acestuia trebuie să fie inițializat (informați-l despre interfață, font, offseturi etc.). Controlerul poate accepta un total de 11 comenzi:

    Numele instrucțiunilor

    Starea PIN

    Timpul de finalizare

    f sclav =270 kHz

    Ștergerea întregului LCD și setarea adresei DDRAM la 0

    Setarea adresei curente DDRAM la 0 (cursor - home) datele DDRAM nu se modifică

    Setarea direcției de mișcare a cursorului (I/D) și a deplasării afișajului (S) la ieșirea datelor

    Control pornire/oprire afișaj

    Pornit oprit. afișaj (D), cursor (C) și pâlpâirea acestuia (B)

    Cursorul sau deplasarea afișajului

    Mută ​​cursorul și mută afișajul pe DDRAM

    Setarea interfeței (DL), a numărului de linii (N) și a fontului caracterelor (F)

    Setați adresa CGRAM

    Setarea contorului de adrese CGRAM. După aceasta, puteți scrie date în CGRAM

    Setați adresa DDRAM

    Setarea contorului de adrese DDRAM

    Citiți steag și adresa ocupat

    Dacă BF = 1, atunci controlerul LCD efectuează o operație internă (ocupat). AC6-AC0 – valoarea curentă a adresei DDRAM

    Scrieți date în RAM

    Scrierea datelor pe RAM

    Citiți datele din RAM

    Citirea datelor din RAM

    I/D = 1: Crește adresa DDRAM I/D = 0: scade
    S = 1: deplasarea zonei de lucru a afișajului prin DDRAM este permisă
    D = 1: afișaj (imagine) pornit
    C = 1: cursorul activat
    B = 1: Cursorul intermitent activat

    S/C = 1: mutarea afișajului S/C = 0: mutarea cursorului
    R/L = 1: dreapta R/L = 0: stânga

    DL=1:8 biți DL=0:4 biți
    N=1:2 linii N=0:1 linie
    F = 1: 5x10 F = 0: 5x8

    ACG:Adresă CGRAM
    ADD: adresa DDRAM (adresa cursorului)
    AC: Contor de adrese adrese DD și CGRAM

    Inițializare LCD

    Există 2 moduri de a inițializa controlerul LCD:

    1. Prin circuitul intern de resetare.

    2. În modul manual (prin trimiterea unui număr de comenzi către acesta, cu care setăm modul de funcționare al LCD-ului)

    Circuitul intern de resetare al controlerului începe să funcționeze imediat după ce alimentarea este pornită. Există un dezavantaj în acest sens - dacă puterea noastră „se strecoară” la nivelul de funcționare lent (mai puțin de 10 ms), atunci auto-inițializarea controlerului poate să nu decurgă corect. Cu această metodă de inițializare, controlerul însuși execută următoarele comenzi:

    1.Afișaj clar

    2.Set de funcții:
    DL = 1; date de interfață pe 8 biți
    N = 0; Afișaj cu 1 linie
    F = 0; font de caractere 5x8 puncte

    3.Control pornire/oprire afișaj:
    D = 0; Afișaj oprit
    C = 0; Cursorul oprit
    B = 0; clipind

    4. Setarea modului de intrare:
    I/D = 1; Crește cu 1
    S = 0; Nici o schimbare

    A doua metodă elimină dependența circuitului de sursa de alimentare. Pentru a inițializa controlerul LCD în modul manual, trebuie să efectuați următorul algoritm:

    După cum puteți vedea, nu este nimic complicat aici: trimitem comandă după comandă către LCD, ținând cont de timpul lor de execuție (aproximativ 40 μs) sau verificând steag-ul de ocupat al controlerului LCD (apoi trebuie să punem pinul RW pe piciorul microcontrolerului și setați-l la „1” atunci când vrem să aflăm dacă LCD-ul este ocupat sau nu).

    Asta, de fapt, este tot ceea ce privește teoria lucrului cu LCD-uri simbolice. Dacă ați omis ceva sau ați făcut o greșeală, citiți specificațiile pentru controler sau .

    În a doua parte, vom lua în considerare implementarea hardware și software a comunicării dintre un microcontroler PIC și un LCD.

    De ceva timp, acest afișaj a rămas inactiv.


    Și acum există dorința de a-l atașa la unul dintre proiecte; puteți, desigur, să încercați să găsiți o bibliotecă cu funcții gata făcute, dar în acest caz imaginea modului în care funcționează afișajul va fi incompletă, iar acest lucru nu nu ne convine. Odată ce ați înțeles principiul de funcționare al unui afișaj LCD, nu va fi dificil să vă scrieți propria bibliotecă pentru afișajul dorit dacă acesta lipsește sau nu este satisfăcător într-un fel.

    Deci, să începem.
    Primul lucru de făcut este să găsiți pinout-ul, adică care contact este responsabil pentru ce, al doilea este să găsiți numele controlerului care controlează afișajul, pentru a face acest lucru, descărcați fișa de date pentru acest LCD și deschideți-o pe prima pagină.


    Contactele sunt numărate de la stânga la dreapta, prima este marcată cu o săgeată roșie. Tensiunea de alimentare este de 5 volți, controlerul de control S6A0069 sau similar, de exemplu, ks0066U.

    De ce căutam numele controlerului de control? Faptul este că în fișa de date de pe afișaj există întârzieri (diagrama de timp), sistemul de comandă este descris, dar nu există o inițializare banală și fără ea nu există nicăieri.
    Apoi, deschideți a doua pagină și vedeți un tabel care spune care contact este responsabil pentru ce.


    DB7...DB0– magistrală de date/adresă.

    R/V- determină ce vom face, citim (R/W=1) sau scriem (R/W=0)

    R/S– determină dacă vom trimite o comandă (RS=0) sau date (RS=1)

    E– intrare strobe, prin schimbarea semnalului la această intrare permitem afișajului să citească/scrie date.

    LED±– controlul luminii de fundal.

    Trebuie să spun că pe afișajul primit, lumina de fundal nu se va aprinde doar; pentru a face acest lucru, trebuie să lipiți un rezistor, marcat pe placă ca R7. Dar deocamdată nu avem nevoie.

    Descărcați fișa de date pentru controlerul de control și găsiți instrucțiunile de inițializare. Pozele pot fi mărite făcând clic pe ele.



    Se pare că există două astfel de instrucțiuni, pentru modurile pe 8 și 4 biți. Ce fel de moduri sunt acestea? Aceste moduri determină câte fire de date vor fi transmise: patru sau opt. Să ne uităm la transmisie 4 fire, în acest caz, afișajul va funcționa mai lent, dar vom salva 4 pini ai microcontrolerului, iar implementarea modului pe opt biți nu este mult diferită.

    Schema de conectare a informațiilor este următoarea.


    Contrastul poate fi reglat prin conectarea unui potențiometru între pinii de alimentare.

    Aș dori să vă atrag atenția asupra faptului că în timpul inițializării R/SȘi R/V sunt întotdeauna egale cu zero, adică vom trimite echipe.

    În timpul inițializării puteți configura:

    • N - numărul de linii afișate
    • C - pornește sau dezactivează cursorul
    • B - faceți cursorul să clipească
    • I/D - crește sau micșorează valoarea contorului adresei
    • SH - mutați fereastra de afișare
    Să ne uităm la ultimele două puncte mai detaliat.
    Imaginea de mai jos arată la ce adresă trebuie să scriem datele astfel încât acestea să fie afișate într-o anumită poziție, de exemplu, dacă dorim să afișăm un simbol pe prima pozitie a liniei a doua, atunci trebuie să scriem la adresa 0x40.


    După aceasta, valoarea contorului se va schimba automat, fie crește, fie scădea, iar odată cu aceasta se va schimba și poziția cursorului.

    Apropo, se numește memoria căreia îi scriem DDRAM, tot ce scriem în această memorie va fi afișat pe afișaj, mai există CGROM, care stochează tabelul generator de caractere.


    Acest tabel nu poate fi schimbat, dar simboluri gata făcute pot fi luate din el. Un alt tip de memorie este CGRAM, este și un tabel generator de caractere, dar personajele din acest tabel le desenăm noi înșine.


    Acum câteva cuvinte despre mișcarea ecranului, adevărul este că de obicei pe afișaj nu vedem toată DDRAM-ul, ci doar o anumită parte, așa cum se arată în imaginea de mai jos.


    Putem scrie și în partea invizibilă, dar ceea ce scriem nu va fi vizibil până când nu mutăm fereastra ecranului în acest loc.

    Am terminat cu teoria, să trecem la practică.
    Imaginea comunicării cu un afișaj LCD în modul pe 4 biți arată astfel.


    Datele sunt trimise în octeți, dar întrucât avem un mod pe 4 biți, pentru a trimite un octet trebuie să faceți 2 trimiteri, cu bitul cel mai semnificativ mai întâi. În imagine, primul pachet este desemnat D7 (tetradă înaltă), al doilea D3 (tetradă scăzută). Înainte de următoarea trimitere, trebuie să verificăm steag-ul de ocupat și dacă nu este setat, putem trimite din nou; dacă este setat, așteptăm până când controlerul care controlează LCD-ul își termină activitatea.

    Având o imagine generală a trimiterii, să ne dăm seama cum să implementăm operația de trimitere.


    Pentru a trimite trebuie să utilizați o magistrală de 8 biți:
    • R/W setat la 0
    • emite codul de comandă/date către magistrală
    • intarziere 2us
    • stroboscopul inferior E

    Operația de citire este implementată în mod similar:

    • asigurați-vă că controlerul este liber
    • R/W setat la 1
    • ridicați strobe E (în acest moment, LCD-ul va scoate date către magistrală)
    • intarziere 2us
    • citim ce a dat LCD-ul
    • stroboscopul inferior E
    De unde a apărut întârzierea 2us?

    Deasupra timpilor există un tabel care spune cu ce sunt egale întârzierile afișate pe grafic și astfel durata pulsului stroboscopic - tw ar trebui să fie egală cu 230nS sau 450nS în funcție de tensiunea de alimentare, am luat-o puțin cu o marginea. De ce am ținut cont doar de această întârziere? Pentru că valoarea întârzierilor rămase este foarte mică.

    Pentru a trimite printr-o magistrală pe 4 biți:

    • asigurați-vă că controlerul este liber
    • setați RS la 0 (comandă) sau 1 (date), în funcție de ceea ce vom trimite
    • R/W setat la 0
    • ridicați stroboscopul E (setat la 1)
    • eliberăm cel mai înalt caiet pentru autobuz
    • intarziere 2us
    • stroboscopul inferior E
    • întârziere 1us
    • ridicați stroboscopul E (setat la 1)
    • emitem tetrada joasă autobuzului
    • intarziere 2us
    • stroboscopul inferior E

    Pentru a citi pe un autobuz pe 4 biți:

    • asigurați-vă că controlerul este liber
    • port de date pentru intrare cu pull-up
    • setați RS la 0 (comandă) sau 1 (date), în funcție de ceea ce vom citi
    • R/W setat la 1
    • ridicați stroboscopul E (setat la 1)
    • intarziere 2us
    • citește caietul seniorului
    • stroboscopul inferior E
    • întârziere 1us
    • ridicați stroboscopul E (setat la 1)
    • intarziere 2us
    • citim caietul de jos
    • stroboscopul inferior E

    Ridicarea stroboscopului și transmiterea comenzii/datelor către magistrală pot fi schimbate. Acum nu va fi dificil să inițializați afișajul. Pentru a simplifica inițializarea, vom înlocui citirea indicatorului de ocupat cu o întârziere și vom lua în considerare lucrul cu steag-ul mai târziu.
    Trebuie remarcat faptul că în timpul inițializării în modul de 4 biți se folosesc instrucțiuni de 4 biți, iar după inițializare se utilizează un sistem de instrucțiuni de 8 biți, așa că pentru inițializare implementăm o funcție separată pentru trimiterea comenzilor void Write_Init_Command (date uint8_t).
    //Cod de inițializare pentru 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 #include void Write_Init_Command(uint8_t data) ( //picioare prin care comenzile/datele sunt transmise către ieșirea LCD_DDR |= DATA_BUS; // vom trimite comanda LCD_PORT &= ~(1)<Un cursor care clipește vesel indică faptul că inițializarea a avut succes. ÎN