logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

AtMega 32 [C] Problem wyświetlaniem na LCD KS0180

Dachno 28 Gru 2010 14:33 4135 13
REKLAMA
  • #1 8923831
    Dachno
    Poziom 9  
    Witam.

    Otóż mam nie mały problem, mianowicie mam Zestaw Uruchomieniowy EvB 4.3v4 oraz dokupiłem sobie LCD graficzny 128064-CF typu ChipOnGlass LED (White/Blue)

    Link usunąłem - jeden wystarczy.
    [zumek]


    NOTA KATALOGOWA http://artronic.pl/o_produkcie.php?id=1145?

    Co prawda w nocie katalogowej jest podany inny sterownik, ale dobrze działa również pod sterownikiem KS0180. Próbowałem uruchomić jakiś program ze strony radzia http://en.radzio.dxp.pl/ks0108/ za pomocą tego właśnie sterownika, lecz tam jest więcej portów niż ja mam wyjściowych, ponieważ w moim LCD po zlutowaniu wszystkich nóżek tak jak w nocie katalogowej jest tylko 7 wyjść: (CS, RST, A0, S-CLK, S-DATA-INPUT, +, -) a w bibliotece od radzia jest:
    KS0108-AVR.c
    
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    
    #define KS0108_DATA_PORT	PORTA
    #define KS0108_DATA_DIR		DDRA
    #define KS0108_DATA_PIN		PINA
    
    #define KS0108_CTRL_PORT	PORTC
    #define KS0108_CTRL_DIR		DDRC
    
    #define KS0108_RS			(1 << 2)
    #define KS0108_RW			(1 << 1)
    #define KS0108_EN			(1 << 0)
    
    #define KS0108_CS1			(1 << 6)
    #define KS0108_CS2			(1 << 5)
    #define KS0108_CS3			(1 << 5)
    
    extern unsigned char screen_x;
    extern unsigned char screen_y;
    
    #define DISPLAY_STATUS_BUSY	0x80
    
    //-------------------------------------------------------------------------------------------------
    // Delay function
    //-------------------------------------------------------------------------------------------------
    void GLCD_Delay(void)
    {
    asm("nop");
    }
    //-------------------------------------------------------------------------------------------------
    // Enalbe Controller (0-2)
    //-------------------------------------------------------------------------------------------------
    void GLCD_EnableController(unsigned char controller)
    {
    switch(controller){
    	case 0 : KS0108_CTRL_PORT &= ~KS0108_CS1; break;
    	case 1 : KS0108_CTRL_PORT &= ~KS0108_CS2; break;
    	case 2 : KS0108_CTRL_PORT &= ~KS0108_CS3; break;
    	}
    }
    //-------------------------------------------------------------------------------------------------
    // Disable Controller (0-2)
    //-------------------------------------------------------------------------------------------------
    void GLCD_DisableController(unsigned char controller)
    {
    switch(controller){
    	case 0 : KS0108_CTRL_PORT |= KS0108_CS1; break;
    	case 1 : KS0108_CTRL_PORT |= KS0108_CS2; break;
    	case 2 : KS0108_CTRL_PORT |= KS0108_CS3; break;
    	}
    }
    //-------------------------------------------------------------------------------------------------
    // Read Status from specified controller (0-2)
    //-------------------------------------------------------------------------------------------------
    unsigned char GLCD_ReadStatus(unsigned char controller)
    {
    unsigned char status;
    KS0108_DATA_DIR = 0x00;
    KS0108_CTRL_PORT |= KS0108_RW;
    KS0108_CTRL_PORT &= ~KS0108_RS;
    GLCD_EnableController(controller);
    KS0108_CTRL_PORT |= KS0108_EN;
    GLCD_Delay();
    status = KS0108_DATA_PIN;
    KS0108_CTRL_PORT &= ~KS0108_EN;
    GLCD_DisableController(controller);
    return status;
    }
    //-------------------------------------------------------------------------------------------------
    // Write command to specified controller
    //-------------------------------------------------------------------------------------------------
    void GLCD_WriteCommand(unsigned char commandToWrite, unsigned char controller)
    {
    while(GLCD_ReadStatus(controller)&DISPLAY_STATUS_BUSY);
    KS0108_DATA_DIR = 0xFF;
    KS0108_CTRL_PORT &= ~(KS0108_RW | KS0108_RS);
    GLCD_EnableController(controller);
    KS0108_DATA_PORT = commandToWrite;
    KS0108_CTRL_PORT |= KS0108_EN;
    GLCD_Delay();
    KS0108_CTRL_PORT &= ~KS0108_EN;
    GLCD_DisableController(controller);
    }
    //-------------------------------------------------------------------------------------------------
    // Read data from current position
    //-------------------------------------------------------------------------------------------------
    unsigned char GLCD_ReadData(void)
    {
    unsigned char data;
    while(GLCD_ReadStatus(screen_x / 64)&DISPLAY_STATUS_BUSY);
    KS0108_DATA_DIR = 0x00;
    KS0108_CTRL_PORT |= (KS0108_RW | KS0108_RS);
    GLCD_EnableController(screen_x / 64);
    //GLCD_Delay();
    KS0108_CTRL_PORT |= KS0108_EN;
    GLCD_Delay();
    data = KS0108_DATA_PIN;
    KS0108_CTRL_PORT &= ~KS0108_EN;
    GLCD_DisableController(screen_x / 64);
    screen_x++;
    return data;
    }
    //-------------------------------------------------------------------------------------------------
    // Write data to current position
    //-------------------------------------------------------------------------------------------------
    void GLCD_WriteData(unsigned char dataToWrite)
    {
    while(GLCD_ReadStatus(screen_x / 64)&DISPLAY_STATUS_BUSY);
    KS0108_DATA_DIR = 0xFF;
    KS0108_CTRL_PORT &= ~KS0108_RW;
    KS0108_CTRL_PORT |= KS0108_RS;
    KS0108_DATA_PORT = dataToWrite;
    GLCD_EnableController(screen_x / 64);
    KS0108_CTRL_PORT |= KS0108_EN;
    GLCD_Delay();
    KS0108_CTRL_PORT &= ~KS0108_EN;
    GLCD_DisableController(screen_x / 64);
    screen_x++;
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    void GLCD_InitalizePorts(void)
    {
    KS0108_CTRL_DIR |= (KS0108_CS1 | KS0108_CS2 | KS0108_CS3 | KS0108_RS | KS0108_RW | KS0108_EN);
    KS0108_CTRL_PORT |= (KS0108_CS1 | KS0108_CS2 | KS0108_CS3);
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    unsigned char GLCD_ReadByteFromROMMemory(char * ptr)
    {
    return pgm_read_byte(ptr);
    }
    //-------------------------------------------------------------------------------------------------
    //
    


    KS0108.h
     
    
    #define KS0108_SCREEN_WIDTH	128
    #define KS0108_SCREEN_HEIGHT	64
    
    
    #define DISPLAY_SET_Y       0x40
    #define DISPLAY_SET_X       0xB8
    #define DISPLAY_START_LINE  0xC0
    #define DISPLAY_ON_CMD		0x3E
      #define ON	0x01
      #define OFF	0x00
    #define DISPLAY_STATUS_BUSY	0x80
    
    void GLCD_Initalize(void);
    void GLCD_WriteData(unsigned char);
    void GLCD_WriteCommand(unsigned char, unsigned char);
    void GLCD_ClearScreen(void);
    void GLCD_GoTo(unsigned char, unsigned char);
    void GLCD_WriteString(char *);
    unsigned char GLCD_ReadByteFromROMMemory(char *);
    unsigned char GLCD_ReadData(void);
    void GLCD_Bitmap(char *, unsigned char, unsigned char, unsigned char, unsigned char);
    


    KS0108.c
     //-------------------------------------------------------------------------------------------------
    // Universal KS0108 driver library
    // (c) Radosław Kwiecień, radek@dxp.pl
    //-------------------------------------------------------------------------------------------------
    #include "KS0108.h"
    #include "font5x8.h"
    //-------------------------------------------------------------------------------------------------
    extern void GLCD_InitalizePorts(void);
    //-------------------------------------------------------------------------------------------------
    unsigned char screen_x = 0, screen_y = 0;
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    void GLCD_Initalize(void)
    {
    unsigned char i;
    GLCD_InitalizePorts();
    for(i = 0; i < 3; i++)
      GLCD_WriteCommand((DISPLAY_ON_CMD | ON), i);
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    void GLCD_GoTo(unsigned char x, unsigned char y)
    {
    unsigned char i;
    screen_x = x;
    screen_y = y;
    
    for(i = 0; i < KS0108_SCREEN_WIDTH/64; i++)
      {
      GLCD_WriteCommand(DISPLAY_SET_Y | 0,i);
      GLCD_WriteCommand(DISPLAY_SET_X | y,i);
      GLCD_WriteCommand(DISPLAY_START_LINE | 0,i);
      }
    GLCD_WriteCommand(DISPLAY_SET_Y | (x % 64), (x / 64));
    GLCD_WriteCommand(DISPLAY_SET_X | y, (x / 64));
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    void GLCD_ClearScreen(void)
    {
    unsigned char i, j;
    for(j = 0; j < KS0108_SCREEN_HEIGHT/8; j++)
      {
      GLCD_GoTo(0,j);
      for(i = 0; i < KS0108_SCREEN_WIDTH; i++)
        GLCD_WriteData(0x00);
      }
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    void GLCD_WriteChar(char charToWrite)
    {
    int i;
    charToWrite -= 32; 
    for(i = 0; i < 5; i++) 
      GLCD_WriteData(GLCD_ReadByteFromROMMemory((char *)((int)font5x8 + (5 * charToWrite) + i))); 
    GLCD_WriteData(0x00);
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    void GLCD_WriteString(char * stringToWrite)
    {
    while(*stringToWrite)
      GLCD_WriteChar(*stringToWrite++);
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    void GLCD_SetPixel(unsigned char x, unsigned char y, unsigned char color)
    {
    unsigned char tmp;
    GLCD_GoTo(x, (y / 8));
    tmp = GLCD_ReadData();
    GLCD_GoTo(x, (y / 8));
    tmp = GLCD_ReadData();
    GLCD_GoTo(x, (y / 8));
    tmp |= (1 << (y % 8));
    GLCD_WriteData(tmp);
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
    void GLCD_Bitmap(char * bmp, unsigned char x, unsigned char y, unsigned char dx, unsigned char dy)
    {
    unsigned char i, j;
    for(j = 0; j < dy / 8; j++)
      {
      GLCD_GoTo(x,y + j);
      for(i = 0; i < dx; i++) 
        GLCD_WriteData(GLCD_ReadByteFromROMMemory(bmp++));
      }
    }
    //-------------------------------------------------------------------------------------------------
    //
    //-------------------------------------------------------------------------------------------------
     


    które nijak sie pokrywają z moimi wyjściami...

    I nie mam za bardzo pojęcia jak pozmieniać te porty i dostosować do moich ;/

    Udało mi się znaleźć inna bibliotekę, dokładnie to: ST7565 oraz uruchomiłem program lecz, po wgraniu go do procka mam taki efekt:

    AtMega 32 [C] Problem wyświetlaniem na LCD KS0180


    I moje dwie zasadnicze prośby i pytania to:
    1] Czy byłby ktoś tak łaskawy i przerobił mi te biblioteki od radzia na moje 7 wyjść praktycznie to 5 wyjść do procka bo dwa są od zasilania...

    2] Czym jest spowodowane to, że na wyświetlaczu mam takie "zacieki" od napisów które wyświetla mi LCD? Prawidłowo powinno być niebieskie podświetlenie i białe napisy a jest ciemno szare podświetlenie i ciemno-białe napisy;/

    Proszę o jakieś podpowiedzi i pomoce. Z góry dziękuje i pozdrawiam...
  • REKLAMA
  • #2 8924466
    tmf
    VIP Zasłużony dla elektroda
    A skąd pomysł, że te wyświetlacz ma sterownik KS0108? On ma ST7565R, w dodatku w trybie szeregowym, gdzie masz interfejs SPI, w dodatku niepełny, bo możesz tylko zapisywać. W efekcie ten LCD jest małoprzydatny, bo musiałbyś mieć kopię VRAM w pamięci mikrokontrolera, chyba, że będziesz go wykorzystywał wyłącznie jako LCD alfanumeryczny.
    A zacieki są najpewniej spowodowane złym kontrastem (ustawiasz za wysoki) lub złą jakością tego LCD. Najpewniej jednym i drugim.
  • #3 8924578
    szelus
    Poziom 34  
    A kondensatory, pokazane w nocie katalogowej, masz podłączone?
  • REKLAMA
  • #4 8924687
    Dachno
    Poziom 9  
    Do "szelus"

    Tak, kondensatory mam podłączone tak jak w nocie katalogowej wszystko...

    Do tmf

    A no stąd ten pomysł, że napisałem maila do gościa który sprzedaje te LCD'ki i napisał mi,
    Cytuję:
    "Nie wiem czy jest biblioteka do ST7565R w C
    Organizacja pamięci obrazu jest analogiczna jak w KS0108A
    Słyszałem, że jeden z klientów zaadoptował tą bibliotekę."

    A LCD nie tylko chcę używać jako alfanumeryczny ale jako graficzny...
    Czyli nie mogę zrobić nic innego? Ze strony sprzętowej, na pewno jest wszystko ok polutowane, bo robił mi to elektronik, patrząc na notę katalogową...
  • #5 8924976
    szelus
    Poziom 34  
    Czytałeś dokumentację kontrolera?
    Ja widzę, że jest trochę komend sterujących napięciami/fazami do wyświetlacza. Niewłaściwie ustawione (jak pisał tmf), dadzą takie efekty.
    Nie wiem, jakie są domyślne w tej bibliotece, ale moim zdaniem trzeba się wgryźć w tę dokumetację i trochę pokombinować.
  • #6 8924984
    tmf
    VIP Zasłużony dla elektroda
    Organizacja pamięci obrazu praktycznie w każdym kontrolerze jest taka sama, co jak się domyślasz nic nie znaczy. Jednak jest to banalnie prosty kontroler i z adaptacja nie powinno być problemów. Musisz przerobić procedury tak, żeby korzystały z SPI (KS ma interfejs równoległy), co jest banalne. Gorzej, że ten twój nie umożliwia odczytu pamięci VRAM przez SPI. W efekcie jak chcesz postawić pixel nie zacierając 7 sąsiednich? Musisz gdzieś trzymać kopię VRAM i na niej operować. Co wykorzystuje ci na wstępie 1kB pamięci SRAM ATMegi32 (czyli 50%). Następnym razem przed zakupem lepiej sprawdź co kupujesz.
  • REKLAMA
  • #7 8925251
    Dachno
    Poziom 9  
    A znacie może jakieś przykłady które rozwiązałyby mój problem?

    Bo powiem szczerze, o tym co napisał tmf nie mam bladego pojęcia...

    Oczywiście, również przeszukam neta, lecz za wszystkie podpowiedzi będę bardzo wdzięczny..
  • #8 8925308
    tmf
    VIP Zasłużony dla elektroda
    Ale jaki problem? Z zaciekami? Zmień napięcie na pinie regulującym kontrast, stracisz na kontraście ale zacieki powinny zniknąć.
  • REKLAMA
  • #9 8925340
    Dachno
    Poziom 9  
    Ok, a mógłbyś podać jakiś prosty program, najprostszy, ale w takim stylu jaki mi opisałeś z tym SPI ale tak żeby chodziło na moim LCD(bo ja nie mam pojęcia jak się za to zabrać).

    Bardzo Proszę o to.

    P.S. Na przyszłość to jak mam wybierać i na co zwracać uwagę w LCD żeby normalnie się go programowało i nie było takich problemów jak te..?
  • #10 8925369
    tmf
    VIP Zasłużony dla elektroda
    Ale jak rozumiem znalazłeś bibliotekę obsługującą twój LCD? I to ci przecież działa?
    Ten LCD jest ok, tylko jak pisałem w trybie SPI, w którym pracuje możesz tylko zapisywać do VRAM i w tym problem. Jeśli możesz poświęcić 1kB RAM procesora to stwórz w tym obszarze kopię VRAM. To będzie wymagało pewnie dosyć poważnej modyfikacji używanej przez ciebie biblioteki.
  • #11 8925422
    Dachno
    Poziom 9  
    Odnośnie kontrastu, to dołożyłem nawet drugi opornik szeregowo i razem było 200Ω i kontrast był niski ale zacieki nawet trochę nie zniknęły ;/ więc wróciłem do jednego opornika 100Ω...

    Tak biblioteke mam do tego LCD ST7565 lecz są te zacieki jak na foto wyżej...
  • #12 8925451
    tmf
    VIP Zasłużony dla elektroda
    IMHO te zacieki wynikają ze słabej jakości LCD i nic na to nie poradzisz. To są stare, tanie matryce. Niestety porządne swoje kosztują.
  • Pomocny post
    #13 8925470
    szelus
    Poziom 34  
    W nocie katalogowej znalazłem taki hint:
    Cytat:

    Bias: 1/7, VLCD=8.5V, VDD=3.3V

    Z tego by wynikało, że LCD bias należy ustawić na 1 komendą (11) - 0xA3.
    Z kolei na podstawie obrazka 9 w dokumentacji kontrolera, że przy zasilaniu 3.3V (takie masz, prawda?) powinno się ustawić "V5 internal resistance ratio" na wartość 110 binarnie - komendą (17) 0x26.
    Natomiast wewnętrzny potencjometr kontrastu gdzieś na połowę zakresu - komendą (18) sekwencją 0x81, 0x20.
    Numery komend z tabelki 16.
    Sprawdź, co robi ta biblioteka przy inicjalizacji. Sprawdź też, jak wysyła komendę (16) - power control set.

    Dodano po 3 [minuty]:

    Dachno napisał:
    Odnośnie kontrastu, to dołożyłem nawet drugi opornik szeregowo i razem było 200Ω i kontrast był niski ale zacieki nawet trochę nie zniknęły ;/ więc wróciłem do jednego opornika 100Ω...


    Gdzie dałeś ten rezystor kontrastu??? W nocie nic takiego nie ma, bo z tym sterownikiem ustawia się kontrast programowo! Przynajmniej tak wynika z dokumentacji...
  • #14 8925519
    Dachno
    Poziom 9  
    tak tak, sorry dołożyłem drugi opornik ale to do podświetlenia jest a nie do kontrastu... Mój błąd... Dlatego nic mi to nie dało heh...

    Dodano po 1 [godziny] 13 [minuty]:

    Do szelus

    Skromnie pisząc :D zaznaczam skromnie, jesteś WIELKI :D w tym był problem,
    Wystarczyło zmienić wartość którą podałeś

    "V5 internal resistance ratio" na wartość 110 binarnie - komendą (17) 0x26.

    I zaczęło działać jak za dotknięciem czarodziejskiej różdżki :D

    Oto dzieło finalne :D

    AtMega 32 [C] Problem wyświetlaniem na LCD KS0180


    Temat zamykam i Wielkie podziękowania dla Wszystkich którzy zaangażowali się w pomoc :)
REKLAMA