Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

LCD TFT ILI9325 - odświeżanie matrycy

hamilton32 18 Gru 2010 16:46 5998 36
  • #1 18 Gru 2010 16:46
    hamilton32
    Poziom 11  

    Witam

    Ku mojemu zdziwieniu udało mi się uruchomić ten świetny wyświetlacz TFT: 320x240 kolory 24bit
    http://www.maritex.com.pl/pl/shop/productInfo/ggid/10088/pid/12877/page/1/backurl

    działa super!
    Jednak nie mogę do końca zrozumieć dokumentacji do sterownika LCD:
    http://www.techtoys.com.hk/Displays/TY280T240320/datasheet/ILI9325DS_V0.28.pdf

    Chodzi o to aby wyświetlacz zapisywał dane do GRAM i wyświetlił dopiero po wysłaniu komendy i tak cały czas. Obecnie LCD działa tak że jak wysyłam pojedyncze piksele to pojawiają się jeden po drugim (szybko ale jednak mimo to istenieje złudzenie że lcd zapełnia się)
    Jaki rejestr w LCD trzeba zmienić aby dane na LCD zostały uaktualnione dopiero po wysłaniu wszystkich danych?
    Jest chyba o tym mowa na stronie 58
    "8.2.8. Display Control 1 (R07h)" ale nie mogę rozszyfrować
    P.S. Za pomoc mogę udostępnić chętnym własne biblioteko do tego lcd

    0 29
  • #2 18 Gru 2010 17:20
    asembler
    Poziom 32  

    Mnie sie wydaje ze nie ma takiej możliwości. Wynika to ze schematu LCD, gdyż nie posiada podwójnej pamieci RAM a tylko tak mozna pozbyc sie tego efektu.

    0
  • #3 18 Gru 2010 18:01
    atom1477
    Poziom 43  

    Jak kolega wyżej napisał, ten LCD nie obsługuje takiej funkcji.

    0
  • #4 18 Gru 2010 18:31
    hamilton32
    Poziom 11  

    atom1477 napisał:
    Jak kolega wyżej napisał, ten LCD nie obsługuje takiej funkcji.

    ale ten LCD mam wewnętrzny kontroler i pamięć GRAM.

    Już prawie działa ta funkcja wystarczy w rejestrze 0x07 wykasować bit D0 lub D1 a po wprowadzeniu zmian do GRAM ustawić Ponownie D0 i D1

    Zmiany na lcd zamiast stopniowo pojawiają się po dopiero po ustwaieniu D0 lub D1 ale..
    problem w tym że..
    statyczny obraz przy wykasowanym D0 zmienia nieco kolory, a przy wykasowanym D0 i D1 obraz stopniowo z czasem traci kontrast

    0
  • #5 18 Gru 2010 18:35
    atom1477
    Poziom 43  

    hamilton32 napisał:
    atom1477 napisał:
    Jak kolega wyżej napisał, ten LCD nie obsługuje takiej funkcji.

    ale ten LCD mam wewnętrzny kontroler i pamięć GRAM.

    To nie ma żadnego znaczenia.

    hamilton32 napisał:
    Już prawie działa ta funkcja wystarczy w rejestrze 0x07 wykasować bit D0 lub D1 a po wprowadzeniu zmian do GRAM ustawić Ponownie D0 i D1

    Zmiany na lcd zamiast stopniowo pojawiają się po dopiero po ustwaieniu D0 lub D1 ale..
    problem w tym że..
    statyczny obraz przy wykasowanym D0 zmienia nieco kolory, a przy wykasowanym D0 i D1 obraz stopniowo z czasem traci kontrast

    Nie działa. To służy do wyłączania wyświetlacza. Jedynie przez przypadek LCD po wyłączaniu przez chwilę trzyma obraz. A skoro trzyma to wydaje Co się że jest to ta opcja której potrzebujesz. Ale uwierz że to nie jest ta opcja.

    0
  • #6 18 Gru 2010 18:45
    asembler
    Poziom 32  

    I doprowadza LCD powoli do grobu.
    Jedyne co możesz zrobic to sprobowac optymalnie napisac procedure transferu danych.

    0
  • #7 18 Gru 2010 19:40
    hamilton32
    Poziom 11  

    atom1477 napisał:
    hamilton32 napisał:
    atom1477 napisał:
    Jak kolega wyżej napisał, ten LCD nie obsługuje takiej funkcji.

    ale ten LCD mam wewnętrzny kontroler i pamięć GRAM.

    To nie ma żadnego znaczenia.

    hamilton32 napisał:
    Już prawie działa ta funkcja wystarczy w rejestrze 0x07 wykasować bit D0 lub D1 a po wprowadzeniu zmian do GRAM ustawić Ponownie D0 i D1

    Zmiany na lcd zamiast stopniowo pojawiają się po dopiero po ustwaieniu D0 lub D1 ale..
    problem w tym że..
    statyczny obraz przy wykasowanym D0 zmienia nieco kolory, a przy wykasowanym D0 i D1 obraz stopniowo z czasem traci kontrast

    Nie działa. To służy do wyłączania wyświetlacza. Jedynie przez przypadek LCD po wyłączaniu przez chwilę trzyma obraz. A skoro trzyma to wydaje Co się że jest to ta opcja której potrzebujesz. Ale uwierz że to nie jest ta opcja.


    a masz jakieś większe doświadcznie z tym LCD?
    Stosowałeś go w jakiś układach?
    Narazie działa w trybie 8 bit ale mam zamiar przejść na 16 bit

    0
  • #8 18 Gru 2010 19:43
    nsvinc
    Poziom 35  

    Tu aż się prosi użycie DMA. Wtedy nie bedzie wcale widoczne, jak "rysują" się pixle.

    To, co potrzebne autorowi tematu, to double buffering. Wszyscy wiemy, ze fajnie by bylo na zmiane w jednej ramce rysować, a drugą wyświetlać, i tak na zmiane.
    Zadałem sobie trud zerknięcia do datasheeta, i niestety - tenże badziew (w sensie kontroler LCD) nie obsluguje "stawiania" adresu poczatkowego ramki w RAMie, aczkolwiek z tego co widzę, nie jest to jego jedyna bieda. Więc tak czy inaczej, ficzer podwojnego buforowania jest nie do zrealizowania na tym kontrolerze.
    Dlatego też warto kupować wyswietlacze z kontrolerami epsona lub solomon (w 99% scalakow tych firm można postawić początek ramki na dowolny adres w zewn lub wewn pamięci).

    0
  • #9 18 Gru 2010 20:08
    atom1477
    Poziom 43  

    hamilton32 napisał:
    atom1477 napisał:

    ...
    ...
    ...


    a masz jakieś większe doświadcznie z tym LCD?
    Stosowałeś go w jakiś układach?

    Nie ale zajrzałem do datasheeta.

    0
  • Pomocny post
    #10 18 Gru 2010 21:30
    tmf
    Moderator Mikrokontrolery Projektowanie

    To co chcesz osiągnąć da się zrobić pisząc w chwilach, kiedy zapisywany fragment LCD nie jest odświeżany. Aby to sprawdzić trzeba czytać bit statusu (8.2.2), jeśli kontroler wyświetla linię znajdującą po zapisywanej, to możesz modyfikować pamięć, zmiany pojawią się dopiero od następnej ramki, oczywiście całość musisz zmodyfikować do tego czasu.
    nsvinc - źle patrzysz, oczywiście można dowolnie ustawiać adres początkowy VRAM, z tym, że double buffering i tak się nie zrobi, bo po prostu jest za mało pamięci. Ale można zrobić dzięki temu łatwo scroll. DMA się też nie nada - chyba, że do operacji kopiowania prostokątnych obszarów pamięci, tyle, że to by wymagało zrealizowania kopii VRAM w pamięci mikrokontrolera.

    0
  • Pomocny post
    #11 18 Gru 2010 21:40
    atom1477
    Poziom 43  

    W sumie w trybie 8-mio bitowym możliwe że by poszło (double buffering), bo pamięci jest na obraz 18-to bitowy.
    Oczywiście pod warunkiem że wtedy pamięć jest wykorzystywana jako 8-mio bitowa. Nie wgłębiałem się. Najgorzej jak nadal jest 18-to bitowa a konwersja 8-->18bitów jest robiona w locie podczas zapisu do tej pamięci.

    0
  • #12 18 Gru 2010 23:13
    hamilton32
    Poziom 11  

    atom1477 napisał:
    W sumie w trybie 8-mio bitowym możliwe że by poszło (double buffering), bo pamięci jest na obraz 18-to bitowy.
    Oczywiście pod warunkiem że wtedy pamięć jest wykorzystywana jako 8-mio bitowa. Nie wgłębiałem się. Najgorzej jak nadal jest 18-to bitowa a konwersja 8-->18bitów jest robiona w locie podczas zapisu do tej pamięci.


    ten lcd jest wogóle jakiś dziwny
    zapisuje 3x8bit co daje 24bit ale po odczycie GRAM otrzymuje tylko 16bitów

    Jaki inny lcd polecisz?
    Cena do 100pln , rozmiar > 2.6 cala do 5 cali. Moze byc bez driveara ale by sensownie działał ze szybkim ARM7 lub stm32


    nsvinc napisał:
    Tu aż się prosi użycie DMA. Wtedy nie bedzie wcale widoczne, jak "rysują" się pixle.

    Dlatego też warto kupować wyswietlacze z kontrolerami epsona lub solomon (w 99% scalakow tych firm można postawić początek ramki na dowolny adres w zewn lub wewn pamięci).


    gdzie to kupie? Nie wiem czy DMA w stm32 działa z portami GPIO. Poza tym każde dane na magistrali muszą by potwierdzone zmianą stanu pinu WRITE

    0
  • #15 19 Gru 2010 00:33
    atom1477
    Poziom 43  

    SDRAM jest po 5zł (a przynajmniej kiedyś był).
    Przykład uruchomienia masz na przykład tutaj:
    https://www.elektroda.pl/rtvforum/viewtopic.php?p=7113317#7113317
    Tylko weź pod uwagę że wykonanie tego nie będzie proste i tanie.
    Ścieżki ledwo da się upchać na 2 warstwach, i to kosztem pola masy. Czyli będzie kiepskie pole masy i będą duże zakłócenia (CE z czystym sumieniem raczej nie nadasz). Pasowało by to zrobić na 4 warstwach.
    Do tego koszt wykonania płytki (a mówię o 2-stronnej) i lutowanie.
    Sterownik raczej musi przekroczyć 100zł czyli będzie droższy od LCDka.
    Więc w ten sposób nie zaoszczędzisz.

    0
  • #16 19 Gru 2010 00:45
    nsvinc
    Poziom 35  

    >atom1477 - twoj przykład to hardcore :]
    Chyba łatwiej uzyc wyświetlacza z kontrolerem, ktory przy okazji ma wieksza niz konieczna pamiec? Jesli ktos chce nawet 640x480x16bit, to nie ma zmiłuj, wtedy prawie kazdy kontroler na matrycach nie bedzie mial 2x[wymagana pamiec], i trzeba stosować SDRAM

    Do rozdzielczości 320x240, ewentualnie 320x400, itp, bywaja wyswietlacze na ktorych sa kontrolery z odpowiednio dużą pamięcią.

    Polecam wyswietlacze Ampire, i OLEDy (ogolnie roznych firm), w większości mają sterownik SSDxxxx, a tam często są do osiągnięcia myki aby skombinować podwójne buforowanie.

    0
  • #17 19 Gru 2010 10:56
    atom1477
    Poziom 43  

    Niekoniecznie. Zależy jaką grafikę chce się wyświetlać.

    0
  • #18 19 Gru 2010 11:17
    _Robak_
    Poziom 33  

    Cytat:

    P.S. Za pomoc mogę udostępnić chętnym własne biblioteko do tego lcd


    hamilton32 napisał:
    atom1477 napisał:
    http://allegro.pl/listing.php/search?string=mio+lcd+p560&category=0..
    Ale wymaga ARMa z kontrolerem LCD i SDRAMu. Np. LPC2478.


    byłyby idealne. Ale jak to ruszyć?
    Jak tym sterować? od czgo zacząć? ten SDRAM niestety troche drogi jest, chyba że źle patrzę. Może jkieś pzykłady?

    Przecież dopiero za pomoc oferowałeś innym swój kod. Więc najpierw w takim razie pomóż innym i wtedy proś o kod!

    0
  • #19 19 Gru 2010 15:31
    hamilton32
    Poziom 11  

    _Robak_ napisał:
    Cytat:

    P.S. Za pomoc mogę udostępnić chętnym własne biblioteko do tego lcd


    hamilton32 napisał:
    atom1477 napisał:
    http://allegro.pl/listing.php/search?string=mio+lcd+p560&category=0..
    Ale wymaga ARMa z kontrolerem LCD i SDRAMu. Np. LPC2478.


    byłyby idealne. Ale jak to ruszyć?
    Jak tym sterować? od czgo zacząć? ten SDRAM niestety troche drogi jest, chyba że źle patrzę. Może jkieś pzykłady?

    Przecież dopiero za pomoc oferowałeś innym swój kod. Więc najpierw w takim razie pomóż innym i wtedy proś o kod!


    nie wiem z czym masz problem? Kto chciał kod ten dostał.
    Pozatym ten LCD to itak ponoć nic nie warty jest....

    0
  • #20 19 Gru 2010 17:18
    tmf
    Moderator Mikrokontrolery Projektowanie

    Wiesz, LCD z tymi kontrolerami stosowane są w znakomitej większości komórek. I jakoś wyświetlać się na nich da - wymaga to tylko nieco więcej wysiłku. Jak już ci ten LCD działa i wygląda dobrze, to lepiej popraw funkcje obsługi, zamiast szukać innego.

    0
  • Pomocny post
    #21 19 Gru 2010 17:47
    nsvinc
    Poziom 35  

    Święte słowa...

    Użyj ficzerów procka (DMA) i ficzerow kontrolera (window), aby tworzyć grafikę. Window cudownie nadaje się do wyświetlania czcionek, ikon czy innych piktogramów. W połączeniu z DMA można uyskać cuda w postaci np. ikon "przesuwalnych" na statycznym tle (jak pulpit windowz).

    W komorkach wykorzystuje się często blisko 100% ficzerów kontrolera. Bardziej opłaca się wykorzystać tańszy kontroler i napisać lepszy soft, niż implementować prawie kartę graficzną z akceleracją 2D (lub 3D) i stosować proste API (pixel, fill, cut, copy,polygon,....).

    Fakt nadal pozostaje - lcdki mało znanych producentów są raczej słabej jakości, i pod względem kontrolera, jak i jakości obrazu...

    0
  • #22 19 Gru 2010 21:36
    hamilton32
    Poziom 11  

    oczywiście czcionki i inne robie w tzw window

    Narysowanie pełnoekranowego tła trwa 80 ms,
    ,narysowanie 100 ukośnych linii o długości 300 pixeli trwa jedynie 100 ms ale mimo to pozostałe pozostawia złudzenie stopniowego zapełniania lcd i mignięcia miedzy kolejnymi ramkami. Brakuje opcji zamrożenia zawartości LCD podczas zapełniania GRAM.

    Jak wykorzystać tutaj DMA? Procek to stm32f103

    0
  • #23 19 Gru 2010 23:26
    tmf
    Moderator Mikrokontrolery Projektowanie

    To strasznie długo to trwa. Mam kilka LCD z podobnym chipem (też ILI) i mogę narysować kompletną ramkę w czasie kiedy LCD nie jest odświeżany. Jaki stosujesz procesor? Jeśli ma wystarczającą ilość pamięci, to możesz wszystkie operacje robić na pamięci procesora, po czym określać minimalny prostokąt w którym zaszły zmiany i np. przy pomocy wspomnianego DMA kopiować go do pamięci VRAM. Ten sterownik wyciąga spokojnie parę MB/s w trybie równoległym, więc z pewnością problemów z niewidocznym uaktualnianiem pamięci sterownika nie zaobserwujesz.

    0
  • #24 20 Gru 2010 12:27
    nsvinc
    Poziom 35  

    stm32f103 ale co dalej?.... Podane oznaczenie o niczym więcej nie mówi, niż o rodzinie procków.

    DMA mozna wykorzystać w dwojaki sposób:

    * DMA na port, czyli gdzies w pamieci masz obraz, odpalasz DMA w trybie mem2mem - najgorsze rozwiazanie, już lepiej wykorzystać SPI

    *DMA na FSMC, nadal tryb mem2mem, ale znacznie lepiej i prościej wykorzystywać timingi narzucone przez FSMC. Dodatkowo, nie musisz się wtedy przejmować CSem, RD, WR itp itd.

    Jak podłączyłeś wyświetlacz po SPI to też możesz prosto wykorzystać DMA.

    100 ukosnych linii o dlugosci 300 pixli nie ma prawa sie rysowac 100ms. Całkiem mozliwe jednak, ze twoja funkcja rysujaca linie raczy marnowac sporo czasu na zmienne float :]

    0
  • #25 21 Gru 2010 22:16
    hamilton32
    Poziom 11  

    udało mi się zredukować czasy przez optymalizację kodu.
    przy interface 8bit zapełnienie całej matrycy (320x240x2bajty koloru) trwa 19 ms
    W celu wysłania inforamcji o jednym pixelu muszę wysłać 2 bajty i toglować pin WRITE
    -wyślij MSB
    -SET WRITE
    -CLR WRITE
    -wyślij LSB
    -SET WRITE
    -CLR WRITE
    co daje 6 instrukcji.

    Z obliczeń wynika że każda z powyższych funkcji zajmuje 0,04us
    Procesor pracuje z częstotliwością 75 Mhz. Da się jeszcze coś wycisnąć?



    FSMC nie wchodzi w grę bo znajduje się tylko w droższych prockach z wielką pamięcią Falash.

    Niestety nawet przy czasie zapełniania matrycy rzędu 30 ms (tło + napisy) widać nieciekawe mignięcia rzy kolejnych odświeżeniach.

    Code:


    #define LBUS_SET    GPIOB->BSRR
    #define LBUS_RESET  GPIOB->BRR
    #define LBUS_OUT    GPIOB->ODR

    #define L0   8

    #define LCS1     GPIOA->BSRR = 1<<9 //CS
    #define LCS0      GPIOA->BRR = 1<<9

    #define LWRITE1   GPIOC->BSRR = 1<<6  // write
    #define LWRITE0   GPIOC->BRR = 1<<6


    void LCD_prostokat(uint16_t x, uint8_t y, uint16_t szer, uint8_t wys, uint16_t kolor)
    {
       uint32_t p;
                 L_window(x,y,szer,wys);  // zaznacz fragment matrycy lub calosc
                 L_GRAM_seria_start(); // komenada ciągłego zapisu GRAM
         for(p=0; p < (wys*szer); p++)  //dla wszystkich pikseli w obszarze
             Lcd_zapiszGRAM_seria(kolor); //wyślij kolor pixela
         LCS1;  //koniec zapisu GRAM
         L_window(0,0,320,240); // okno standarowe

    }

    void L_GRAM_seria_start()  // rozpoczyna zapis GRAM wielu pikseli
    {                        
       LCS0;
       LRS0;

       LBUS_OUT = (0x00<<L0);   
        LWRITE0;
        LWRITE1;

        LBUS_OUT = (0x22<<L0);   //adres rejestru GRAM
        LWRITE0;
        LWRITE1;
       LRS1;

    }

    void Lcd_zapiszGRAM_seria(uint16_t kolor)  // wysyła kolor kolejnego piksela w tablicy GRAM
    {
        LBUS_OUT = kolor&0xFF00;
        LWRITE0;
        LWRITE1;

        LBUS_OUT = (kolor<<L0);
        LWRITE0;
        LWRITE1;
    }

    0
  • #26 21 Gru 2010 22:55
    tmf
    Moderator Mikrokontrolery Projektowanie

    Widać mignięcie, bo nie synchronizujesz odświeżania z zapisem, tak jak ci już sugerowałem. Swoją droga, nie masz jakiegoś interfejsu pamięci zewnętrznej w użytym procesorze? Wierzyć się nie chce, bo nawet ATMega po podłączeniu do sprzętowego interfejsu XMem wyciągnęłaby prędkość pare razy większą.

    0
  • #27 22 Gru 2010 08:22
    piti___
    Poziom 23  

    Nie wszystkie ARMy (7, cortex) mają zewnętrzną magistrale. W przeciwieństwie do AVRów, zewnętrzna magistrala dla tych układów to przynajmniej 40 dodatkowych pinów (np 24 adres, 16 dane).

    0
  • #28 22 Gru 2010 09:33
    tmf
    Moderator Mikrokontrolery Projektowanie

    Na ARMach się nie znam, ale nikt tam nie wprowadził możliwości konfiguracji interfejsu typu 8/16/32 bity magistrali danych? Przecież takie funkcje miały archaiczne 8086. Podobnie z liniami adresowymi, to, że są 24 nie oznacza chyba, że wszystkie trzeba wykorzystać? W AVR jest rejestr kontrolny określający, które bity adresowe są w użyciu, nieużywane są normalnymi portami IO. Nie wierzę, żeby ARM tego nie miał. Jeśli istotnie tak jest to proponuję przesiadkę na XMega, nie tylko ma XMEM, ale także DMA :)

    0
  • #29 22 Gru 2010 09:39
    nsvinc
    Poziom 35  

    ...Ale tylko 30DMIPS :] Za mało, niestety...

    >tmf
    To akurat, że sporo ARMów nie ma wyprowadzonej magistrali, jest zaletą. Nie zawsze chce się uzywac 80 lub 100pin potwora. Dla porownania, taka mega32 tez zewn. magistrali nie ma...

    Zasadą jest, że powinno się dobierać procesor do zastosowania, a nie dobrać na pałę, a potem narzekać...

    Poza tym - na STM32 świat się nie kończy. Kilku producentów robi prze-rozmaite procki na rdzeniu CM3, można dowoli przebierać aż znajdzie się odpowiedni procesor (w miarę mało pinów, w miarę mało flasha, kontroler zewn. pamięci)...

    0
  • #30 22 Gru 2010 10:05
    piti___
    Poziom 23  

    tmf napisał:
    Na ARMach się nie znam, ale nikt tam nie wprowadził możliwości konfiguracji interfejsu typu 8/16/32 bity magistrali danych? Przecież takie funkcje miały archaiczne 8086.


    Oczywiście że jest możliwość, jednak jak wspomniał nsvinc, ARMy z zewnętrzną magistralą to już potwory po 100, 144 pinów i więcej.

    Wracając do tematu, przy sterowaniu kontrolerem wyświetlacza aż prosi się o zewnętrzną magistrale. Pod jednym adresem umieszczamy transmisję komend pod innym lecą dane - odpada ręczne sterowanie LRS0.

    Funkcję
    Code:

    void Lcd_zapiszGRAM_seria(uint16_t kolor)  // wysyła kolor kolejnego piksela w tablicy GRAM
    {
        LBUS_OUT = kolor&0xFF00;
        LWRITE0;
        LWRITE1;

        LBUS_OUT = (kolor<<L0);
        LWRITE0;
        LWRITE1;
    }

    zrobiłbym jako inline, chociaż nie mam pewności czy kompilator w tym przypadku nie zrobi tego sam. Zawsze to parę cykli zegarowych mniej.

    0