|
|
  |
Свои символы hd44780 |
|
|
|
Jul 29 2008, 09:23
|
Группа: Новичок
Сообщений: 6
Регистрация: 25-06-08
Пользователь №: 38 539

|
Привет. Пишу свои функции для управления дисплеем. Использую 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 - Jul 29 2008, 09:25
|
|
|
|
|
Jul 29 2008, 10:57
|
Группа: Новичок
Сообщений: 6
Регистрация: 25-06-08
Пользователь №: 38 539

|
Всю ночь долбался не мог понять в чем проблема, а сейчас выяснил. Надеюсь кому-то поможет.Адрес в 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); Хотя должна была быть очистка дисплея, а появляется бред на экране.
|
|
|
|
|
Jul 29 2008, 10:59
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(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}; // Цельсий
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Jul 29 2008, 11:28
|
Группа: Новичок
Сообщений: 6
Регистрация: 25-06-08
Пользователь №: 38 539

|
Цитата(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 Я уже разобрался в из-за чего у меня глюки дисплея, но не пойму почему.
|
|
|
|
|
Jul 29 2008, 13:08
|
Группа: Новичок
Сообщений: 6
Регистрация: 25-06-08
Пользователь №: 38 539

|
Инициализацию я выполняю по даташиту и она проходит нормально. А вот если я в программе где-то хочу очистить экран и ставлю код, который отправляет команду очистки - появляются глюки.
Сообщение отредактировал Specialist - Jul 29 2008, 13:09
|
|
|
|
|
Jul 29 2008, 17:08
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
микро прога для удобства перевода символов в строку Flash.
Прикрепленные файлы
ggram.zip ( 191.45 килобайт )
Кол-во скачиваний: 89
|
|
|
|
|
Aug 9 2008, 04:34
|

Участник

Группа: Свой
Сообщений: 67
Регистрация: 5-02-07
Пользователь №: 25 074

|
Цитата(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); Пример...
|
|
|
|
|
Sep 2 2008, 05:08
|

embedder
  
Группа: Свой
Сообщений: 264
Регистрация: 11-05-05
Из: Казань
Пользователь №: 4 911

|
Привожу свой пример, может поможет: Код //--- Дополнительные символы для знакогенератора 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); } }
--------------------
Мечты стареют куда быстрее мечтателей… Стивен Кинг. "Ловец снов"
|
|
|
|
|
Sep 2 2008, 07:22
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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); // не забыть после этого поставить курсор в нужную позицию, обычно это делается в конце инициализации. }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|