Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Свои символы hd44780
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему
Specialist
Привет. Пишу свои функции для управления дисплеем. Использую PIC, компилятор Hi-Tech C for PIC Вроде бы все работает нормально. Но как только загружаю свой символ в CGRAM у меня а дисплее абракадабра получается.

Записать 4 бита RS data
void mylcd_wdata4(char,char);

Делаю вот так, но я не полностью понял как пользовательские символы записывать туда.

Код
char user_gradus[16] = {0b0000,0b1110,0b0001,0b0001,0b0001,0b0001,0b0000,0b1110,0,0,0,0,0,0,0,0}; // Цельсий

mylcd_init();

mylcd_wdata4(0,0b0100);//Пока записываю по 4 бита, дальше не делал.
mylcd_wdata4(0,0b0001);//Тут я выбрал адрес в CGRAM

for (i=0; i<16; i++) mylcd_wdata4(1,user_gradus[i]);


Что тут не так ?
Specialist
Всю ночь долбался не мог понять в чем проблема, а сейчас выяснил.
Надеюсь кому-то поможет.

Адрес в CGRAM нужно выбирать через 8, например 0x00, 0x08. Это в даташите написано. Сразу не понял почему.


То есть, чтоб записать свой символ нужно первым делом инициализировать дисплей
Код
mylcd_init();

Потом выбрать адрес

Код
mylcd_wdata4(0,0b0100);//Нулевой
mylcd_wdata4(0,0b0000);                 символ


Отправить данные
Код
for (i=0; i<16; i++) mylcd_wdata4(1,user_gradus[i]);


Поставить курсор в нужное место
Код
mylcd_goto(1,1);

И вывести символ

Код
mylcd_wdata4(1,0);
mylcd_wdata4(1,0);


Код
#define LCD_RS RC2
#define LCD_sync RC3
#define LCD_F4 RC7
#define LCD_F5 RC6
#define LCD_F6 RC5
#define LCD_F7 RC4

void mylcd_strobe(){
    LCD_sync = 1; // Синхронизация.
    DelayUs(250);// Задержка
    DelayUs(250);// Задержка
    LCD_sync = 0; // Синхронизация.
}

void mylcd_wdata4(short RS, short data){
    
    if(LCD_RS != RS)
    {
        LCD_RS = RS;// Выбор Регистра команд.
        DelayMs(1);// Задержка
    }
     //Данные
    if((data & 0b1) >= 1)    LCD_F7 = 1;    else    LCD_F7 = 0;
    if((data & 0b10) >= 1)    LCD_F6 = 1;    else    LCD_F6 = 0;
    if((data & 0b100) >= 1)    LCD_F5 = 1;    else    LCD_F5 = 0;
    if((data & 0b1000) >= 1)LCD_F4 = 1;    else    LCD_F4 = 0;
    
     //Данные
     DelayUs(250);// Задержка
     mylcd_strobe();
     DelayUs(50);// Задержка    

}

void mylcd_init(){
     PORTC = 0;
     DelayMs(100);// Задержка после включения
     mylcd_wdata4(0,0b0010);//4 Бита шина
     DelayMs(100);
     mylcd_wdata4(0,0b0000);
     mylcd_wdata4(0,0b1100);
     DelayMs(100);
     mylcd_wdata4(0,0b0000);
     mylcd_wdata4(0,0b0001);
     DelayMs(10);
     mylcd_wdata4(0,0b0000);
     mylcd_wdata4(0,0b0110);
     DelayMs(10);
     mylcd_wdata4(0,0b0010);
     mylcd_wdata4(0,0b1000);
     DelayMs(10);
}

void mylcd_goto(char row, char col)//Номер строки и символа начинаются с 1
{
    if (row == 1) mylcd_wdata4(0,0b1000); else mylcd_wdata4(0,0b1100);
    mylcd_wdata4(0, col - 1);
}


Абракадабра появляется когда я записываю данные
Код
mylcd_wdata4(0,0);
mylcd_wdata4(0,0b0001);

Хотя должна была быть очистка дисплея, а появляется бред на экране.
sKWO
Цитата(Specialist @ Jul 29 2008, 12:23) *
Привет. Пишу свои функции для управления дисплеем. Использую PIC, компилятор Hi-Tech C for PIC Вроде бы все работает нормально. Но как только загружаю свой символ в CGRAM у меня а дисплее абракадабра получается.
Что тут не так ?

Может поможет дабовление нуля в конце массива?
Код
char user_gradus[17] = {0b0000,0b1110,0b0001,0b0001,0b0001,0b0001,0b0000,0b1110,0,0,0,0,0,0,0,0,0x00}; // Цельсий
Specialist
Цитата(sKWO @ Jul 29 2008, 12:59) *
Может поможет дабовление нуля в конце массива?
Код
char user_gradus[17] = {0b0000,0b1110,0b0001,0b0001,0b0001,0b0001,0b0000,0b1110,0,0,0,0,0,0,0,0,0x00}; // Цельсий


Мне нужно отправить 8 байт информации. Я их отправляю по 4 бита, значит всего будет 16 кусков данных.
А если я добавлю еще 17-ю часть то это уже получиться не правильно.
Вот они

char user_gradus[16] = {0b0000,0b1110,0b0001,0b0001,0b0001,0b0001,0b0000,0b1110,0,0,0,0,0,0,0,0}; // Цельсий

Если нарисовать то, что я отправляю получиться так:
01110
10001
10001
01110
00000
00000
00000
00000

Я уже разобрался в из-за чего у меня глюки дисплея, но не пойму почему.
Палыч
Цитата(Specialist @ Jul 29 2008, 13:57) *
Хотя должна была быть очистка дисплея, а появляется бред на экране.
Можен, нужно перенести очистку экрана в конец процедуры инициализации (после определения других параметров)?
Specialist
Инициализацию я выполняю по даташиту и она проходит нормально. А вот если я в программе где-то хочу очистить экран и ставлю код, который отправляет команду очистки - появляются глюки.
rezident
Цитата(Specialist @ Jul 29 2008, 19:08) *
Инициализацию я выполняю по даташиту и она проходит нормально.
Инициализация выполнена неверно! См. блок-схему алгоритма Figure 24. 4-Bit Interface на стр. 46 datasheet HD44780U.
К тому же логика управления сигналом E (если я понял это у вас LCD_sync?) тоже неверная. См. временные диаграммы записи в этом же даташите.
andrvisht
микро прога для удобства перевода символов в строку Flash.
VXDRV
Цитата(Specialist @ Jul 29 2008, 17:28) *
Мне нужно отправить 8 байт информации. Я их отправляю по 4 бита, значит всего будет 16 кусков данных.
А если я добавлю еще 17-ю часть то это уже получиться не правильно.
Вот они

char user_gradus[16] = {0b0000,0b1110,0b0001,0b0001,0b0001,0b0001,0b0000,0b1110,0,0,0,0,0,0,0,0}; // Цельсий

Если нарисовать то, что я отправляю получиться так:
01110
10001
10001
01110
00000
00000
00000
00000

Я уже разобрался в из-за чего у меня глюки дисплея, но не пойму почему.


Код
    INIT_LCD();                while (WAIT_READY()==0);
    WRITE_IR(0x40);            while (WAIT_READY()==0);    // зашиваем незакрашенный квадратик в LCD, USER-символ по адресу 0x00
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00000000);    while (WAIT_READY()==0);
    WRITE_DR(0b00010001);    while (WAIT_READY()==0);
    WRITE_DR(0b00000000);    while (WAIT_READY()==0);
    WRITE_DR(0b00010001);    while (WAIT_READY()==0);
    WRITE_DR(0b00000000);    while (WAIT_READY()==0);
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00000000);    while (WAIT_READY()==0);

    WRITE_DR(0b00011111);    while (WAIT_READY()==0);    // зашиваем закрашенный квадратик в LCD, USER-символ по адресу 0x01
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00000000);    while (WAIT_READY()==0);
    
    WRITE_IR(0x50);            while (WAIT_READY()==0);    // зашиваем что-то ещё в LCD (сердечко), USER-символ по адресу 0x03
    WRITE_DR(0b00000000);    while (WAIT_READY()==0);
    WRITE_DR(0b00001010);    while (WAIT_READY()==0);
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00011111);    while (WAIT_READY()==0);
    WRITE_DR(0b00001110);    while (WAIT_READY()==0);
    WRITE_DR(0b00000100);    while (WAIT_READY()==0);
    WRITE_DR(0b00000000);    while (WAIT_READY()==0);
    WRITE_DR(0b00000000);    while (WAIT_READY()==0);

Пример...
zksystem
Привожу свой пример, может поможет:

Код
//--- Дополнительные символы для знакогенератора LCD модуля --------------

static const unsigned char lcd_charset[]={    0b00000000, //0
                                            0b00010000,
                                            0b00011000,
                                            0b00011100,
                                            0b00011100,
                                            0b00011000,
                                            0b00010000,
                                            0b00000000,

                                            0b00000000, //1
                                            0b00000001,
                                            0b00000011,
                                            0b00000111,
                                            0b00000111,
                                            0b00000011,
                                            0b00000001,
                                            0b00000000,

                                            0b00000000, //2
                                            0b00011111,
                                            0b00010001,
                                            0b00010001,
                                            0b00010001,
                                            0b00010001,
                                            0b00011111,
                                            0b00000000,

                                            0b00000000, //3
                                            0b00011111,
                                            0b00011111,
                                            0b00011111,
                                            0b00011111,
                                            0b00011111,
                                            0b00011111,
                                            0b00000000,

                                            0b00000000, //4
                                            0b00000000,
                                            0b00000000,
                                            0b11011011,
                                            0b11011011,
                                            0b11011011,
                                            0b11011011,
                                            0b11011011};



#define    lcd_udg_data = 5*8

//--- write data to LCD char,RS ---

void lcd_data(unsigned char c, unsigned char reg)
{
    DelayMs(4);
    TRISD2 = 0;

    LCD_RS = reg;
    LCD_PORT = (LCD_PORT & 0xF0) |  (c >> 4);
    LCD_STROBE;
    LCD_PORT = (LCD_PORT & 0xF0) |  (c & 0x0F);
    LCD_STROBE;
}

void lcd_loadchars(void)
{
    unsigned char i;

// загрузка дополнительных символов в LCD модуль

    for (i=0;i<lcd_udg_data;i++)
    {
        lcd_data(0x40+i,0);
        lcd_data(lcd_charset[i],1);
    }
}
Сергей Борщ
Цитата(zksystem @ Sep 2 2008, 08:08) *
Привожу свой пример, может поможет:
Можно его немножко поправить?
Код
static const char lcd_charset[]={   0b10000000, //0
                                    0b10010000,
                                    0b10011000,
                                    0b10011100,
                                    0b10011100,
                                    0b10011000,
                                    0b10010000,
                                    0b10000000,
                                    //все равно старший бит не отображается, можно использовать его как признак не конца строки
                                    ........

                                    0b10000000, //4
                                    0b10000000,
                                    0b10000000,
                                    0b11011011,
                                    0b11011011,
                                    0b11011011,
                                    0b11011011,
                                    0b11011011,
                                    0};
........
//--- write data to LCD char,RS ---

void lcd_data(unsigned char c)
{
    DelayMs(4);
    TRISD2 = 0;

    LCD_PORT = (LCD_PORT & 0xF0) |  (c >> 4);
    LCD_STROBE;
    LCD_PORT = (LCD_PORT & 0xF0) |  (c & 0x0F);
    LCD_STROBE;
    LCD_RS = 1;
}
void lcd_command(unsigned char c)
{
    LCD_RS = 0;
    lcd_data(c);
}

void lcd_putstring(char const * str) // вывод строк на экран. Полезная функция.
{
    unsigned char c;
    while((c = *str++) != 0)
    {
        lcd_data(c);
    }
}

void lcd_loadchars(void)
{
// загрузка дополнительных символов в LCD модуль
    lcd_command(0x40);
    lcd_putstring(lcd_charset);
// не забыть после этого поставить курсор в нужную позицию, обычно это делается в конце инициализации.
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.