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.

[Atmega162][C] Wyswietlacz Graficzny LCD SED1330f

wdogli 05 Sie 2008 21:18 5800 11
  • #1 05 Sie 2008 21:18
    wdogli
    Poziom 18  

    Witam.
    Jakiś czas temu zakupiłem na allegro matryce wyświetlacza graficznego wraz z płytą główną kasy fiskalnej na której to był umieszczony układ SED1330F. Po zdemontowaniu układu SED z płyty zbudowałem własny sterownik w/w matrycy.
    W obecnej chwili jestem po pierwszych testach które trwały 1 miesiąc :)
    No i natrafiłem na problem z którym nie mogę sobie poradzić a mianowicie gdy wysyłam do sterownika komendę wyświetl literę
    "E"
    pobraną z wewnętrznego generatora znaków w efekcie dostaję
    E_E
    gdzie podkreślnik jest migającym kursorem. Poniżej zamieszczam zdjęcie pracującego wyświetlacza.
    Nadmienię jeszcze że wyświetlacz jest o rozdzielczości 256x128 a panel składa się z dwóch osobnych paneli. Widać to na zdjęciu ponieważ jeden wyczyściłem programowo a drugi został zapisany przypadkowymi znakami znajdującymi się w pamięci RAM

    Poza tym poniżej zamieszczam listing programu który steruje SED'm.

    Code:

    //PROGRAM DZIAŁAJĄCY krysztal 16MHz  jeden takt trwa 62,5 ns
    //działający kursor na 00
    #include <avr/io.h>
    #include <stdlib.h>
     

    //====================================LCD GRAFICZNY SED1330F=========================================

    //----------------------------------------LINIE DANYCH-----------------------------------------------

    #define LCDG  PORTC                                     // PORT LINII STERUJACYCH
    #define DLCDG DDRC
    #define CS  6                                           // LINIA CHIP SELECT
    #define A0  5                                           // LINIA WYBORU REJESTRU 0- REJESTR DANYCH, 1-REJESTR POLECEN
    #define WR  4                                           // LINIA ZAPIS DANYCH DO SED1330F
    #define RD  3                                           // LINIA ODCZYT DANYCH DO SED1330F
    #define RES  2                                          // LINIA RESET AKTYWNY W STANIE NISKIM
    //
    #define SET_CS   LCDG |= _BV(CS)
    #define CLR_CS   LCDG &= ~_BV(CS)
    //
    #define SET_A0  LCDG |= _BV(A0)
    #define CLR_A0  LCDG &= ~_BV(A0)




    //
    #define SET_WR  LCDG |= _BV(WR)
    #define CLR_WR  LCDG &= ~_BV(WR)
     //
    #define SET_RD  LCDG |= _BV(RD)
    #define CLR_RD  LCDG &= ~_BV(RD)
    //
    #define SET_RES  LCDG |= _BV(RES)               
    #define CLR_RES  LCDG &= ~_BV(RES)

    //----------------------------------------LINIE DANYCH-----------------------------------------------

    #define LCDGd  PORTA                                     // PORT LINII DANYCH
    #define DLCDGd DDRA
    #define LCDG_PIN PINA

    short int x;

    //==========================================LCD==================================================


    void dlns (void)                   
    {
    asm("nop");
    asm("nop");
    }

    void dl(unsigned char x)
    {
    TCCR0=0x02;
    OCR0=x;
    while(1)
    {
    if(TCNT0>=OCR0)
    break;
    }
    TCCR0=0;
    TCNT0=0;
    }

    void dlms(unsigned char x) // 1,018ms
    {
     
    TCCR0=0x05;
    OCR0=28;
    for(;x>0;x--)
    {
    TCNT0=0;
    while(1)
    {
    if(TCNT0>=OCR0)
    break;
    }
    }
    TCCR0=0;
    TCNT0=0;

    }

    //==========================================================================================//

    void wr_lcd_bus(unsigned char data)               // procedura zapisujaca 8-bitowa dana na magistrale
    {
    int temp = data;                                  // zaczytaj dana polecenie
    LCDGd = temp;
    dlns();
    dlns();
    dlns();
    SET_WR;                                          // WR ustaw w stan wysoki koniec zapisu
    dlns();
    SET_CS;                                          // CS - chyp selekt w stan wysoki
    LCDGd = 0x00;
    dlns();
    }

    void lcdg_init(void)                             // procedura inicjacji wyjsc sterujących
    {
    dlms(2);
    DLCDG = 0x7C;
    dlns();
    LCDG = 0x7C;
    dlns();                                         // linie sterujace jako wyjsca
    CLR_RES;                                         //stan niski na resecie sed1330f przez conajmniej 1ms
    dlms(3);
    SET_RES;                                         //stan wysoki na resecie sed1330f przez conajmniej 1ms
    dlms(3);
    LCDG = 0x7C;                                    //stan wysoki +5V na liniach sterujacych
    }

    void lcdg_write_data(unsigned char data)         // procedura zapisu danej do sterownika
    {
    DLCDGd = 0xFF;                                    // linie sterujace jako wyjsca
    LCDGd = 0x00;                                     //stan niski 0V na liniach sterujacych
    SET_RD;                                          // RD=1 - RD w stanie wysokim nie będziemy odczytywać danych
    SET_WR;
    dlms(1);
    CLR_A0;                                          // A0=1 - zapis danej      poprawnie wg dokumentacji
    CLR_CS;                                          // CS - chyp selekt w stan niski
    dlns();                                          //czekaj min 30 ns ( 62,5ns czeka)
    CLR_WR;
    dlns();
    wr_lcd_bus(data);                                // funkcja zapisu danej na magistrale
    }

    void lcdg_write_cmd(unsigned char cmd)         // procedura zapisu polecenia do sterownika
    {
    DLCDGd = 0xFF;                                    // linie sterujace jako wyjsca
    LCDGd = 0x00;                                     //stan niski 0V na liniach sterujacych
    SET_RD;                                          // RD=1 - RD w stanie wysokim nie będziemy odczytywać danych
    SET_WR;
    dlms(1);
    SET_A0;                                          // A0=1 - zapis polecenia  poprawnie wg dokumentacji
    CLR_CS;                                          // CS - chyp selekt w stan niski
    dlns();                                          //czekaj min 30 ns ( 62,5ns czeka)
    CLR_WR;
    dlns();
    wr_lcd_bus(cmd);                                 // funkcja zapisu danej na magistrale
    }

    unsigned char lcdg_read_status(void)                    // procedura odczytu flagi statusu
    {
    unsigned char stan;
    stan=1;
    DLCDGd = 0xBF;                                    // linie danych jako wejścia
    LCDGd = 0x40;                                     // linie danych reagują na 0
    SET_WR;                                          // WR=1 - WR w stanie wysokim nie będziemy zapisywac danych/komendy
    SET_RD;
    dlms(1);
    CLR_A0;                                          // A0=0 - odczyt statusu
    CLR_CS;                                          // CS - chyp selekt w stan niski
    dlns();                                          //czekaj min 30 ns ( 62,5ns czeka)
    CLR_RD;
    dlns();
    dlns();                                       
    if(bit_is_clear(PINA,6))
    {
    stan=0;
    }
    SET_CS;                                          // CS w stan wysoki koniec obslugi SED
    SET_RD;                                          // RD w stan wysoki odczytalismy dane
    return stan;                       
    }


    void lcdg_init1(void)
    {
    lcdg_init();
    lcdg_write_cmd(0x40);   //C
    lcdg_write_data(0x38);  //P1 => DR, T/L, IV, 1, W/S, M2, M1, M0   
    lcdg_write_data(0x87);  //P2=> WF 0 0 0 0 Fx2 Fx1 Fx0 szerokosc ramki znaku
    lcdg_write_data(0x08);  //P3 => 0 0 0 0 Fy3 Fy2 Fy1 Fy0 wysokosc ramki znaku
    lcdg_write_data(0x1F);  //P4 ilosc bajtow na linie 0x20=> 31 bajtow na linie  1F
    lcdg_write_data(0x23);  //P5 TC/R = C/R+4 TC/R=32+4=36 22, 31
    lcdg_write_data(0x7F);  //P6 L/F wysokość  calkowita ekranu 127 linie na panel  3f  7F
    lcdg_write_data(0x20);  //P7
    lcdg_write_data(0x00);  //P8   szerokość całkowita wyświetlacza 2 starsze bajty bajty
    }

    void lcd_wyswietlaj(void)
    {
    lcdg_write_cmd(0x44);   //C   SCROLL
    lcdg_write_data(0x00);  //P1
    lcdg_write_data(0x00);  //P2
    lcdg_write_data(0x40);  //P3
    lcdg_write_data(0x00);  //P4
    lcdg_write_data(0x02);  //P5
    lcdg_write_data(0x40);  //P6
    lcdg_write_data(0x00);  //P7
    lcdg_write_data(0x01);  //P8   
    lcdg_write_data(0x00);  //P9
    lcdg_write_data(0x0A);  //P10

    lcdg_write_cmd(0x5A);   //C    HDOT SCR
    lcdg_write_data(0x00);  //P1

    lcdg_write_cmd(0x5B);   //C    OVLAY
    lcdg_write_data(0x01);  //P1=>   0 0 0 OV DM2 DM1 MX1 MX0   określa tyb wyświetlania

    lcdg_write_cmd(0x58);   //C    DISP ON/OFF
    lcdg_write_data(0x47);  //P1=>   FP5, FP4, FP3, FP2, FP1, FP0, FC1, FC0  włącza i wyłącza wyświetlanie
                         
    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0x00);  //P1    współrzędna CSRL
    lcdg_write_data(0x00);  //P2    współrzędna CSRH

    lcdg_write_cmd(0x5D);   //C    CSR FROM  --
    lcdg_write_data(0x07);  //P1  szerokość kursora w pikselach
    lcdg_write_data(0x08);  //P2  wysokośc kursora w liniach

    lcdg_write_cmd(0x59);   //C    DISP ON/OFF
    lcdg_write_data(0x47);  //P1=>   FP5, FP4, FP3, FP2, FP1, FP0, FC1, FC0  włącza i wyłącza wyświetlanie

    lcdg_write_cmd(0x4C);   //C    CSR DIR

    //------------------czyść pierwszy ekran LCD -----------------------------

    lcdg_write_cmd(0x42);   //C    MWRITE
    int i;
    for(i=0;i<31;i++)
    lcdg_write_data(0x20);  //P1 ' '
    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0x20);  //P1    współrzędna CSRL   ustawia w poziomie
    lcdg_write_data(0x00);  //P2    współrzędna CSRH   ustawia w pionie
    lcdg_write_cmd(0x42);   //C    MWRITE
    for(i=0;i<31;i++)
    lcdg_write_data(0x20);  //P1 ' '
    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0x40);  //P1    współrzędna CSRL   ustawia w poziomie
    lcdg_write_data(0x00);  //P2    współrzędna CSRH   ustawia w pionie
    lcdg_write_cmd(0x42);   //C    MWRITE
    for(i=0;i<31;i++)
    lcdg_write_data(0x20);  //P1 ' '
    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0x60);  //P1    współrzędna CSRL   ustawia w poziomie
    lcdg_write_data(0x00);  //P2    współrzędna CSRH   ustawia w pionie
    lcdg_write_cmd(0x42);   //C    MWRITE
    for(i=0;i<31;i++)
    lcdg_write_data(0x20);  //P1 ' '
    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0x80);  //P1    współrzędna CSRL   ustawia w poziomie
    lcdg_write_data(0x00);  //P2    współrzędna CSRH   ustawia w pionie
    lcdg_write_cmd(0x42);   //C    MWRITE
    for(i=0;i<31;i++)
    lcdg_write_data(0x20);  //P1 ' '
    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0xA0);  //P1    współrzędna CSRL   ustawia w poziomie
    lcdg_write_data(0x00);  //P2    współrzędna CSRH   ustawia w pionie
    lcdg_write_cmd(0x42);   //C    MWRITE
    for(i=0;i<31;i++)
    lcdg_write_data(0x20);  //P1 ' '
    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0xC0);  //P1    współrzędna CSRL   ustawia w poziomie
    lcdg_write_data(0x00);  //P2    współrzędna CSRH   ustawia w pionie
    lcdg_write_cmd(0x42);   //C    MWRITE
    for(i=0;i<31;i++)
    lcdg_write_data(0x20);  //P1 ' '
    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0xE0);  //P1    współrzędna CSRL   ustawia w poziomie
    lcdg_write_data(0x00);  //P2    współrzędna CSRH   ustawia w pionie
    lcdg_write_cmd(0x42);   //C    MWRITE
    for(i=0;i<31;i++)
    lcdg_write_data(0x20);  //P1 ' '

    //----------------------wyświetl znak na LCD-----------------------------

    lcdg_write_cmd(0x46);   //C    CSRW  ustawienie kursora w rządanym punkcie
    lcdg_write_data(0x00);  //P1    współrzędna CSRL   ustawia w poziomie
    lcdg_write_data(0x00);  //P2    współrzędna CSRH   ustawia w pionie
    lcdg_write_cmd(0x42);   //C    MWRITE
    for(i=0;i<1;i++)
    lcdg_write_data(0x45);  //P1 ' '
    }

    int main (void)

    {
    lcdg_init1();
    lcd_wyswietlaj();
    while(1)
    {
    dlms(200);
    }
    }   




    [Atmega162][C] Wyswietlacz Graficzny LCD SED1330f

    Za Wszelką pomoc serdecznie dziękuję :)
    Pozdrawiam

    0 11
  • #2 05 Sie 2008 22:47
    Father
    Poziom 26  

    Podejrzewam, że parametry mogą być ustawione niewłaściwie... być może adresy pamięci... ale wymaga to głębszego przeanalizowania kodu... który jest średnio czytelny....

    0
  • #3 06 Sie 2008 05:58
    wdogli
    Poziom 18  

    Witam.
    Dzięki za zainteresowanie.
    Wydaje mi sie ze nie jest to problem ustawień pamięci ustawiłem ją wg dokumentacji.
    Warstwa tekstowa:
    A więc mam wyświetlacz o rozmiarze 256x128 wielkość znaku 8 czyli na jedną linię w trybie tekstowym będzie 256/8=32 bajty ilość linii na ekranie tekstowym to 128/8=16 ale że mam panel składający się z dwóch osobnych paneli to 16/2=8.
    a więc niezbędna ilość pamięci dla ekranu tekstowego to 8*32=256bajtów

    warstwa graficzna:
    256/8=32;
    128/1=128
    128x32=4096
    4096/2=2048 wymagana ilość pamięci na jeden ekran

    i pamięć ustawiam następująco:
    0000H - 0100H => pierwsza część panelu warstwa tekstowa (256 bajtów);
    0100H - 0200H => druga część panelu warstwa tekstowa (256 bajtów);
    0200H - 0A00H => pierwsza część panelu warstwa graficzna (2048 bajtów);
    0A00H - ......... => druga część panelu warstwa graficzna (2048 bajtów);

    i za to odpowiada ta część kodu:


    Code:

    lcdg_write_cmd(0x44);   //C   SCROLL
    lcdg_write_data(0x00);  //P1
    lcdg_write_data(0x00);  //P2
    lcdg_write_data(0x40);  //P3
    lcdg_write_data(0x00);  //P4
    lcdg_write_data(0x02);  //P5
    lcdg_write_data(0x40);  //P6
    lcdg_write_data(0x00);  //P7
    lcdg_write_data(0x01);  //P8   
    lcdg_write_data(0x00);  //P9
    lcdg_write_data(0x0A);  //P10

    0
  • #4 06 Sie 2008 08:48
    Father
    Poziom 26  

    Być może pomoże zmiana param. P3/P6 z 40H na 3FH... nie zrobiłem jeszcze płytki pod kontroler do tego wyświetlacza wiec nie mam jak sprawdzić...

    0
  • #6 06 Sie 2008 22:13
    wdogli
    Poziom 18  

    Witam.

    rcpilot :arrow: wielkie dzięki za link który mi podesłałeś ale po przeanalizowaniu w/w programu mogę stwierdzić ze w części wyświetlania tekstu nie różni sie on od mojego jeśli chodzi o zasadę działania a jedynie sposobem napisania kodu no i oczywyście tym że w/w program jest napisany dla wyświetlacza jedno panelowego natomiast mój jest dwu panelowy.

    Poza tym dziś miałem czas i dalej testowałem wyświetlacz i oto wyniki które uzyskałem.
    A więc przy zmianie kierunku pisania z pisz w prawo na pisz w dół uzyskałem dwa równoległe napisy EPSON oddalone od siebie o spację.
    Poza tym dla przetestowania poprawności zdefiniowania zakresów pamięci kazałem mu wyświetlić te napisy w czterech rogach wyświetlacza i tutaj wszystko sie zgadza.
    Jedynym problemem jaki mam nadal to jest to:
    Dlaczego wypisując jeden napis EPSON na wyświetlaczu w sumie dostaję dwa oddalone od siebie o jedną spację.
    Poniżej zamieszczam zdjęcie wyświetlacza z dzisiejszymi wynikami pracy
    No i oczywiście liczę na jakieś wasze sugestje co z tym dalej począć???
    Serdecznie pozdrawiam
    [Atmega162][C] Wyswietlacz Graficzny LCD SED1330f

    P.S.

    Tak sie dzieje gdy próbuję ten sam napis EPSON wyświetlić w poziomie

    [Atmega162][C] Wyswietlacz Graficzny LCD SED1330f

    0
  • Pomocny post
    #7 06 Sie 2008 22:17
    Samuraj
    Poziom 35  

    A może jest zwarcie na liniach adresowych pamięci - oba adresy pamięci odwołują się do tego samego obszaru. NIc innego nie przychodzi mi do głowy, a na poprzednich screnach tak by wychodziło.
    Radzę sprawdzić linie adresowe pamięci.

    0
  • #8 06 Sie 2008 22:46
    wdogli
    Poziom 18  

    Witam
    Samuraj :arrow: to było właśnie to co mu było.
    Teraz wszystko jest jak powinno być.
    Serdecznie dziękuję za pomoc. :)
    Pozdrawiam

    0
  • #9 05 Sty 2009 18:17
    JaSHyN
    Poziom 9  

    Witam.
    Może późno, ale czy mogłym sie dowiedzieć jakie napięcia są na pinach 1 - Vcc, 2 - Vss i 3 - Vee ?
    Być może jest to kwestia zbyt małego odświeżania (ATMEGA8 przy 16 MHz) , bo u mnie nie chcą poszczególne piksele wyświetlać się tak jak powinny.

    Pozdrawiam.
    Jacek.

    0
  • #10 07 Sty 2009 13:05
    wdogli
    Poziom 18  

    Kontrast mam zbudowany na ICL7662. Kontrast jest podłączony względem zasilania a więc na zasilaniu kontrastu względem VCC mam -17,5 natomiast względem masy mam -12,5 czyli 17,5-12,5=5V czyli VCC.
    Jesli chodzi o napięcie kontrastu nie jest podpięte bezpośrednio do wyświetlacza tylko poprzez oporek regulowany 10kOm i do masy.
    dokładny schemat leży tutaj Link

    0
  • #11 07 Maj 2009 20:47
    kubiaczek1982
    Poziom 11  

    witam.

    Próbuje rozszyfrować pierwszy kod w poście. Mógłby ktoś wytłumaczyć co znaczą linie w stylu

    Code:
    #define SET_CS   LCDG |= _BV(CS) 
    ??

    0
  • #12 07 Maj 2009 21:15
    zdebel
    Poziom 14  

    Jest to makro, które zmienną LCDG OR-uje z linią na której jest CS, w sensie że _BV zwraca liczbę dla danego pinu (nie wiem jak to się fachowo nazywa) ale np. dla PA0 byłoby to 0x0000001, dla PA1 0x00000010 itd.

    0