Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Микроконтроллеры (MCU) и микропроцессоры (MPU) > [avr] LCD wh1601a


Автор: CompWorm 15.4.2010, 19:32
Доброго времени!
решил вот разобраться с LCD дисплеем. купил wh1601a у которого 1х16 символов, прицепил к ATmega8 и заюзал библиотеку lcd.h в CodeVisionAVR, как сказано http://www.123avr.com/z5.htm .
но чёт даже инициализация не проходит. то есть экран чёрные квадраты не выдаёт. 
отмечу, что библиотечка эта работает в 4х битовом режиме, а не 8ми, как описано в большинстве мануалов.
вот код

Код

#include <mega8.h>
#include <m8_128.h>
#include <delay.h>


// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h> 

void main(void)
{
lcd_init(16);
delay_ms(100);       
while (1)
      {
      lcd_gotoxy(5,0);
        lcd_putsf("Hello");             
        delay_ms(100);
        lcd_clear(); 
        delay_ms(100);
      };
}


в архиве проект, ДШ и схемка.

подскажите пожалуйста, где я туплю. 
у меня два предположения - либо мой LCD не совместим с hd44780 дисплеями и я его спалил...
либо скрепил что-то неправильно... например, V0 у меня напрямую +5В подключён... но там вроде как до 7и можно... и квадраты уж должны быть по-любому..

Автор: smalcom 15.4.2010, 20:54
насколько я помню, то черные квадраты выводятся пока не проинициализирован дисплей.
а инициализацию лучше самому написать. там есть нюансы с таймингами у некоторых дисплеев.

Автор: CompWorm 15.4.2010, 21:17
smalcom, спасибо за ответ!
хххмм... да, действительно я читал, что часто проблема в задержке... но разве lcd_init() не имеет внутренней задержки? к тому же я поставил дополнитеольно delay_ms(100); он хоть на 100 мс должен чернеть...  а ннет!

Автор: smalcom 15.4.2010, 23:07
вот-вот, мне както попался LCD-модуль который хотел четких задержек и решение "ааа, чем медленее тем надёжней" там не сработало. в итоге мне пришлось четко выдержать все тайминги из доки.
Посему лучше просмотреть еще рах доку на LCD-модуль. И вот что там кодвижн сгенерил...

Код

                 __long_delay_G2:
0000f8 27aa          clr   r26
0000f9 27bb          clr   r27
                 __long_delay0:
0000fa 9711          sbiw  r26,1         ;2 cycles
0000fb f7f1          brne  __long_delay0 ;2 cycles

это вроде как задержка. уж больно маловата она.

зы. если надо то выложу код модуля, но я для 8-ми битной шины писал.


-----
Код

lcd_init(16);
delay_ms(100);       

а вот перед инициализацией LCD желательно выждать время

Автор: CompWorm 16.4.2010, 11:56
smalcom, спасибо за идею!
по поводу чётких задержек я ничего не могу сказать в отношении своего дисплея, так как ДШ по нему наредкость бестолковый. я решил проверить ваше предположение о задержке до вызова инициализации, поморгав лампочкой. в случае успеха, lcd_init(16) возвращает единицу, если я ничего не путаю.

Код

// LCD module initialization 
DDRB.1 = 0xFF; // PORTB, PIN-1 на выход  для отладочного LED
PORTB.1 ++;
delay_ms(1000);
PORTB.1 --;
if (lcd_init(16)==1)
{
        delay_ms(1000);       
        while (1)
                {
                // поморгать лампочкой, если подключение успешно
                PORTB.1 ++;
                delay_ms(50);
                PORTB.1 --;
                delay_ms(50);    
                PORTB.1 ++;
                delay_ms(50);
                PORTB.1 --;
                delay_ms(50);
                // написать текст
                lcd_gotoxy(2,0);
                lcd_putsf("Hello!");             
                delay_ms(1000);
                lcd_clear(); 
                delay_ms(1000);
                };  
}else
{       // гореть лампочкой, если не инициализировался
        PORTB.1 ++;
}
}

лампочка горит, то есть lcd_init(16) не вернул единицу. очевидно эта функция работает неправильно smile 
вообще, в ДШ указан контролер http://pdf1.alldatasheet.com/datasheet-pdf/view/37318/SAMSUNG/KS0066.html... он совместим с hd44780 ? на вид, таблица 7 с командами весьма похожа на ту, что у hd44780...
ещё меня интересует, какой должен быть резистор для контраста V0 ?

так же я написал свою инициализацию в 4х битовом режиме. на основе http://easyelectronics.ru/avr-uchebnyj-kurs-podklyuchenie-k-avr-lcd-displeya-hd44780.htmlмануала, но на СИ
Код

#include <mega8.h>
#include <m8_128.h>
#include <delay.h>


// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h> 


// Declare your global variables here

void main(void)
{
// LCD module initialization 
DDRB.1 = 0xFF; // PORTB, PIN-1 на выход  
PORTB.1 ++;
delay_ms(1000);
                             

DDRD.0 = 0xFF; // PORTD, PIN-0 на выход RS
DDRD.1 = 0xFF; // PORTD, PIN-1 на выход RW
DDRD.2 = 0xFF; // PORTD, PIN-2 на выход E
DDRD.3 = 0xFF; // PORTD, PIN-3 на выход пустой
DDRD.4 = 0xFF; // PORTD, PIN-4 на выход DB4
DDRD.5 = 0xFF; // PORTD, PIN-5 на выход DB5
DDRD.6 = 0xFF; // PORTD, PIN-6 на выход DB6
DDRD.7 = 0xFF; // PORTD, PIN-7 на выход DB7
    
// проверяем, готов ли дисплей, считывая Busy flag на DB7  
DDRD.7 = 0x00; // PORTD, PIN-7 на вход DB7
label1:
PORTD.0 = 0; // передача команды
PORTD.1 = 0; // режим отправки  
PORTD.2 = 1; // начало транзакции
delay_ms(100);
PORTD.2 = 0; // конец транзакции
delay_ms(100);
if (PORTD.7==1) goto label1;

// режим 00100000 - шина 4 бита, одна строка, символы 5х8 точек
//DB5 = D5
PORTD.0 = 0; // передача команды
PORTD.1 = 0; // режим отправки
PORTD.2 = 1; // начало транзакции  
PORTD.5 = 1;               
delay_ms(100);
PORTD.2 = 0; // конец транзакции
delay_ms(100);
               
PORTD.0 = 1; // передача данных
PORTD.1 = 0; // режим отправки


// LCD готов к работе.
DDRD.7 = 0xFF; // возвращаем PORTD, PIN-7 на выход DB7
PORTB.1 --;

                // написать текст
                lcd_gotoxy(2,0);
                lcd_putsf("Hello!");             
                delay_ms(1000);
                lcd_clear(); 
                delay_ms(1000);
                
                // поморгать лампочкой, если подключение успешно
                PORTB.1 ++;
                delay_ms(50);
                PORTB.1 --;
                delay_ms(50);    
                PORTB.1 ++;
                delay_ms(50);
                PORTB.1 --;
                delay_ms(50);
}
 

пожалуйста проверьте правильность написанного. я начинающий и вполне мог наляпать ошибок.

задержки тут могучие (в десять раз больше рекомендуемых автором статьи), и в результате код срабатывает, что можно понять по контрольной лампочке на порту Б1, однакто ничего не происходит.
подю питание и загорается только подсветка LCD. никаких чёрных квадратов и тем более текста я не вижу.

можно ли как-то понять, жив ли ещё мой дисплей без ATmega ? соединим контакты какие-нибудь или замерив что-нибудь... например, меня настораживает контакт контрастности V0. я прицепил на него LED и он не горит во время работы LCD... 

Автор: smalcom 17.4.2010, 10:54
Цитата

можно ли как-то понять, жив ли ещё мой дисплей без ATmega ? соединим контакты какие-нибудь или замерив что-нибудь... например, меня настораживает контакт контрастности V0. я прицепил на него LED и он не горит во время работы LCD... 

для максимальной контрасноти V0 сажать на "общий". Обычно включенный, но не инициализированный LCD-модуль отображает ряд из черных квадратиков.

Цитата

задержки тут могучие (в десять раз больше рекомендуемых автором статьи)

вот я на этом както и обжегся. больше не оказалось лучше, пришлось выдерживать более-менее четкие тайминги.


Автор: xvr 19.4.2010, 18:36
Ваш init неправильный, во первых не надо проверять busy до начала инициализации (она все равно не выдается), во вторых команд в инициализации должно быть побольше (штук так около 4-5)

Автор: CompWorm 19.4.2010, 22:42
xvr, не поделитесь навыком инициализации на си ? у меня так мало параметров, я так думаю, потому что мне нужно передать всего одну единичку 00100000 , остальные нули, согласно табличке в ДШ.

но у меня не проходит эксперимент, предложенный smalcom на проверку работоспособности дисплея. я врубил Vcc и Vo напрямую в +5V, Gnd в землю и у меня никаких квадратов нет... 
что ещё можно проверить?  smile  

думаю, надо завязывать с мясными продуктами и начинать копить на новы LCD  smile 

Автор: xvr 20.4.2010, 21:45
Цитата(CompWorm @ 19.4.2010,  22:42)
xvr, не поделитесь навыком инициализации на си ?

Вот кусок из рабочего проекта

Автор: CompWorm 21.4.2010, 11:55
xvr, спасибо, попытаюсь разобраться с кодом  smile  +1

Автор: Yarmak 10.7.2013, 14:11
Доброго времени суток. Господа, поясните пожалуйста по поводу инициализации: почитал весь даташит и про инициализацию нашел только один алгоритм. Сделал вроде все правильно, но на дисплее квадраты (значит не правильно).  Пользуюсь этим даташитом: http://catalog.compel.ru/file/lcm/WINSTAR/pdf/WH1601A-YGH-CTK.pdf
Во многих других примерах вижу работу с ENABLE, но в даташите написано только chip enable signal, а в алгоритме о нем ничего, для чего он нужен?
Хотелось бы не просто пользоваться библиотеками, а разобраться. Спасибо.

Автор: xvr 14.7.2013, 18:44
Цитата(Yarmak @  10.7.2013,  14:11 Найти цитируемый пост)
Во многих других примерах вижу работу с ENABLE, но в даташите написано только chip enable signal,

Это он и есть

Цитата(Yarmak @  10.7.2013,  14:11 Найти цитируемый пост)
 для чего он нужен?

Собственно при установке этого сигнала и происходит обращение к индикатору (либо чтение, либо запись). Так что без него работать явно не будет

Автор: LeonidPr 15.7.2013, 09:01
Цитата(xvr @  14.7.2013,  18:44 Найти цитируемый пост)
Собственно при установке этого сигнала

Точнее при сбросе - запись и чтение идут по заднему фронту сигнала ENABLE.
Когда-то управлял WH1602 (та же фигня, только двухстрочная). Работал он чисто на задержках, Busy даже не использовал.
После каждой команды давал задержку на 40 мкс.

Добавлено через 3 минуты и 27 секунд
Пример из моего проекта
Код

void LCD_WriteCommand(BYTE cmd)
{
 OutByteToReg(cmd);
 RS_PIN=0;
 Nop();
 Nop();
 Nop();
 Nop();
 E_PIN=1;
 Nop();
 Nop();
 Nop();
 Nop();
 Nop();
 Nop();
 E_PIN=0;
 Delay_40us();
};

void LCD_WriteData(BYTE data)
{
 OutByteToReg(data);
 RS_PIN=1;
 Nop();
 Nop();
 Nop();
 Nop();
 E_PIN=1;
 Nop();
 Nop();
 Nop();
 Nop();
 Nop();
 Nop();
 E_PIN=0;
 Delay_40us();
};

Сигнал R/W всегда в 0 и не управляется.
OutByteToReg выдает байт на шину DB[0-7]

Автор: Yarmak 15.7.2013, 16:36
Спасибо всем, заработало.smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)