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

[LCD] nie moge zainicjowac w trybie 2 linii

Smiet69 20 Gru 2010 21:45 3388 20
  • #1 8894129
    Smiet69
    Poziom 10  
    Walczę i walcze i coś nie mogę trafić.

    Ściągnąłem kod http://radzio.dxp.pl/hd44780/ - 8-bit z odczytem flagi zajętości

    I mam problem przy inicjowaniu LCD 2x16 - nie mogę go zmusić do pracy z 2 liniami.

    Kiedy inicjuję na jedną działa:
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_ONE_LINE | HD44780_8_BIT); // interfejs 4-bity, 2-linie, znak 5x7
    LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF); // wyłączenie wyswietlacza
    LCD_WriteCommand(HD44780_CLEAR); // czyszczenie zawartosći pamieci DDRAM
    _delay_ms(150);
    LCD_WriteCommand(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR | HD44780_EM_INCREMENT);// inkrementaja adresu i przesuwanie kursora
    LCD_WriteCommand(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF | HD44780_CURSOR_NOBLINK); // włącz LCD, bez kursora i mrugania

    Musiałem tylko dodać "_delay_ms(150);" po clear. I pierwsza linijka się wyświetla.

    Ale jak dam:
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_8_BIT);

    To mam czyściutki ekran i nic się nie pojawia.

    Podpowie ktoś o co się zaczepić?
  • #2 8895723
    LordBlick
    VIP Zasłużony dla elektroda
    Smiet69 napisał:
    Ale jak dam:
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_8_BIT);

    To mam czyściutki ekran i nic się nie pojawia.
    Ale co ma się pojawić i skąd ? Podane namiary są na kod obsługi wyświetlacza, nie znalazłem tam kodu do testowania...
  • #3 8896376
    Smiet69
    Poziom 10  
    Kod był typowy:
    ...
    LCD_Initalize();
    LCD_Clear();
    LCD_WriteText("Test01");
    LCD_GoTo(0,1);
    LCD_WriteText("2nd line");
    _delay_ms(1000);
    LCD_Clear();
    LCD_WriteText("1st line");
    LCD_GoTo(0,1);
    LCD_WriteText("2nd line");
    _delay_ms(1000);
    ...

    Przy zainicjowaniu na 1 linię pierwsze linie się pojawiają. Ale po zainicjowaniu na dwie nie pojawia się nic (to co było wcześniej na wyświetlaczu po poprzednim kodzie znika).

    Cały kod tutaj:
    http://www.henry.vel.pl/temp/ATMega32_test2.zip
    w obsłudze LCD zmieniłem zapis bo LCD jest podłączony do portu PA odwrotnie i dodałem opóźnienie 100ms w procedurze inicjalizacji po clear.
  • #4 8897084
    LordBlick
    VIP Zasłużony dla elektroda
    1. Funkcja _LCD_Write powinna najpierw zapisywać wyjście, dopiero potem :
    LCD_E_PORT |= LCD_E;
    _delay_us(20); 
    LCD_E_PORT &= ~LCD_E;

    2. Spróbuj w HD44780.c zamiast
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_8_BIT); // interfejs 4-bity, 2-linie, znak 5x7
    
    tego :
    LCD_WriteCommand(0x38);
  • #5 8898640
    rpal
    Poziom 27  
    Czy kolega jest pewien że ma wyświetlacz z 2 liniami ? to banalne pytanie ale może od tego trzeba najpierw zacząć ?:)
  • #6 8900816
    Smiet69
    Poziom 10  
    Light-I napisał:
    1. Funkcja _LCD_Write powinna najpierw zapisywać wyjście, dopiero potem :
    LCD_E_PORT |= LCD_E;
    _delay_us(20); 
    LCD_E_PORT &= ~LCD_E;

    2. Spróbuj w HD44780.c zamiast
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_8_BIT); // interfejs 4-bity, 2-linie, znak 5x7
    
    tego :
    LCD_WriteCommand(0x38);


    Z PDF'a wygląda że ustawianie danych powinno być gdy E=1.
    W każdym razie nic się nie zmieniło, "LCD_WriteCommand(0x38);" daje pusty ekran, "LCD_WriteCommand(0x30);" tylko pierwszą linię (czyli wyjścia działają).

    rpal, jako 2 liniowy go kupiłem ;-) Ma 2x16. Zresztą wczesniej próbowałem na 2x8 - i to samo, nie dał się zmusić do współpracy z 2 linią. Jak go podłączałem do 89C2051 zaprogramowanego bascomem to działał. Tylko z Atmegą nie mogę...
  • #7 8902068
    michalko12
    Specjalista - Mikrokontrolery
    Zanim wywołasz LCD_Initalize(); spróbuj odczekać ze 100ms.
  • #8 8904180
    rpal
    Poziom 27  
    poradzę koledze aby uważnie przeczytac note katalogową zwłaszcza pod kątem przebiegów czasowych i niezbędnych opóźnień. Dodatkową radą jest to aby monitorować stan linii RD i nie ogladać się na biblioteki które zakładają gotowość wyświetlacza w przeciągu założonego odcinka czasu. Wyświetlacze mają różną "szybkość" i zakładanie na sztywno że po jakimś czasie będzię on gotowy na przyjęcie kolejnego polecenia lub wysłanie danych jest pomyłką bo dana biblioteka będzie działać tylko z jednym typem wyświetlacza albo zalożysz tak duże opóznienia czasowe będą tak duże że LCD będzie działał na pół gwizdka. Typowe w LCD jest zwykle rozłożenie pinów a reszta to już zależy od producenta.
    Popatrzyłem na kod i zdaje się że tam jest monitorowana linia RD zatem coś sknociłeś w połaczeniach albo modyfikowaniu programu.
  • #9 8905331
    Smiet69
    Poziom 10  
    No właśnie przerobiłem układ żeby móc kontrolować RW. W kodzie który podałem jest jeszcze błąd - zamiast "while(LCD_ReadStatus()&0x80);" powinienem dać "while(LCD_ReadStatus()&0x01);" - bo port DB7 mam podłączony do PA0. Ale to też nic nie pomogło. Powstawiałem opóźnienia na 200ms wszędzie gdzie się tylko dało i nadal nic.
    Wrzuciłem ostatni kod na
    http://www.henry.vel.pl/temp/ATMega32_test2.zip

    Połączenia muszą być ok, bo LCD zainicjowany na jedną linię działa świetnie. Nie jest też zepsuty bo podłączyłem do starego układu testowego i działa bez problemu z dwiema liniami. Dopiero się zaczynam uczyć C więc może coś przeoczyłem (już tęsknię za assemblerem ;-) ).
  • #10 8905927
    michalko12
    Specjalista - Mikrokontrolery
    W LCD_Initalize(void) masz błąd
    Zamiast:

    LCD_DATA_PORT = 0x3F;

    wpisz:

    LCD_DATA_PORT = 0xFC;

    lub:

    _LCD_Out(0x3F);
  • #11 8908507
    Smiet69
    Poziom 10  
    Racja... tylko że też nie pomogło... :-(
  • #14 8924353
    sulfur
    Poziom 24  
    A czy kolega po uruchomieniu wyświetlacza w jednej linii wysyła coś do niego ? Mam teorię, że jest zwarcie pomiędzy trzecim i czwartym pinem (DB2 i DB3). Sprawdzić multimetrem lub odpalić jaki 2 linie i czcionka 5x10 (zamiast 5x7).
  • #15 8926787
    LordBlick
    VIP Zasłużony dla elektroda
    Się zawziąłem i wrzuciłem u siebie na ATmega8515/11,0592MHz i na tej konfiguracji jest sprawdzone, że działa na dwie linie - wyświetlacz WC1602A. Początkowo u mnie tez były problemy, ale przerobiłem inicjalizację mniej więcej tak, jak to mam w AVRasm zrobione.
    1. Plik HD44780.c był niedorobiony, jeśli chodzi o odczyt, wszelkie zbędne śmieci wywaliłem i uprościłem.
    2. Konfigurację trybów przeniosłem z HD44780.c do HD44780.h
    3. Makefile uzupełniłem o łatwą możliwość konfiguracji nazwy projektu, F_CPU oraz możliwość programowania przez avrdude przy pomocy używanego przeze mnie USBAsp.
    Owoce przeróbki na ATmega32/1MHz i ATmega8515/11,0592MHz w załącznikach.
    Jako, że pliki do ATmega8515 są dodatkowo, pozwolę sobie na nie założyć prowizję punktową.
  • #16 8931187
    Smiet69
    Poziom 10  
    Dzięki za uporządkowanie kodu - wziąłem go, ale pominąłem makefile - do programowania używam ISP Programmer'a.
    Tylko że niestety nadal nie chce mi działać :-(

    Przeniosłem trochę kodu do głównego programu:

    int main(void)
    {
    LCD_DATA_DIR = 0xFF;
    LCD_DATA_PORT = 0x00;
    LCD_E_DIR 	|= LCD_E;   //
    LCD_RS_DIR 	|= LCD_RS;  //
    LCD_RW_DIR	|= LCD_RW;
    LCD_RS_PORT &= ~LCD_RS; // wyzerowanie linii RS
    LCD_E_PORT &= ~LCD_E;  // wyzerowanie linii E
    LCD_RW_PORT  &= ~LCD_RW;
    //LCD_Initalize();
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_ONE_LINE | HD44780_8_BIT);
    LCD_WriteCommand(HD44780_DISPLAY_CURSOR);
    LCD_WriteCommand(HD44780_CLEAR); // czyszczenie zawartosći pamieci DDRAM
    _delay_ms(2);
    LCD_WriteCommand(HD44780_ENTRY_SET);
    
    LCD_Clear();
    LCD_WriteText("Test02");
    LCD_GoTo(0,1);
    LCD_WriteText("2nd line A");
    _delay_ms(1000);
    LCD_WriteCommand(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE | HD44780_8_BIT);
    LCD_WriteCommand(HD44780_DISPLAY_CURSOR);
    LCD_WriteCommand(HD44780_CLEAR); // czyszczenie zawartosći pamieci DDRAM
    _delay_ms(2);
    LCD_WriteCommand(HD44780_ENTRY_SET);
    
    _delay_ms(1000);
    LCD_Clear();
    LCD_WriteText("1st line B");
    LCD_GoTo(0,1);
    LCD_WriteText("2nd line B");


    Wyświetla mi się "Test02", a sekundę później wszystko znika i już nic sie nie pojawia.

    sulfur, przy zainicjowaniu na 1 linię działa normalnie - działają komendy i write, tekst w pierwszej linii jest poprawny. Wcześniej miałem ten sam problem przy innej płytce gdzie sterowałem przez 4-bity (zrobiłem drugą myśląc że to przez brak kontroli linii RW). Gdyby to miało być coś technicznego to chyba tylko uwalony port w atmedze - ale musiałby wysyłać krzaki przy wypisywaniu tekstu (przy 8-bitach może by nie wyszło, ale przy 4 raczej mało prawdopodobne żeby się ukryło). No bo chyba to że to ATMega32L nie powinno mieć znaczenia (zasilam na ok. 5V) - fuse bity standardowe tylko z wyłączonym JTAGiem żeby odzyskać PORTC. Wyświetlacz WC1602A tak jak u Light-I
  • #17 8932530
    LordBlick
    VIP Zasłużony dla elektroda
    Dla mnie nie ma bata, kod, który przerobiłem jest dobry, specjalnie nawet zamieniłem kolejność podłączeń linii danych (mam ATmega8115 ćwiczebną na płytce stykowej) i nadal działa (załączam zdjęcia).
    1. Sprawdź stabilność napięcia zasilania.
    2. Sprawdź czy prędkość zegara pokrywa się z zadeklarowaną w Makefile.
    3. Sprawdź rezystancję połączenia linii RS.
  • #18 8933317
    Smiet69
    Poziom 10  
    Wierzę że u Ciebie działa - kod jest tak prosty że nie widzę powodu żeby miało nie działać.
    Zasilanie jest stabilne - zasilam z 4xAA (akku), zasilałem też z zasilacza na 7805 i to samo było.
    Zegar też musi być ok - zmiany tekstu są co sekundę. Zrobiłem inny program z odliczaniem zadanego czasu z ordynarnym opóźnieniem w pętli i było mniej więcej dokładnie (jak na wewnętrzny oscylator). A chyba kilku procentowe róznice nie powinny być problemem...
    Rezystancji linii nie mam teraz jak sprawdzić, ale gdyby coś było nie tak z lutami to przy zainicjowaniu na jedną linię też powinien być jakiś problem - a nie ma żadnego...
    Cóż - biorę się za projektowanie płytki pod ATTiny26 bo akurat taki gdzieś mam i sprawdzę na nim - bo skoro zmieniałem LCD, zmieniałem płytki, zmieniałem z Twoją pomocą program, to została już tylko wymiana układu.
  • #19 8935482
    LordBlick
    VIP Zasłużony dla elektroda
    Pozostałe ewentualności:
    - przepięcie linii sterujących (EN, RW, RS) do innego portu - być może gdzieś coś zapisuje do niewłaściwego obszaru I/O, co skutkuje uaktywnienie funkcji dodatkowych.
    - Makefile jest do sprawdzenia pod kontem literówek we flagach, ewentualnie może być niekompatybilny z konkretną wersją WinAVR/avr-gcc/avr-binutils.
  • #20 8946003
    Smiet69
    Poziom 10  
    No ale czy to tłumaczyło by to, że zainicjowany na jedną linię LCD działa? Można wypisywać, można też czyścić, przesuwać kursor, zmieniać kursor - czyli linie E i RS muszą działać. Zrobiłem sobie timerek w którym można ustawiać czas i odlicza go pokazując na lcd - i żadnych błędów w trakcie nie ma.
    Mam już kolejną płytkę pod inny AVR - muszę tylko poczekać aż pogoda pozwoli mi pojechać po lutownicę i elementy.
    W wolnej chwili spróbuję też z Bascomem AVR - skoro pod zwykłym działało to i pod tym powinno (chyba że wina faktycznie leży po stronie ATmegi32 - na co logicznego wytłumaczenia znaleźć nie mogę).
  • #21 9553914
    Smiet69
    Poziom 10  
    Przepraszam że się nie odzywałem - jestem hobbystą z doskoku.
    Próbowałem na nowej płytce na attiny26 i to samo - żaden tryb nie działał jak należy. Dopiero jak ściągnąłem biblioteczkę z http://jump.to/fleury to nagle wszystko zadziałało - nawet stary układ z atmegą32. Tak po prostu klik i są dwie linie... Nie wiem co było z tamtym kodem, ale cieszę się że w końcu mój projekcik ruszy dalej :-)
REKLAMA