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

[C]Problem z wyświetlaczem 128x64 - Nadal nie rozwiązany

Yazutsu 13 Lis 2010 18:35 2025 9
REKLAMA
  • #1 8739073
    Yazutsu
    Poziom 10  
    Witam

    Posiadam taki wyświetlacz : Link

    Wyświetlacz sprawdziłem używając przykładu z tej strony : Link Działa, torchę się rozjeżdza ale przynajmniej coś wyświetla.

    Natomiast do jego obsługi chciałbym wykorzystać funkcje z tej strony: http://radzio.dxp.pl/ks0108/

    Problem mam z odczytem flagi BUSY.

    W tej funkcji:
    void lcdWait(void)
    {
    LCD_DATA_DDR = 0x00; // ustawienie portu danych w tryb wejściowy
    CLR_RS(); // niski stan na linii RS -> odczyt rejestru statusu
    SET_RW(); // wysoki stan na linii RW -> odczyt z wyświetlacza
    do { //pętla
    delay(); // opóźnienie
    SET_EN(); // ustaw linię EN
    delay(); // opóźnienie
    CLR_EN(); // wyzeruj linię EN
    } while((LCD_DATA_PIN & DISPLAY_STATUS_BUSY)); // powtarzaj do
    // wyzerowania flagi BUSY
    }


    pętla do...while zapętla się na wieczność.

    Jeszcze przy okazji mam pytanie o podłączenie pinu RESET z wyświetlacza, różnie ludzie piszą, generalnie próbowałem podłączać do
    +5V bezpośrednio(wtedy na ekranie pojawiają się krzaki-nawet bez wgranego softu)
    +5 przez rezystor 4,7k (nic się nie wyświetla).

    Może ktoś ma taki sam i też z nim walczył...ja męczę się juz 3 dzień(noc) :/
  • REKLAMA
  • #2 8739198
    asembler
    Poziom 32  
    Czy potrzebny ci odczyt danych z wyswietlacza? i do czego?
  • REKLAMA
  • #3 8739319
    Yazutsu
    Poziom 10  
    potrzebne mi jest wyświetlenie na razie czegokolwiek na wyświetlaczu, jeśli da się jakoś zastąpić odczyt tej flagi to bardzo chciałbym wiedzieć jak.

    A może tak teraz myślę że coś z tym resetem jest nie tak, może on blokuje (ustawia flage na busy)?

    No przecież ludzie jakoś używają tych wyświetlaczy, na sterowniku właśnie KS0108, nie rozumiem dlaczego tak ciężko znaleźć sprawne biblioteki.
  • REKLAMA
  • #4 8739349
    asembler
    Poziom 32  
    Do wyswietlanie czegokolwiek niepotrzebny jest odczyt z wyswietlacza czyli cala ta procedura też.
  • #5 8739392
    Yazutsu
    Poziom 10  
    Kiedy ta funkcja używana jest w innych funkcjach:

    lcdWait(); // oczekiwanie na gotowość kontrolera

    po prostu ją wyciąć?
  • #6 8739437
    asembler
    Poziom 32  
    W niektórych przypadkach trzebaby zastąpic ją poprostu funkcją delay w zleznosci od wyslanego rozkazu do wysiwetlacza co prawdopodobnie jest opisane w nocie tak aby wyswietlacz mial czas na wykonanie polecenia.
  • #7 8739534
    Yazutsu
    Poziom 10  
    niestety nic to nie dało, pozastępowałem delayem na 5ms i nic.

    Może po koleii, co mam podać że ktoś był w stanie mi pomóc?

    Zacznę od :

    wszystkie funkcje do obsługi wyświetlacza wrzuciłem ze strony http://radzio.dxp.pl/ks0108/

    tak wyglądają moje definicje:
    
    #define DISPLAY_STATUS_BUSY    0x80
    #define DISPLAY_SET_X 0x40
    #define DISPLAY_SET_Y 0xB8
    //#define DISPLAY_SET_X 0xB8
    //#define DISPLAY_SET_Y 0x40
    #define DISPLAY_START_LINE 0xC0 
    #define DISPLAY_ON_CMD        0x3E
     #define ON    0x01
     #define OFF    0x00 
    
    // port szyny danych
    #define LCD_DATA_PORT PORTA
    #define LCD_DATA_PIN PINA
    #define LCD_DATA_DDR DDRA
    // port sygnałów sterujących
    #define LCD_CTRL_PORT PORTD
    #define LCD_CTRL_PIN PIND
    #define LCD_CTRL_DDR DDRD
    // sygnały sterujące
    #define LCD_CS1P PD0
    #define LCD_CS2P PD1
    #define LCD_EN PD4
    #define LCD_RW PD6
    #define LCD_RS PD3


    main:
    
    int main()
    {
    lcdInit();
    lcdOn();
    lcdCls();
    lcdGoTo(0,0);
    lcdWriteString("napis");
    return 0;
    }


    Program się kompiluje i wykonuje do końca.

    aha dokumentacja wyświetlacza jest TUTAJ

    Co jeszcze podać?

    Dodano po 2 [godziny] 48 [minuty]:

    Naprawdę nikt nie ma pomysłu? popełniam jakiś błąd...
  • #8 8740719
    asembler
    Poziom 32  
    Powyzej to cały twój kod?
  • #9 8740729
    Yazutsu
    Poziom 10  
    to jest cały kod:
    
    
    
    
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/pgmspace.h>
    #include "lib/font5x7.h"
    
    unsigned char lcd_x, lcd_y;
    
    
    #define setbit(zmienna, bit)	zmienna |= (1 << bit)					// Ustawia 'bit' w 'zmiennej'
    #define clrbit(zmienna, bit)	zmienna &= ~(1 << bit)					// Kasuje 'bit' w 'zmiennej'
    #define invbit(zmienna, bit)	zmienna ^= (1 << bit)					// Zmienia stan 'bit'-u na przeciwny
    
    
    #define DISPLAY_STATUS_BUSY    0x80
    #define DISPLAY_SET_X 0xB8
    #define DISPLAY_SET_Y 0x40
    //#define DISPLAY_SET_X 0xB8
    //#define DISPLAY_SET_Y 0x40
    #define DISPLAY_START_LINE 0xC0 
    #define DISPLAY_ON_CMD        0x3E
      #define ON    0x01
      #define OFF    0x00 
    
    
    
    // port szyny danych
    #define LCD_DATA_PORT PORTC
    #define LCD_DATA_PIN PINC
    #define LCD_DATA_DDR DDRC
    // port sygnałów sterujących
    #define LCD_CTRL_PORT PORTD
    #define LCD_CTRL_PIN PIND
    #define LCD_CTRL_DDR DDRD
    // sygnały sterujące
    
    #define LCD_CS1P PD5
    #define LCD_CS2P PD6
    #define LCD_EN PD0
    #define LCD_RW PD3
    #define LCD_RS PD2 
    
    //#define LCD_CS1P (PIND, 0)
    //#define LCD_CS2P (PIND, 1)
    //#define LCD_EN 	(PIND, 4)
    //#define LCD_RW (PIND, 6)
    //#define LCD_RS (PIND, 3)
    
    
    /*
    // makroinstrukcje ustawienia stanu na linii CS1
    #define SET_CS1() (LCD_CTRL_PORT |= (1 << LCD_CS1P))
    #define CLR_CS1() (LCD_CTRL_PORT &= ~(1 << LCD_CS1P))
    // makroinstrukcje ustawienia stanu na linii CS2
    #define SET_CS2() (LCD_CTRL_PORT |= (1 << LCD_CS2P))
    #define CLR_CS2() (LCD_CTRL_PORT &= ~(1 << LCD_CS2P))
    */
    
    // makroinstrukcje ustawienia stanu na linii CS1
    #define CLR_CS1() (LCD_CTRL_PORT |= (1 << LCD_CS1P))
    #define SET_CS1() (LCD_CTRL_PORT &= ~(1 << LCD_CS1P))
    // makroinstrukcje ustawienia stanu na linii CS2
    #define CLR_CS2() (LCD_CTRL_PORT |= (1 << LCD_CS2P))
    #define SET_CS2() (LCD_CTRL_PORT &= ~(1 << LCD_CS2P))
    
    
    
    // makroinstrukcje ustawienia stanu na linii EN
    #define SET_EN() (LCD_CTRL_PORT |= (1 << LCD_EN))
    #define CLR_EN() (LCD_CTRL_PORT &= ~(1 << LCD_EN))
    // makroinstrukcje ustawienia stanu na linii RW
    #define SET_RW() (LCD_CTRL_PORT |= (1 << LCD_RW))
    #define CLR_RW() (LCD_CTRL_PORT &= ~(1 << LCD_RW))
    // makroinstrukcje ustawienia stanu na linii RS
    #define SET_RS() (LCD_CTRL_PORT |= (1 << LCD_RS))
    #define CLR_RS() (LCD_CTRL_PORT &= ~(1 << LCD_RS))
    // makroinstrukcje ustawiajace odpowiednią kombinację sygnałów CS1 i CS2
    
    /*
    #define LCD_CS0() CLR_CS1();SET_CS2();
    #define LCD_CS1() SET_CS1();CLR_CS2();
    */
    #define LCD_CS0() SET_CS2();CLR_CS1();
    #define LCD_CS1() CLR_CS2();SET_CS1();
    
    
    #define LCD_NOCS() SET_CS1();SET_CS2();
    
    void lcdInit(void)
    {
    LCD_DATA_DDR = 0xFF;
    LCD_CTRL_DDR = 0xFF;
    }
    
    void delay(void)
    {
    asm("nop");asm("nop");
    }
    
    void lcdWait(void)
    {
    LCD_DATA_DDR = 0x00; // ustawienie portu danych w tryb wejściowy
    CLR_RS(); // niski stan na linii RS -> odczyt rejestru statusu
    SET_RW(); // wysoki stan na linii RW -> odczyt z wyświetlacza
    do { //pętla
    //invbit(PORTB,PB5);_delay_ms(100);invbit(PORTB,PB5);_delay_ms(100);
    delay(); // opóźnienie
    SET_EN(); // ustaw linię EN
    delay(); // opóźnienie
    CLR_EN(); // wyzeruj linię EN
    } while((LCD_DATA_PIN & DISPLAY_STATUS_BUSY)); // powtarzaj do wyzerowania flagi BUSY
    }
    
    void lcdWriteCmd(unsigned char x)
    {
    
    
    //
    lcdWait();
    CLR_RS();
    CLR_RW();
    LCD_DATA_DDR = 0xFF;
    LCD_DATA_PORT = x;
    SET_EN();
    delay();
    CLR_EN();
    }
    
    void lcdWriteData(unsigned char data)
    {
    if(lcd_x < 64) // jeśli współrzędna x wyświetlacza < 64
    {LCD_CS0()} // to zapisujemy do pierwszego kontrolera
    else // w przeciwnym razie
    {LCD_CS1()} // zapisujemy do drugiego kontrolera
    //_delay_ms(5);//
    lcdWait(); // oczekiwanie na gotowość kontrolera
    SET_RS(); // wysoki stan na linii RS -> dane
    CLR_RW(); // niski stan na linii RW -> zapis
    LCD_DATA_DDR = 0xFF; // port danych -> wyjście
    LCD_DATA_PORT = data; // wystawienie na port danej
    SET_EN(); // wysoki stan na linii EN
    delay(); // opóźnienie
    CLR_EN(); // niski stan na linii EN
    lcd_x++; // zwiększenie współrzędnej x wyświetlacza (pomocniczej)
    if(lcd_x > 127) // jesli koniec ekranu
    lcd_x = 0; // to wyzeruj współrzędną x
    LCD_NOCS();
    }
    
    
    unsigned char lcdReadData(void)
    {
    unsigned char data;
    if(lcd_x < 64) // jeśli współrzędna x wyświetlacza < 64
    {LCD_CS0()} // to odczytujemy z pierwszego kontrolera
    else // w przeciwnym razie
    {LCD_CS1()} // odczytujemy z drugiego kontrolera
    //_delay_ms(5);//
    lcdWait(); // oczekiwanie na gotowość kontrolera
    SET_RS(); // wysoki stan na linii RS -> dane
    SET_RW(); // wysoki stan na linii RW -> odczyt
    SET_EN(); // wysoki stan na linii EN
    delay(); // opóźnienie
    LCD_DATA_DDR = 0x00; // ustawienie portu danych w tryb wejsciowy
    data = LCD_DATA_PIN; // odczyt danych z portu
    CLR_EN(); // niski stan na linii EN
    lcd_x++; // zwiększenie współrzędnej x wyświetlacza
    if(lcd_x > 127) // jesli koniec ekranu
    lcd_x = 0; // to wyzeruj współrzędną x
    LCD_NOCS();
    return data;
    }
    
    void lcdGoTo(unsigned char x, unsigned char y)
    {
    lcd_x = x; // przypisanie współrzędym globalnym nowych wartości
    lcd_y = y;
    if(lcd_x > 63) // jeśli współrzędna pozioma jest większa od 64 to
    {
    LCD_CS1(); // uaktywnienie drugiego kontrolera
    lcdWriteCmd(DISPLAY_SET_X | lcd_y); // zapis współrzędnej pionowej
    lcdWriteCmd(DISPLAY_SET_Y | (lcd_x - 64)); // zapis współrzędnej poziomej
    }
    else // w przeciwnym razie
    {
    
    LCD_CS0(); // uatywnienie pierwszego kontrolera
    
    lcdWriteCmd(DISPLAY_SET_X | lcd_y); // zapis współrzędnej pionowej
    lcdWriteCmd(DISPLAY_SET_Y | lcd_x); // zapis współrzędnej poziomej
    
    
    LCD_CS1(); // uaktywnienie drugiego kontrolera
    
    
    
    
    
    
    lcdWriteCmd(DISPLAY_SET_X | lcd_y); // zapis współrzędnej pionowej // <----tu staje program
    
    
    
    
    lcdWriteCmd(DISPLAY_SET_Y | 0 ); // wyzerowanie współrzędnej poziomej
    
    
    
    
    }
    LCD_CS0(); // uaktywnienie pierwszego kontrolera
    lcdWriteCmd(DISPLAY_START_LINE | 0); //
    LCD_CS1(); // uaktywnienie drugiego kontrolera
    lcdWriteCmd(DISPLAY_START_LINE | 0);
    LCD_NOCS();
    
    
    }
    
    
    void lcdOn(void)
    {
    LCD_CS0(); // aktywny pierwszy kontroler
    lcdWriteCmd(DISPLAY_ON_CMD | ON); // włączenie wyświetlania danych
    LCD_CS1(); // aktywny drugi kontroler
    lcdWriteCmd(DISPLAY_ON_CMD | ON); // włączenie wyświetlania danych
    LCD_NOCS(); //
    }
    
    
    void lcdOff(void)
    {
    LCD_CS0(); // aktywny pierwszy kontroler
    lcdWriteCmd(DISPLAY_ON_CMD | OFF); // wyłączenie wyświetlania danych
    LCD_CS1(); // aktywny drugi kontroler
    lcdWriteCmd(DISPLAY_ON_CMD | OFF); // wyłączenie wyświetlania danych
    LCD_NOCS(); //
    }
    
    void lcdCls(void)
    {
    unsigned char x, y; // pomocnicze zmienne
    for (y = 0; y < 8; y++) // 8-krotne powtórzenie pętli
    {
    lcdGoTo(0,y); // ustawienie współrzędnej y wyświetlacza
    for (x = 0; x < 128; x++) // 128-krotne powtórzenie pętli
    lcdWriteData(0x00); // zapis do wyświetlacza
    }
    lcdGoTo(0,0); // ustawienie początkowych współrzędnych
    }
    
    void lcdWriteChar(char x)
    {
    char i;
    x -= 32; // konwersja kodu znaku
    for(i = 0; i < 5; i++)
    lcdWriteData(pgm_read_byte(font5x7 + (5 * x) + i)); // zapis do wyświetlacza
    //5 kolejnych bajtów tworzących znak
    lcdWriteData(0); // odstęp między znakami
    }
    
    void lcdWriteString(char * s)
    {
    while(*s) // dopóki znak wskazywany przez s jest różny od zera
    lcdWriteChar(*s++); // zapis znaku
    }
    
    void lcdWriteStringPgm(prog_char * s)
    {
    char c; // pomocnicza zmienna
    while(c = pgm_read_byte(s++)) // dopóki znak wskazywany przez s jest różny od
    // zera
    lcdWriteChar(c); // zapis znaku
    }
    
    void lcdLocate(unsigned char x, unsigned char y)
    {
    lcdGoTo(x * 6, y); // zapis
    }
    
    void lcdSetPixel(unsigned char x, unsigned char y)
    {
    char temp; // zmienna pomocnicza
    lcdGoTo(x, y/8); // ustawienie współrzędnych
    temp = lcdReadData(); //
    temp = lcdReadData(); // podwójny odczyt danych
    lcdGoTo(x, y/8); // ponowne ustawienie współrzędnych
    lcdWriteData(temp | (1 << (y % 8))); // zapis odpowiednio zmodyfikowanej wartości
    }
    
    void lcdClrPixel(unsigned char x, unsigned char y)
    {
    char temp;
    lcdGoTo(x, y/8);
    temp = lcdReadData();
    temp = lcdReadData();
    lcdGoTo(x, y/8);
    lcdWriteData(temp & (0xFF - (1 << (y % 8))));
    }
    
    
    
    
    
    int main()
    {
    
    lcdInit();
    lcdOn();
    lcdCls();
    lcdGoTo(0,0);
    lcdWriteString("11223344556677889900");
    return 0;
    }
    


    Dodano po 1 [minuty]:

    zastanawia mnie jeden fakt, ten kod chyba wybiera kontroler stanem wysokim, a wg dokumentacji do tego wyświetlacza CS1 i CS2 wybierane ma być stanem niskim... to może być to?

    Dodano po 29 [minuty]:

    ok, wprowadziłem pewne zmiany w kodzie, i teraz na środku ekranu między całą masą krzaków wyświetla się napis :D

    zmieniłem to:
    // makroinstrukcje ustawienia stanu na linii CS1
    #define SET_CS1() (LCD_CTRL_PORT |= (1 << LCD_CS1P))
    #define CLR_CS1() (LCD_CTRL_PORT &= ~(1 << LCD_CS1P))
    // makroinstrukcje ustawienia stanu na linii CS2
    #define SET_CS2() (LCD_CTRL_PORT |= (1 << LCD_CS2P))
    #define CLR_CS2() (LCD_CTRL_PORT &= ~(1 << LCD_CS2P))


    na to:
    // makroinstrukcje ustawienia stanu na linii CS1
    #define CLR_CS1() (LCD_CTRL_PORT |= (1 << LCD_CS1P))
    #define SET_CS1() (LCD_CTRL_PORT &= ~(1 << LCD_CS1P))
    // makroinstrukcje ustawienia stanu na linii CS2
    #define CLR_CS2() (LCD_CTRL_PORT |= (1 << LCD_CS2P))
    #define SET_CS2() (LCD_CTRL_PORT &= ~(1 << LCD_CS2P))


    gdzieś dzwony biją ale gdzie?

    Dodano po 8 [minuty]:

    [C]Problem z wyświetlaczem 128x64 - Nadal nie rozwiązany
  • REKLAMA
REKLAMA