Sari la conținut
ELFORUM - Forumul electronistilor

Afisare LCD


mitescu

Postări Recomandate

Am observat ca exista o oarecare preocupare catre afisarile grafice pe LCD-uri.

La: http://www.mikrocontroller.net/topic/25099#new se afla un amplu material pentru asa ceva.

M-a preocupat si pe mine problema.

Pentru un LCD de tipul LCM5328, care are 680x(RGB)x480 am increcat sa aplic solutiile celor de mai sus care sunt bune, dar au cateva deficiente atat de natura hard cat si soft. Astfel interfata RS232 este destul de lenta si nu se pot transfera date in timp real.

Daca se conecteaza la USB si se incearca viteze de peste 230400 baud , apar proble(cel putin la mine), si oricum viteza este prea mica (aprox. 30KB/s).

Solutiile pe care le-am gasit ca fiind acceptabile sunt doua:

- modul de transfer paralel - viteze de pana la 1MB/s

- modul de transfer pe SPI - viteze de pana la 400KB/s

Din punct de vedere soft, modificarea pe care am facut-o se refera la scanarea unei linii de la LCD pe intreruperea T0Ovf, de cca 88us, dar se poate urca pana la cca.50us, lasand astfel programul sa acceseze transferurile catre memorie, afisarea devenind astfel "transparenta".

Pentru conformitate, am lasat si modul de transfer asicron.

In attach am pus schema si un monitor in hex, ce face scanarea si cateva comenzi de la USART. De asemena am pus si rutina de intrerupere.

Pentru cei ce doresc sa-si construiasca asa ceva (la solicitare) pot veni si cu alte amanunte si pentru modurile de transfer si/sau modurile de comanda alfa si grafic.

Link spre comentariu
  • 2 săptămâni mai târziu...
  • Răspunsuri 60
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • mitescu

    31

  • ole

    21

  • sofian

    1

  • danzup

    1

Top autori în acest subiect

Foarte interesant proiectul !Acum un an m-a gandeam sa fac si eu ceva asemenator : facusem un card ISA pe busul calculatorului care scria intr-o memorie , pe care o citea un atmega8515 care varsa datele in LCD .Din pacate nu am mai terminat sau finalizat proiectul ....Ne dai mai multe amanunte ?Transferul paralel cum il faci ( nu partea de microcontroler ! ) ?Ai scris un driver ?Banuiesc ca faci transferul de pe un pc .... cum ?

Link spre comentariu

Schema adoptata este (asa cum am mentionat) adaptata dupa cea de la:

http://www.mikrocontroller.net/topic/25099#new

LCM 5328-22NTK , are impartita zona de afisare in doua sectoare

- primul este cel superior 640x(RGB)X240

- al doilea , cel inferior tot 640x(RGB)X240

dac facem socoteala la memoria necesara rezulta

640 x 3 x 2 x 240 = 921600 biti

640 : nr.col pe H

3 : RGB

2 : sectoare

240 : nr.linii/sector

ceea ce insemna 921600/8=115200 octeti

Rezulta o memorie RAM (necesara) de 128KB

ATMega8515 nu poate adresa in mod direct decat 64KB, din acest motiv, am paginat zona de memorie in doua pagini de cate 64KB, gestionate de semnalul generat prin soft numit A16 La trecerea dintr-o pagina in alta softul are grija sa schimbe acest semnal.

Scrierea/citirea in/din RAM se face prin alegerea paginii(A16) si selectia unuia dintre cele doua buffere bidirectionale IC2,IC4 (74HC245) , corespunzatoare paginii respective.

Deci selectia se face cu A16 si unul din semnalele RD(read) sau WR(write),circuitele IC6A, IC6B, IC5A, IC5D

Directia cu este data de semnalul RD.

Pentru scriere in RAM se utilizeaza semnalele WU si WL care sunt date de WR si A16 respectiv /A16 (negat)cu circuitele IC6B, IC5B, IC5C

Daca tinem cont ca in intervalul 0-0x260, MC-ul are rezervata zona pentru registrii si memoria interna rezulta ca din cele doua pagini de memorie de 2x64KB raman la utilizator numai 2x(0xFFFF-0x25F)=0x1FB40=129856 octeti, suficienti pentru afisare.

De asemenea in zona de sfarsit a memoriei am mai alocat inca 32 de octeti (2x16 , cate 16 ptr fiecare pagina) pentru a "mapa" portul de intrare si cel de iesire (IC14,IC12) pe care putem sa ii utilizam pentru comunicatia paralela.

Selectia intre RW-RAM si IO se face cu semnalele /CSM- selectie ram si IN0, OUT0 - selectie porturi. Acestea sunt obtinute cu IC7, IC11A IC10B, - respectiv, IC11B, IC10C, IC10D, IC6D

Suplimentar MC-ul gestioneaza comunicatia paralela cu ajutorul semnalelor:

- PEN -echivalent EN de la clasicile LCD

- PRW - echivalent RW de la clasicile LCD

- PRS - echivalent RS de la clasicile LCD

- PBUSY - este un bit care va indica ca MC-ul este busy, este echivalentul bitului 7 de la citirea starii in cazul clasicilor LCD

 

Pe de alta parte LCM5328 transfera sincron cate 8 biti pentru fiecare sector de afisare.

Rezulta ca LCD-ul "utilizeaza" o pagina de 64kx16biti

LCD-ul are prevazute 16 registre de 2x(8x10biti) fiecare pentru coloane, intrarile de la perechea de cate 8 registrii sunt UD0-UD7 (sectorul superior) si LD0-LD7(sectorul inferior)

Pentru linii are prevazute 4 registrii de cate 60biti fiecare, si cu ajutorul carora se face selectia liniiei afisate.

Principiul de afisare este urmatorul:

- se transmite o linie in sectorul superior simultan cu o linie in sectorul inferior

- se afiseaza

- se asteapta un timp

- se trece la linia urmatoare si se repeta operatiile

- cand au fost afisate 240 linii/sector (un frame) se reia ciclul

Pentru o afisare corecta frecventa de frame trebuie sa fie mai mare decat 16frame/s, ceea ce insemna cca 62,5ms

Rezulta un timp pentru afisarea unei linii=62,5ms/240= cca 260us.

Pe o linie trebuiesc transmisi 640x3 biti=80x3 octeti =240 octeti.

Se observa ca numarul de octeti raportat la timpul in care trebuie afisata o linie , duce la o viteza de 1octet/1us. Totul este in regula, numai ca microcontrollerului nu ii mai ramane timp si pentru altceva.

Problema se rezolva marind viteza de transmisie a unei linii cat mai mult.

Pentru asta (in prima faza) ridicam frecventa la quartz-ul MC-ului. Am ales-o de 14,74MHz pentru a putea realiza comunicatii seriale la viteze ridicate.

O alta metoda de a ridica viteza de transfer ,este modul in care se interfateaza MC-ul cu LCD-ul.

Solutia gasita este de a "pune la dispozitia" LCD-ului toti cei 16 biti necesari prin accesarea celor doua pagini de memorie simultan cu un semnal de RD si unul suplimentar DSP/MC prin IC10A

Iesirile de date de la cele doua memorii (IM1,IM2) sunt conectate la UD0-UD7 respectiv LD0-LD7 de la LCD

Pentru a putea transmite un octet la LCD este suficient a face o citire din zona de memorie alocata afisarii, iar semnalul CL2, care shifteaza cei doi octeti este dat de semnalul RD impreuna cu DSP/MC ( IC10A)

Pe perioada cat se face o citire din ram pentru MC, se inactiveaza semnalul DSP/MC, iar LCD-ul nu mai primeste nimic.

Semnalele utilizate la afisare si generate de MC sunt in conformitate cu PDF-ul de la LCM 5328. su au urmatoarele semnificatii:

- CL2 - clock ce shifteaza cei doi octeti de la UD0-UD7 si LD0-LD7 in LCD

- CL1 - clock ce comuta linia de afisare

- FLM - clock ce indica afisarea unui nou frame

- LCD_EN - activeaza afisarea

- M_LCD - indica starea de initializare a LCD-ului (eu nu l-am utilizat, pur si simplu astept un timp)

 

Pornind de la cele de mai sus afisarea se face in felul urmator:

1. - aleg o zona de memorie din care facem afisarea

2.- initializez o intrerupere la cca 64ms

3. - initializez adresa de start

4.- tramsit o linie ptr fiecare intrerupere

- transmiterea unei linii o fac in felul urmator:

- aduc adresa din ram a liniei

- DSP/MC=0 ; cu asta activez semnalul CL2

- fac 240 de citiri dim ram de la adresa linie cu incrementarea adresei, automat se genereaza semnulul CL2(vezi mai sus), citirea se face simultan din cele doua pagini

- cand s-a termint generez CL1 pentru schimbarea liniei si slavez adresa urmatoarei linii

- DSP/MC=1 - inactivez semnalul CL2

5. dupa ce transmit 240 de linii generez semnalul FLM si reinitializez RAM-ul cu adresa primei linii

 

Operatiunea de transmitere a unei linii dureaza cca.28us, ceea ce insemna ca MC-ul mai are la dispiozitie inca 36us(intre doua intreruperi) pentru a executa diversele comenzi primite.

 

Practic am ales zona de memorie grafica de afisare intre 0x400 si 0xE500 de la 0xE500 la 0xF7C0 , din prima pagina am alocat-o pentru zona de afisare alfanumerica tot de la 0xE500 la 0xF7C0 , dar din pagina a doua am alocat-o zonei de atribute (forecolor, backcolor, size, etc) ale afisarii alfa numerice.

Tipul de memorie RAM utilizata este W24512 , din acelea ce se foloseau ptr cache la vecile PC-uri.

Link spre comentariu

W24512 se poate inlocuii cu una din memoriile:- K6L0908- KM68512- CXK58512- HM62512etc...In cazul in care nu gasesti asa ceva , se poate inlocui cu sram de 128x8, cu conditia ca A16 sa il pui la un nivel fix (exemplu 0V), si il utilizezi numai pe jumatate.Pentru acest tip se gasesc :- M5M51008 128kx8 - R1LP0408- SR624008...etcSau ,(acum mi-a venit), poti sa aloci o iesire de la MC pentru acest A16(diferit de a16 din schema), astfel incat sa ai doua pagini grafice diferite, si pe care le poti comuta intre ele

Link spre comentariu
Am citit ce ati scris pe forum si ce este scris pe site-ul nemtesc.

As avea cateva intrebari daca imi permiteti:

1.In schema dumneavoastra am vazut doar partea de comanda a lcd-ului. Aveti cumva si o schema pentru alimentare(mai ales pentru VEE)?

In attach este o schema ca fabrica tensiunile necesare pentru LCD. Incusiv backlight-ul.

Vpp - 12V - este un alimentator din comert 12V/1000mA (alimenteaza si LCD si MC)

Partea de backlight:

PL1,PL2,PL3 - se conecteaza un potentiometru de cca.5k- pentru luminozitate

L1 - o bobina cu 40sp. CuEm 0,3mm , pe un miez ferita cu diametrul de 3mm

Transformatorul :

Miez ferita E+I (eu am utilizat unul cu dimens. de gabarit =20x25x5mm)

intrefier cca. 0,1mm (o banda de scotch)

P1-P2 = 7sp. CuEm 0,6mm

P2-P3 = 7sp. CuEm 0,6mm

P4-P5 = 4sp. CuEm 0,3mm

P6-P7 = 350sp. CuEm 0,1mm

ATENTIE la izolatie

LSP7-LSP8 -iesire ptr backlight

A NU se conecta fara sarcina

Partea de contrast(VEE):

Am utilizat un 555 pe post de oscilator

PC1,PC2,PC3 - se conecteaza un potentiometru de cca. 5K - regleaza contrastul

L1 - 130sp. CuEm 0,3mm miez ferita cu diametrul de 3mm

 

Lista de componete atat de la MC cat si de la prezenta sursa, reies din scheme

3.Asa cum ati scris si pe forum si din schema reiese faptul ca lcd-ul(tot ansamblul inclusiv partea de comanda) se conecteaza "mai departe" asemenea unui lcd alfanumeric clasic. Softul pe care l-ati scris permite si afisarea de imagini, eventual video mai slab?

Pentru transferul paralel si SPI nu am definitivat soft-ul, functie de timp o sa il termin

Pentru VIDEO, mai putin, e cam greu, cu atat mai mult cu cat afisorul nu admite decat 8 culori

 

cu ce program s-ar putea folosi impreuna cu pc-ul?

Fiecare isi scrie propriul program

pentru folosirea impreuna cu un convertor FT245 sunt necesare modificari alea schemei/softului?

Nu m-am gandit, dar ideea mi se pare interesanta. In varianta actuala eu merg pe USART, se poate pune un FT232 si mergi pe USB (fara modificari hard), dar trebuie sa schimbi soft-ul.

Am sa postez si comenzile de la USART, impreuna cu soft-ul

Link spre comentariu
Pt backlight nu pot folosi si un invertor dintr-un scanner? Se alimenteaza tot la 12V.

Da dar, trebuie sa ai grija ca tensiunea+C(serie) sa nu reduca durata de viata a backlight-ului

O memorie SRAM 64K x 16 (SR611016HSA10J) nu ar putea fi folosita? Timpul de acces W/R este 15/12 nS. Sau se complica lucrurile?

Se poate , cu urmatoarele modificari : in loc de WU si WL se aplica direct WR la sigurul CHIP, de asemenea UD0-UD7 se leaga la DO-D7 (RAM) iar LD0-LD7 se leaga la D8-D15(RAM)

Dom' mitescu am o rugaminte: nu mai dati enter cand randul ajunge la capat. Cursorul trece automat mai jos, fara a da enter. Apasa pe enter cand vei sa incepi un rand nou, sa separi idei, etc.

Ok. Numai ca eu nu editez direct on_line. Utilizez copy-paste

Link spre comentariu

In attach am pus varianta a soft-ului in care se utilizeaza comunicatia seriala, cea paralela si SPI fiind inca "nefunctionale" Catva observatii se impun:

In primul rand , nu este ceva definitiv, dar oricum este functional si se poate porni de aici pentru punerea in functiune a LCD-ului.

Cu exceptia a doua comenzi, sunt si au parametrii in HEX (reprezentare ascii), astfel incat cu un terminal obisnuit (hyperteminal) sa se poata da comenzi manuale). Cele doua comenzi care sunt "usor" diferite le voi explicita mai jos.

Viteza de comunicatie (default) este de 115200 baud, si se poate modifica din setari. Asa cum am mai spus , se poate face o adaptare USB du FT232, (sau altceva), caz in care dispare MAX232.

Comenzi de la uart:

x - intoarce numarul sectorului accesat (upper/lower)

X - comuta sectorul de RAM

b p - schimba baudrate la USART , p poate fi:

1 - 4800

2 - 9600

3 - 19200

4 - 38000

5 - 115200 (default)

f AdrBegin AdrEnd Byte - face fill in RAM intre cele doua adrese cu byte

9 - converteste pagina alfa in grafic(comanda suplimentara la fill screen)

0 - fill screen Black

1 - fill screen RED

2 - fill screen GREEN

3 - fill screen BLUE

4 - fill screen MAGENTA

5 - fill screen CYAN

6 - fill screen YELLOW

7 - fill screen WHITE

t - incepe o secventa de scriere a unui text la adresa curenta din pagina de RAM alfanumerica

ctrl +C - break - end of text, intrerupe secventa de scriere a unui text

g Xdim Ydim StartAdr - transfera o imagine cu dimensiunile Xdim,Ydim, la adresa Startadr

F Color - seteaza forecolor la Color (0-7)

B Color - seteaza backcolor la Color(0-7)

C - cls ram grafic, cls ram alfa

p Xpos Ypos - seteaza un pixel la coordonatele Xpos Ypos

l Xstart Ystart Xend Yend - (L mic)traseaza o linie de la X Y start pana la punctul XY end

q Xstart Ystart Xend Yend - traseaza un dreptunghi de la X Y start pana la punctul XY end

Q Xstart Ystart Xend Yend - traseaza un dreptunghi de la X Y start pana la punctul XY end cu fill. Obs.: cotele se rotunjesc la Byte

P X Y - seteaza pozitia de inceput a textului (de comanda t) in X(0-79) si Y(0-59)

z - intoarce size Chr curenta (0 - default, other X2)

Z Size - seteaza marimea caracterului "0" = default, "other"=X2

i - intorce starea INVERT 00 - normal , other = INVERT

I "inv" - seteaza INVERT "0" - normal, "other" - INVERT (INVERT: switch forecolor backcolor,chr only)("inv"=chr)

S - scroll , face scroll , cu un rand

 

La comutarea marimii caracterului , comanda Z, parametrul pentru size = normal este caracterul "0", iar orice alt caracter face size=x2. Aceeasi situatie si la INVERT.

Un caz aparte este transferul unei imagini, comanda g, unde parametrii sunt reprezentarea ascii a valorilor hex, iar dupa aceea transferul se face la nivel de Byte(valoare binara), si deci nu poate fi facut direct din terminal. De exemplu daca dorim transferul unei imagini ce are dimensiunile de 230x280 pixeli si coltul de sus a imaginii trebuie sa fie la adresa din ram 0x600 , comanda comanda data trebuie sa apara in felul urmator:

g 00E6 0118 0600 [........ bytes ........]

ceea ce insemna 0x00E6 =230 x dim., 0x0118=280 ydim. 0x600 adrstart, ptr proba se poate da o comanda din terminal , iar octetii (aleatorii) din tastatura. Binenteles ca inafara dimensiunii nimic nu va fi coerent.

ATENTIE la adresa din RAM, un pixel ocupa 3 biti, si trebuie socotita cu grija. De asemenea daca se doreste amplasarea imaginii in lower sector , trebuie sa dati in prealabil comutarea paginii, o imagine care incepe din upper sector poate avea si o parte in lower sector, NU este grija operatorului, programul comuta singur sectorul, numai ca , atentie, la sfarsit sectorul selectat ramane lower. IMPORTANT numarul de bytes ytransferati trebuie sa coincida cu dimensiunea.

Alte specificatii sunt cu referire la culori, astfel in mod grafic (pixeli, linii dreptunghiuri) se traseaza cu forecolor. In mod text unde un caracter normal ocupa 8x8 pixeli, caracterul va fi trasat cu forecolor, iar fundalul va fi backcolor. In cazul in care se scrie un text iar apoi se traseaza un desen grafic, se poate sterge ecranul cu comanda 0(sau alta culoare) si se poate reface textul cu comanda 9, care converteste bufferul alfa in grafic.

O comada speciala care este impplementata dar care nu este activata din motive de bug-ri (sper sa o rezolv) este comanda :

j Xstart Ystart Step NrByte - traseaza un grafic incepand de la Xstart Ystart , valorile bytes ce se transfera reprezinta cota pe Y a punctelor intre care se traseaza linii, Step reprezeinta incrementul pe axa X. Bytes transferati sunt in binar, Valoarea maxima a lui NrBytes este de 255, iar Step inmultit cu NrBytes nu poate depasi 640.

Practic aceasta comanda a fost implementata pentru functia de osciloscop, dupa o conversie se "varsa" rezultatele, iar afisorul le afiseaza.

Complementar cu aceasta comanda este comada:

J - care sterge automat ultimul grafic afisat

Deocamdata atat, Softul a fost scris de fapt pentru a putea pune in functie un LCD LCM2358.

Cand o sa fac, poate, o sa postez si niste foto cu rezultatele obtinute.

Link spre comentariu

Multumim pentru efortul depus in scrierea softului!Din moment ce o varianta a softului e gata schema e defininiva,nu?In varianta in care as folosi memoria SRAM specificata mai sus(64k x 16) modificarile descrise mai sus sunt singurele necesare?Nu necesita modificari soft?

Link spre comentariu

In varianta in care as folosi memoria SRAM specificata mai sus(64k x 16) modificarile descrise mai sus sunt singurele necesare?Nu necesita modificari soft?

Aici am gresit, nu, nu se poate utiliza asa ceva, fara schimbare de soft, numai in cazul in care folosesti tot doua bucati, poti in schimb sa folosesti memorii de 128Kx8 (asa cum am mai spus. Nu merita sa te complici pentru 6Ron in plus)
Link spre comentariu

Pai daca le legi asa, sa vedem ce se intampla in cele trei situatii posibile:1. MCU - Write:RD =1 - corectWR=0 corectLB=/UB - corect - selectie sector doritGL=/GU - corect - directia este buna ptr ca RD=1Scrierea este facuta in mod corect2. MCU-ReadRD= 0 corectWR=0 - correctWL=LB=1,WR=UB=1 - INCORECT , care sector se selecteaza ?3.LCD - ReadRD=0 corectWL=LB=1, WU=UB=1 - INCORECT, trebuiesc selectate ambele sectoarePentru a utiliza o memorie de tipul asta trebuie facuta o alta schema de selectie, de asa maniera incat la citire sa se respecte conditia de citire simultana a 16 biti. In acest caz la secventa de citire MC-READ, nu conteaza ptr ca este selectat numai unul din bufferele 245. Incearca schema din figura, cu observatia ca ptr conformatia aranjamentului am schimbat L<>U (la mine L reprezinta low de la screen , care ar insemna la tine D8-D15, deci U). Restul legaturilor pot ramane asa cum le-ai scris. Oricum nu inteleg de ce vrei sa te complici, in cazul in care nu ai ram-ul de 64x16, iei doua de 128x8 si scapi de probleme(este verificat)[attachment=0]Sel65x16.png[/attachment]

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări