NT7603 i ustawianie adresu DDRAM

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From Polish to

Threaded View
Hej,

Kupiłem na Allegro takiego LCD-ka:
http://www.allegro.pl/item638225240.html

Jest tam kontroler NT7603, generalnie kompatybilny z HD44780:
http://www.densitron.com/uploadedFiles/Displays/Support/NT7603.pdf

Problem: Każde ustawienie adresu DDRAM powyżej 40 i poniżej 48 (np. 43)
ustawia go na 40, czyli znak pojawia się na początku drugiej linijki.
Powyżej 48 w ogóle się nie pojawia. Dla pierwszej linijki wszystko jest
w porządku.

Dostęp jest w trybie 4-bitowym.

Spotkaliście się z czymś takim?

Więcej info, jeżeli komuś chce się wgryzać:

Inicjalizuję wyświetlacz wysyłając bajty:

- 0x00 (dl=0: 4-bit)
- 0x08 (f=0: 5x8, n=1: 2line, dl=0: 4bit)
- 0x06 (i/d:1 increment, s=0: shift off)
- 0x14 (s/c=0: moe cursor, r/l=1: right)
- 0x01 (cls)
- 0x02 (home)
- 0x0C (d=1: display on)

Co ważniejsze funkcje (przejrzałem je kilka razy, ale może coś przeoczyłem?).

void lcd_goto(uint8_t x, uint8_t y)
{
        send_byte(RS_C, 0x80 + ((y == 1) ? 40 : 0) + x);
}

void lcd_printf(const char *fmt, ...)
{
        char buf[17];
        const char *p;
        va_list ap;

        va_start(ap, fmt);
        vsnprintf(buf, sizeof(buf), fmt, ap);
        va_end(ap);

        for (p = buf; *p; ++p)
                send_byte(RS_D, *p);
}

static void send_byte(bool isdata, uint8_t byte)
{
        send_nibble(isdata, byte >> 4);
        send_nibble(isdata, byte & 0x0F);
}

static void send_nibble(bool isdata, uint8_t nibble)
{
        i2c_lcd_send(isdata, RW_W, false, nibble);
        i2c_lcd_send(isdata, RW_W, true, nibble);
        i2c_lcd_send(isdata, RW_W, false, nibble);

        // xxx zrobic na busy flag
        {
                uint16_t i;
                for (i = 0; i < 0x3FF; ++i)
                        __asm__("nop");
        }
}

static void i2c_lcd_send(bool rs, bool rw, bool en, uint8_t nibble)
{
        uint8_t bytes[2];

        bytes[0] = _BV(7);                      // VDD -> bit7
        bytes[0] |= (nibble & _BV(3)) >> 3;     // D3 -> bit0
        bytes[0] |= (nibble & _BV(2)) >> 1;     // D2 -> bit1
        bytes[0] |= (nibble & _BV(1)) << 1;     // D1 -> bit2
        bytes[0] |= (nibble & _BV(0)) << 3;     // D0 -> bit3
        bytes[0] |= en << 4;                    // EN -> bit4
        bytes[0] |= rw << 5;                    // RW -> bit5
        bytes[0] |= rs << 6;                    // RS -> bit6

        bytes[1] = 0xFF;                        // unused

        i2c_send(SLAVE, bytes, _countof(bytes));
}

Po wypełnieniu wyświetlacza wartościami X i uruchomieniu takiego kodu:

        for (i = 0; i < 16; ++i)
        {
                lcd_goto(i, 0);
                lcd_printf("%X", i);

                lcd_goto(i, 1);
                lcd_printf("%x", i);
        }

Pojawia się:

0123456789ABCDEF
7XXXXXXXXXXXXXXX

--
http://www.gophi.pl /

Re: NT7603 i ustawianie adresu DDRAM
Hej,

Kupiłem na Allegro takiego LCD-ka:
http://www.allegro.pl/item638225240.html

Jest tam kontroler NT7603, generalnie kompatybilny z HD44780:
http://www.densitron.com/uploadedFiles/Displays/Support/NT7603.pdf

Problem: Każde ustawienie adresu DDRAM powyżej 40 i poniżej 48 (np. 43)
ustawia go na 40, czyli znak pojawia się na początku drugiej linijki.
Powyżej 48 w ogóle się nie pojawia. Dla pierwszej linijki wszystko jest
w porządku.

Dzieje się tak tylko przy ustawianiu poleceniem 0x80. Inkrementacja
przez wyświetlacz przy zapisie do DDRAM działa ok.

Dostęp jest w trybie 4-bitowym.

Spotkaliście się z czymś takim?

Więcej info, jeżeli komuś chce się wgryzać:

Inicjalizuję wyświetlacz wysyłając bajty:

- 0x00 (dl=0: 4-bit)
- 0x08 (f=0: 5x8, n=1: 2line, dl=0: 4bit)
- 0x06 (i/d:1 increment, s=0: shift off)
- 0x14 (s/c=0: moe cursor, r/l=1: right)
- 0x01 (cls)
- 0x02 (home)
- 0x0C (d=1: display on)

Co ważniejsze funkcje (przejrzałem je kilka razy, ale może coś przeoczyłem?).

void lcd_goto(uint8_t x, uint8_t y)
{
        send_byte(RS_C, 0x80 + ((y == 1) ? 40 : 0) + x);
}

void lcd_printf(const char *fmt, ...)
{
        char buf[17];
        const char *p;
        va_list ap;

        va_start(ap, fmt);
        vsnprintf(buf, sizeof(buf), fmt, ap);
        va_end(ap);

        for (p = buf; *p; ++p)
                send_byte(RS_D, *p);
}

static void send_byte(bool isdata, uint8_t byte)
{
        send_nibble(isdata, byte >> 4);
        send_nibble(isdata, byte & 0x0F);
}

static void send_nibble(bool isdata, uint8_t nibble)
{
        i2c_lcd_send(isdata, RW_W, false, nibble);
        i2c_lcd_send(isdata, RW_W, true, nibble);
        i2c_lcd_send(isdata, RW_W, false, nibble);

        // xxx zrobic na busy flag
        {
                uint16_t i;
                for (i = 0; i < 0x3FF; ++i)
                        __asm__("nop");
        }
}

static void i2c_lcd_send(bool rs, bool rw, bool en, uint8_t nibble)
{
        uint8_t bytes[2];

        bytes[0] = _BV(7);                      // VDD -> bit7
        bytes[0] |= (nibble & _BV(3)) >> 3;     // D3 -> bit0
        bytes[0] |= (nibble & _BV(2)) >> 1;     // D2 -> bit1
        bytes[0] |= (nibble & _BV(1)) << 1;     // D1 -> bit2
        bytes[0] |= (nibble & _BV(0)) << 3;     // D0 -> bit3
        bytes[0] |= en << 4;                    // EN -> bit4
        bytes[0] |= rw << 5;                    // RW -> bit5
        bytes[0] |= rs << 6;                    // RS -> bit6

        bytes[1] = 0xFF;                        // unused

        i2c_send(SLAVE, bytes, _countof(bytes));
}

Po wypełnieniu wyświetlacza wartościami X i uruchomieniu takiego kodu:

        for (i = 0; i < 16; ++i)
        {
                lcd_goto(i, 0);
                lcd_printf("%X", i);

                lcd_goto(i, 1);
                lcd_printf("%x", i);
        }

Pojawia się:

0123456789ABCDEF
7XXXXXXXXXXXXXXX

--
http://www.gophi.pl /

Re: NT7603 i ustawianie adresu DDRAM
Hej,

Kupiłem na Allegro takiego LCD-ka:
http://www.allegro.pl/item638225240.html

Jest tam kontroler NT7603, generalnie kompatybilny z HD44780:
http://www.densitron.com/uploadedFiles/Displays/Support/NT7603.pdf

Problem: Każde ustawienie adresu DDRAM powyżej 40 i poniżej 48 (np. 43)
ustawia go na 40, czyli znak pojawia się na początku drugiej linijki.
Powyżej 48 w ogóle się nie pojawia. Dla pierwszej linijki wszystko jest
w porządku.

Dzieje się tak tylko przy ustawianiu poleceniem 0x80. Inkrementacja
przez wyświetlacz przy zapisie do DDRAM działa ok.

Dostęp jest w trybie 4-bitowym.

Spotkaliście się z czymś takim?

Więcej info, jeżeli komuś chce się wgryzać:

Inicjalizuję wyświetlacz wysyłając bajty:

- 0x00 (dl=0: 4-bit)
- 0x08 (f=0: 5x8, n=1: 2line, dl=0: 4bit)
- 0x06 (i/d:1 increment, s=0: shift off)
- 0x14 (s/c=0: move cursor, r/l=1: right)
- 0x01 (cls)
- 0x02 (home)
- 0x0C (d=1: display on)

Co ważniejsze funkcje (przejrzałem je kilka razy, ale może coś przeoczyłem?).

void lcd_goto(uint8_t x, uint8_t y)
{
        send_byte(RS_C, 0x80 + ((y == 1) ? 40 : 0) + x);
}

void lcd_printf(const char *fmt, ...)
{
        char buf[17];
        const char *p;
        va_list ap;

        va_start(ap, fmt);
        vsnprintf(buf, sizeof(buf), fmt, ap);
        va_end(ap);

        for (p = buf; *p; ++p)
                send_byte(RS_D, *p);
}

static void send_byte(bool isdata, uint8_t byte)
{
        send_nibble(isdata, byte >> 4);
        send_nibble(isdata, byte & 0x0F);
}

static void send_nibble(bool isdata, uint8_t nibble)
{
        i2c_lcd_send(isdata, RW_W, false, nibble);
        i2c_lcd_send(isdata, RW_W, true, nibble);
        i2c_lcd_send(isdata, RW_W, false, nibble);

        // xxx zrobic na busy flag
        {
                uint16_t i;
                for (i = 0; i < 0x3FF; ++i)
                        __asm__("nop");
        }
}

static void i2c_lcd_send(bool rs, bool rw, bool en, uint8_t nibble)
{
        uint8_t bytes[2];

        bytes[0] = _BV(7);                      // VDD -> bit7
        bytes[0] |= (nibble & _BV(3)) >> 3;     // D3 -> bit0
        bytes[0] |= (nibble & _BV(2)) >> 1;     // D2 -> bit1
        bytes[0] |= (nibble & _BV(1)) << 1;     // D1 -> bit2
        bytes[0] |= (nibble & _BV(0)) << 3;     // D0 -> bit3
        bytes[0] |= en << 4;                    // EN -> bit4
        bytes[0] |= rw << 5;                    // RW -> bit5
        bytes[0] |= rs << 6;                    // RS -> bit6

        bytes[1] = 0xFF;                        // unused

        i2c_send(SLAVE, bytes, _countof(bytes));
}

Po wypełnieniu wyświetlacza wartościami X i uruchomieniu takiego kodu:

        for (i = 0; i < 16; ++i)
        {
                lcd_goto(i, 0);
                lcd_printf("%X", i);

                lcd_goto(i, 1);
                lcd_printf("%x", i);
        }

Pojawia się:

0123456789ABCDEF
7XXXXXXXXXXXXXXX

--
http://www.gophi.pl /

Re: NT7603 i ustawianie adresu DDRAM

Quoted text here. Click to load it

podlaczyles inny, dobry LCD - taki sam efekt?

Quoted text here. Click to load it

jestes pewien, ze ta funkcja dziala dobrze??

1) SET DDRAM - na bicie 7 ma być zawsze 1 - pole bitowe z ustawionymi bitami
lepiej maskowac niz dodawac
2) adresy DDRAM dla LCD 2-wierszowego: 1 linia 0x00..0x27, 2 linia
0x40..0x67
3) w kodzie jak operujesz na hex, to uzywaj stalych tylko hex - latwo mozna
cos przeoczyc (0x80 i 40)
4) sprawdzaj zakresy argumentow

Ja bym ta funkcje napisal tak (dla LCD 2x16 znakowego):
CursorX - kolumny 0..15
CursorY - wiersze 0..1

#define LCD_CURSOR_X_MAX    15
#define LCD_LINE0           0
#define LCD_LINE1           1
#define LCD_OFFSET_LINE0    0x00
#define LCD_OFFSET_LINE1    0x40
#define LCD_SET_DDRAM_CMD   0x80

void LcdGotoXY(u8 CursorX, u8 CursorY)
{
    if (CursorX > LCD_CURSOR_X_MAX)
        CursorX = LCD_CURSOR_X_MAX;
    u8 Cmd;
    Offset = LCD_OFFSET_LINE0;
    if (CursorY == LCD_LINE1)
        Cmd = LCD_OFFSET_LINE1;
    Cmd |= LCD_SET_DDRAM_CMD | CursorX;
    LcdSendByte(Cmd);
}

latwo przerobisz kod dla wiekszych LCD.

http://home.iae.nl/users/pouweha/lcd/lcd0.shtml


Re: NT7603 i ustawianie adresu DDRAM

Quoted text here. Click to load it

Mam tylko ten jeden, musiałbym przelutowywać. Ten jest nowy.

Quoted text here. Click to load it

Nie :) Dlatego wkleiłem.

Quoted text here. Click to load it

Ano. Chociaż optymalizator i tak pewnie zrobił OR-a. Tak czy inaczej zmieniłem
na _BV(7) | (((y == 1) ? 40 : 0) + x), przejrzyściej...

Quoted text here. Click to load it

Byłem pewien że skoro DDRAM ma rozmiar 80 bajtów, to jest podzielony po równo
w dec i druga linia zaczyna się od 40 dec a nie hex. Zmieniłem na 0x40 i działa
super. Dzięki!

--
http://www.gophi.pl /

Site Timeline